/consistency-check/src/main/java/org/neo4j/consistency/checking/full/MultiPassStore.java

https://github.com/dmontag/neo4j-enterprise · Java · 230 lines · 195 code · 16 blank · 19 comment · 9 complexity · 231a6798af9df8e24062b4c70dddf357 MD5 · raw file

  1. /**
  2. * Copyright (c) 2002-2012 "Neo Technology,"
  3. * Network Engine for Objects in Lund AB [http://neotechnology.com]
  4. *
  5. * This file is part of Neo4j.
  6. *
  7. * Neo4j is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU Affero General Public License as
  9. * published by the Free Software Foundation, either version 3 of the
  10. * License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Affero General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Affero General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. package org.neo4j.consistency.checking.full;
  21. import static org.neo4j.consistency.store.RecordReference.SkippingReference.skipReference;
  22. import java.util.ArrayList;
  23. import java.util.List;
  24. import org.neo4j.consistency.checking.CheckDecorator;
  25. import org.neo4j.consistency.report.ConsistencyLogger;
  26. import org.neo4j.consistency.report.ConsistencyReporter;
  27. import org.neo4j.consistency.report.ConsistencySummaryStatistics;
  28. import org.neo4j.consistency.store.DiffRecordAccess;
  29. import org.neo4j.consistency.store.RecordReference;
  30. import org.neo4j.kernel.impl.nioneo.store.DynamicRecord;
  31. import org.neo4j.kernel.impl.nioneo.store.NodeRecord;
  32. import org.neo4j.kernel.impl.nioneo.store.PropertyRecord;
  33. import org.neo4j.kernel.impl.nioneo.store.RecordStore;
  34. import org.neo4j.kernel.impl.nioneo.store.RelationshipRecord;
  35. import org.neo4j.kernel.impl.nioneo.store.StoreAccess;
  36. enum MultiPassStore
  37. {
  38. NODES()
  39. {
  40. @Override
  41. RecordStore getRecordStore( StoreAccess storeAccess )
  42. {
  43. return storeAccess.getNodeStore();
  44. }
  45. @Override
  46. DiffRecordAccess filter( final DiffRecordAccess recordAccess, final int iPass,
  47. final long recordsPerPass )
  48. {
  49. return new SkipAllButCached( recordAccess )
  50. {
  51. @Override
  52. public RecordReference<NodeRecord> node( long id )
  53. {
  54. if ( recordInCurrentPass( id, iPass, recordsPerPass ) )
  55. {
  56. return recordAccess.node( id );
  57. }
  58. return skipReference();
  59. }
  60. };
  61. }
  62. },
  63. RELATIONSHIPS()
  64. {
  65. @Override
  66. RecordStore getRecordStore( StoreAccess storeAccess )
  67. {
  68. return storeAccess.getRelationshipStore();
  69. }
  70. @Override
  71. DiffRecordAccess filter( final DiffRecordAccess recordAccess, final int iPass,
  72. final long recordsPerPass )
  73. {
  74. return new SkipAllButCached( recordAccess )
  75. {
  76. @Override
  77. public RecordReference<RelationshipRecord> relationship( long id )
  78. {
  79. if ( recordInCurrentPass( id, iPass, recordsPerPass ) )
  80. {
  81. return recordAccess.relationship( id );
  82. }
  83. return skipReference();
  84. }
  85. };
  86. }
  87. },
  88. PROPERTIES()
  89. {
  90. @Override
  91. RecordStore getRecordStore( StoreAccess storeAccess )
  92. {
  93. return storeAccess.getPropertyStore();
  94. }
  95. @Override
  96. DiffRecordAccess filter( final DiffRecordAccess recordAccess, final int iPass,
  97. final long recordsPerPass )
  98. {
  99. return new SkipAllButCached( recordAccess )
  100. {
  101. @Override
  102. public RecordReference<PropertyRecord> property( long id )
  103. {
  104. if ( recordInCurrentPass( id, iPass, recordsPerPass ) )
  105. {
  106. return recordAccess.property( id );
  107. }
  108. return skipReference();
  109. }
  110. };
  111. }
  112. },
  113. STRINGS()
  114. {
  115. @Override
  116. RecordStore getRecordStore( StoreAccess storeAccess )
  117. {
  118. return storeAccess.getNodeStore();
  119. }
  120. @Override
  121. DiffRecordAccess filter( final DiffRecordAccess recordAccess, final int iPass,
  122. final long recordsPerPass )
  123. {
  124. return new SkipAllButCached( recordAccess )
  125. {
  126. @Override
  127. public RecordReference<DynamicRecord> string( long id )
  128. {
  129. if ( recordInCurrentPass( id, iPass, recordsPerPass ) )
  130. {
  131. return recordAccess.string( id );
  132. }
  133. return skipReference();
  134. }
  135. };
  136. }
  137. },
  138. ARRAYS()
  139. {
  140. @Override
  141. RecordStore getRecordStore( StoreAccess storeAccess )
  142. {
  143. return storeAccess.getNodeStore();
  144. }
  145. @Override
  146. DiffRecordAccess filter( final DiffRecordAccess recordAccess, final int iPass,
  147. final long recordsPerPass )
  148. {
  149. return new SkipAllButCached( recordAccess )
  150. {
  151. @Override
  152. public RecordReference<DynamicRecord> array( long id )
  153. {
  154. if ( recordInCurrentPass( id, iPass, recordsPerPass ) )
  155. {
  156. return recordAccess.array( id );
  157. }
  158. return skipReference();
  159. }
  160. };
  161. }
  162. };
  163. private static boolean recordInCurrentPass( long id, int iPass, long recordsPerPass )
  164. {
  165. return id >= iPass * recordsPerPass && id < (iPass + 1) * recordsPerPass;
  166. }
  167. public List<DiffRecordAccess> multiPassFilters( long memoryPerPass, StoreAccess storeAccess,
  168. DiffRecordAccess recordAccess )
  169. {
  170. ArrayList<DiffRecordAccess> filters = new ArrayList<DiffRecordAccess>();
  171. RecordStore recordStore = getRecordStore( storeAccess );
  172. long recordsPerPass = memoryPerPass / recordStore.getRecordSize();
  173. long highId = recordStore.getHighId();
  174. for ( int iPass = 0; iPass * recordsPerPass <= highId; iPass++ )
  175. {
  176. filters.add( filter( recordAccess, iPass, recordsPerPass ) );
  177. }
  178. return filters;
  179. }
  180. abstract RecordStore getRecordStore( StoreAccess storeAccess );
  181. abstract DiffRecordAccess filter( DiffRecordAccess recordAccess, int iPass, long recordsPerPass );
  182. static class Factory
  183. {
  184. private final CheckDecorator decorator;
  185. private final ConsistencyLogger logger;
  186. private final DiffRecordAccess recordAccess;
  187. private final ConsistencySummaryStatistics summary;
  188. private final long totalMappedMemory;
  189. private final StoreAccess storeAccess;
  190. Factory( CheckDecorator decorator, ConsistencyLogger logger, long totalMappedMemory,
  191. StoreAccess storeAccess, DiffRecordAccess recordAccess, ConsistencySummaryStatistics summary )
  192. {
  193. this.decorator = decorator;
  194. this.logger = logger;
  195. this.totalMappedMemory = totalMappedMemory;
  196. this.storeAccess = storeAccess;
  197. this.recordAccess = recordAccess;
  198. this.summary = summary;
  199. }
  200. StoreProcessor[] createAll( MultiPassStore... stores )
  201. {
  202. List<StoreProcessor> result = new ArrayList<StoreProcessor>();
  203. for ( MultiPassStore store : stores )
  204. {
  205. List<DiffRecordAccess> filters = store.multiPassFilters( totalMappedMemory, storeAccess, recordAccess );
  206. for ( DiffRecordAccess filter : filters )
  207. {
  208. result.add( new StoreProcessor( decorator, new ConsistencyReporter( logger, filter, summary ) ) );
  209. }
  210. }
  211. return result.toArray( new StoreProcessor[result.size()] );
  212. }
  213. }
  214. }