-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
ConsistencyReport.java
558 lines (412 loc) · 26.1 KB
/
ConsistencyReport.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
/*
* Copyright (c) 2002-2018 "Neo4j,"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.consistency.report;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.neo4j.consistency.RecordType;
import org.neo4j.consistency.checking.RecordCheck;
import org.neo4j.consistency.store.synthetic.CountsEntry;
import org.neo4j.consistency.store.synthetic.IndexEntry;
import org.neo4j.consistency.store.synthetic.LabelScanDocument;
import org.neo4j.kernel.impl.annotations.Documented;
import org.neo4j.kernel.impl.store.record.DynamicRecord;
import org.neo4j.kernel.impl.store.record.LabelTokenRecord;
import org.neo4j.kernel.impl.store.record.NeoStoreRecord;
import org.neo4j.kernel.impl.store.record.NodeRecord;
import org.neo4j.kernel.impl.store.record.PropertyBlock;
import org.neo4j.kernel.impl.store.record.PropertyKeyTokenRecord;
import org.neo4j.kernel.impl.store.record.PropertyRecord;
import org.neo4j.kernel.impl.store.record.RelationshipGroupRecord;
import org.neo4j.kernel.impl.store.record.RelationshipRecord;
import org.neo4j.kernel.impl.store.record.RelationshipTypeTokenRecord;
import org.neo4j.storageengine.api.schema.SchemaRule;
import org.neo4j.storageengine.api.schema.StoreIndexDescriptor;
public interface ConsistencyReport
{
@Retention( RetentionPolicy.RUNTIME )
@Target( ElementType.METHOD )
@interface Warning
{
}
interface Reporter
{
void forSchema( DynamicRecord schema,
RecordCheck<DynamicRecord, SchemaConsistencyReport> checker );
void forNode( NodeRecord node,
RecordCheck<NodeRecord, NodeConsistencyReport> checker );
void forRelationship( RelationshipRecord relationship,
RecordCheck<RelationshipRecord, RelationshipConsistencyReport> checker );
void forProperty( PropertyRecord property,
RecordCheck<PropertyRecord, PropertyConsistencyReport> checker );
void forRelationshipTypeName( RelationshipTypeTokenRecord relationshipType,
RecordCheck<RelationshipTypeTokenRecord, RelationshipTypeConsistencyReport> checker );
void forLabelName( LabelTokenRecord label,
RecordCheck<LabelTokenRecord, LabelTokenConsistencyReport> checker );
void forPropertyKey( PropertyKeyTokenRecord key,
RecordCheck<PropertyKeyTokenRecord, PropertyKeyTokenConsistencyReport> checker );
void forDynamicBlock( RecordType type, DynamicRecord record,
RecordCheck<DynamicRecord, DynamicConsistencyReport> checker );
void forDynamicLabelBlock( RecordType type, DynamicRecord record,
RecordCheck<DynamicRecord, DynamicLabelConsistencyReport> checker );
void forNodeLabelScan( LabelScanDocument document,
RecordCheck<LabelScanDocument, ConsistencyReport.LabelScanConsistencyReport> checker );
void forIndexEntry( IndexEntry entry,
RecordCheck<IndexEntry, ConsistencyReport.IndexConsistencyReport> checker );
void forRelationshipGroup( RelationshipGroupRecord record,
RecordCheck<RelationshipGroupRecord, ConsistencyReport.RelationshipGroupConsistencyReport> checker );
void forCounts( CountsEntry countsEntry,
RecordCheck<CountsEntry, ConsistencyReport.CountsConsistencyReport> checker );
}
interface PrimitiveConsistencyReport extends ConsistencyReport
{
@Documented( "The referenced property record is not in use." )
void propertyNotInUse( PropertyRecord property );
@Documented( "The referenced property record is not the first in its property chain." )
void propertyNotFirstInChain( PropertyRecord property );
@Documented( "The referenced property is owned by another Node." )
void multipleOwners( NodeRecord node );
@Documented( "The referenced property is owned by another Relationship." )
void multipleOwners( RelationshipRecord relationship );
@Documented( "The referenced property is owned by the neo store (graph global property)." )
void multipleOwners( NeoStoreRecord neoStore );
@Documented( "The property chain contains multiple properties that have the same property key id, " +
"which means that the entity has at least one duplicate property." )
void propertyKeyNotUniqueInChain();
@Documented( "The property chain does not contain a property that is mandatory for this entity." )
void missingMandatoryProperty( int key );
}
interface NeoStoreConsistencyReport extends PrimitiveConsistencyReport
{
}
interface SchemaConsistencyReport extends ConsistencyReport
{
@Documented( "The label token record referenced from the schema is not in use." )
void labelNotInUse( LabelTokenRecord label );
@Documented( "The relationship type token record referenced from the schema is not in use." )
void relationshipTypeNotInUse( RelationshipTypeTokenRecord relationshipType );
@Documented( "The property key token record is not in use." )
void propertyKeyNotInUse( PropertyKeyTokenRecord propertyKey );
@Documented( "The uniqueness constraint does not reference back to the given record" )
void uniquenessConstraintNotReferencingBack( DynamicRecord ruleRecord );
@Documented( "The constraint index does not reference back to the given record" )
void constraintIndexRuleNotReferencingBack( DynamicRecord ruleRecord );
@Documented( "This record is required to reference some other record of the given kind but no such obligation " +
"was found" )
void missingObligation( SchemaRule.Kind kind );
@Documented( "This record requires some other record to reference back to it but there already was such " +
"a conflicting obligation created by the record given as a parameter" )
void duplicateObligation( DynamicRecord record );
@Documented( "This record contains a schema rule which has the same content as the schema rule contained " +
"in the record given as parameter" )
void duplicateRuleContent( DynamicRecord record );
@Documented( "The schema rule contained in the DynamicRecord chain is malformed (not deserializable)" )
void malformedSchemaRule();
@Documented( "The schema rule contained in the DynamicRecord chain is of an unrecognized Kind" )
void unsupportedSchemaRuleKind( SchemaRule.Kind kind );
@Warning
@Documented( "The schema rule contained in the DynamicRecord chain has a reference to a schema rule that is not online." )
void schemaRuleNotOnline( SchemaRule schemaRule );
}
interface NodeConsistencyReport extends PrimitiveConsistencyReport
{
@Documented( "The referenced relationship record is not in use." )
void relationshipNotInUse( RelationshipRecord referenced );
@Documented( "The referenced relationship record is a relationship between two other nodes." )
void relationshipForOtherNode( RelationshipRecord relationship );
@Documented( "The referenced relationship record is not the first in the relationship chain where this node " +
"is source." )
void relationshipNotFirstInSourceChain( RelationshipRecord relationship );
@Documented( "The referenced relationship record is not the first in the relationship chain where this node " +
"is target." )
void relationshipNotFirstInTargetChain( RelationshipRecord relationship );
@Documented( "The label token record referenced from a node record is not in use." )
void labelNotInUse( LabelTokenRecord label );
@Documented( "The label token record is referenced twice from the same node." )
void labelDuplicate( long labelId );
@Documented( "The label id array is not ordered" )
void labelsOutOfOrder( long largest, long smallest );
@Documented( "The dynamic label record is not in use." )
void dynamicLabelRecordNotInUse( DynamicRecord record );
@Documented( "This record points to a next record that was already part of this dynamic record chain." )
void dynamicRecordChainCycle( DynamicRecord nextRecord );
@Documented( "This node was not found in the expected index." )
void notIndexed( StoreIndexDescriptor index, Object[] propertyValues );
@Documented( "This node was found in the expected index, although multiple times" )
void indexedMultipleTimes( StoreIndexDescriptor index, Object[] propertyValues, long count );
@Documented( "There is another node in the unique index with the same property value(s)." )
void uniqueIndexNotUnique( StoreIndexDescriptor index, Object[] propertyValues, long duplicateNodeId );
@Documented( "The referenced relationship group record is not in use." )
void relationshipGroupNotInUse( RelationshipGroupRecord group );
@Documented( "The first relationship group record has another node set as owner." )
void relationshipGroupHasOtherOwner( RelationshipGroupRecord group );
}
interface RelationshipConsistencyReport
extends PrimitiveConsistencyReport
{
@Documented( "The relationship record is not in use, but referenced from relationships chain." )
void notUsedRelationshipReferencedInChain( RelationshipRecord relationshipRecord );
@Documented( "The relationship type field has an illegal value." )
void illegalRelationshipType();
@Documented( "The relationship type record is not in use." )
void relationshipTypeNotInUse( RelationshipTypeTokenRecord relationshipType );
@Documented( "The source node field has an illegal value." )
void illegalSourceNode();
@Documented( "The target node field has an illegal value." )
void illegalTargetNode();
@Documented( "The source node is not in use." )
void sourceNodeNotInUse( NodeRecord node );
@Documented( "The target node is not in use." )
void targetNodeNotInUse( NodeRecord node );
@Documented( "This record should be the first in the source chain, but the source node does not reference this record." )
void sourceNodeDoesNotReferenceBack( NodeRecord node );
@Documented( "This record should be the first in the target chain, but the target node does not reference this record." )
void targetNodeDoesNotReferenceBack( NodeRecord node );
@Documented( "The source node does not have a relationship chain." )
void sourceNodeHasNoRelationships( NodeRecord source );
@Documented( "The target node does not have a relationship chain." )
void targetNodeHasNoRelationships( NodeRecord source );
@Documented( "The previous record in the source chain is a relationship between two other nodes." )
void sourcePrevReferencesOtherNodes( RelationshipRecord relationship );
@Documented( "The next record in the source chain is a relationship between two other nodes." )
void sourceNextReferencesOtherNodes( RelationshipRecord relationship );
@Documented( "The previous record in the target chain is a relationship between two other nodes." )
void targetPrevReferencesOtherNodes( RelationshipRecord relationship );
@Documented( "The next record in the target chain is a relationship between two other nodes." )
void targetNextReferencesOtherNodes( RelationshipRecord relationship );
@Documented( "The previous record in the source chain does not have this record as its next record." )
void sourcePrevDoesNotReferenceBack( RelationshipRecord relationship );
@Documented( "The next record in the source chain does not have this record as its previous record." )
void sourceNextDoesNotReferenceBack( RelationshipRecord relationship );
@Documented( "The previous record in the target chain does not have this record as its next record." )
void targetPrevDoesNotReferenceBack( RelationshipRecord relationship );
@Documented( "The next record in the target chain does not have this record as its previous record." )
void targetNextDoesNotReferenceBack( RelationshipRecord relationship );
@Documented( "This relationship was not found in the expected index." )
void notIndexed( StoreIndexDescriptor index, Object[] propertyValues );
@Documented( "This relationship was found in the expected index, although multiple times" )
void indexedMultipleTimes( StoreIndexDescriptor index, Object[] propertyValues, long count );
}
interface PropertyConsistencyReport extends ConsistencyReport
{
@Documented( "The property key as an invalid value." )
void invalidPropertyKey( PropertyBlock block );
@Documented( "The key for this property is not in use." )
void keyNotInUse( PropertyBlock block, PropertyKeyTokenRecord key );
@Documented( "The previous property record is not in use." )
void prevNotInUse( PropertyRecord property );
@Documented( "The next property record is not in use." )
void nextNotInUse( PropertyRecord property );
@Documented( "The previous property record does not have this record as its next record." )
void previousDoesNotReferenceBack( PropertyRecord property );
@Documented( "The next property record does not have this record as its previous record." )
void nextDoesNotReferenceBack( PropertyRecord property );
@Documented( "The type of this property is invalid." )
void invalidPropertyType( PropertyBlock block );
@Documented( "The string block is not in use." )
void stringNotInUse( PropertyBlock block, DynamicRecord value );
@Documented( "The array block is not in use." )
void arrayNotInUse( PropertyBlock block, DynamicRecord value );
@Documented( "The string block is empty." )
void stringEmpty( PropertyBlock block, DynamicRecord value );
@Documented( "The array block is empty." )
void arrayEmpty( PropertyBlock block, DynamicRecord value );
@Documented( "The property value is invalid." )
void invalidPropertyValue( PropertyBlock block );
@Documented( "This record is first in a property chain, but no Node or Relationship records reference this record." )
void orphanPropertyChain();
@Documented( "The string property is not referenced anymore, but the corresponding block has not been deleted." )
void stringUnreferencedButNotDeleted( PropertyBlock block );
@Documented( "The array property is not referenced anymore, but the corresponding block as not been deleted." )
void arrayUnreferencedButNotDeleted( PropertyBlock block );
@Documented( "This property was declared to be changed for a node or relationship, but that node or relationship " +
"does not contain this property in its property chain." )
void ownerDoesNotReferenceBack();
@Documented( "This property was declared to be changed for a node or relationship, but that node or relationship " +
"did not contain this property in its property chain prior to the change. The property is referenced by another owner." )
void changedForWrongOwner();
@Documented( "The string record referred from this property is also referred from a another property." )
void stringMultipleOwners( PropertyRecord otherOwner );
@Documented( "The array record referred from this property is also referred from a another property." )
void arrayMultipleOwners( PropertyRecord otherOwner );
@Documented( "The string record referred from this property is also referred from a another string record." )
void stringMultipleOwners( DynamicRecord dynamic );
@Documented( "The array record referred from this property is also referred from a another array record." )
void arrayMultipleOwners( DynamicRecord dynamic );
}
interface NameConsistencyReport extends ConsistencyReport
{
@Documented( "The name block is not in use." )
void nameBlockNotInUse( DynamicRecord record );
@Warning
@Documented( "The token name is empty. Empty token names are discouraged and also prevented in version 2.0.x and " +
"above, but they can be accessed just like any other tokens. It's possible that this token have been " +
"created in an earlier version where there were no checks for name being empty." )
void emptyName( DynamicRecord name );
@Documented( "The string record referred from this name record is also referred from a another string record." )
void nameMultipleOwners( DynamicRecord otherOwner );
}
interface RelationshipTypeConsistencyReport extends NameConsistencyReport
{
@Documented( "The string record referred from this relationship type is also referred from a another relationship type." )
void nameMultipleOwners( RelationshipTypeTokenRecord otherOwner );
}
interface LabelTokenConsistencyReport extends NameConsistencyReport
{
@Documented( "The string record referred from this label name is also referred from a another label name." )
void nameMultipleOwners( LabelTokenRecord otherOwner );
}
interface PropertyKeyTokenConsistencyReport extends NameConsistencyReport
{
@Documented( "The string record referred from this key is also referred from a another key." )
void nameMultipleOwners( PropertyKeyTokenRecord otherOwner );
}
interface RelationshipGroupConsistencyReport extends ConsistencyReport
{
@Documented( "The relationship type field has an illegal value." )
void illegalRelationshipType();
@Documented( "The relationship type record is not in use." )
void relationshipTypeNotInUse( RelationshipTypeTokenRecord referred );
@Documented( "The next relationship group is not in use." )
void nextGroupNotInUse();
@Documented( "The location of group in the chain is invalid, should be sorted by type ascending." )
void invalidTypeSortOrder();
@Documented( "The first outgoing relationship is not in use." )
void firstOutgoingRelationshipNotInUse();
@Documented( "The first incoming relationship is not in use." )
void firstIncomingRelationshipNotInUse();
@Documented( "The first loop relationship is not in use." )
void firstLoopRelationshipNotInUse();
@Documented( "The first outgoing relationship is not the first in its chain." )
void firstOutgoingRelationshipNotFirstInChain();
@Documented( "The first incoming relationship is not the first in its chain." )
void firstIncomingRelationshipNotFirstInChain();
@Documented( "The first loop relationship is not the first in its chain." )
void firstLoopRelationshipNotFirstInChain();
@Documented( "The first outgoing relationship is of a different type than its group." )
void firstOutgoingRelationshipOfOfOtherType();
@Documented( "The first incoming relationship is of a different type than its group." )
void firstIncomingRelationshipOfOfOtherType();
@Documented( "The first loop relationship is of a different type than its group." )
void firstLoopRelationshipOfOfOtherType();
@Documented( "The owner of the relationship group is not in use." )
void ownerNotInUse();
@Documented( "Illegal owner value." )
void illegalOwner();
@Documented( "Next chained relationship group has another owner." )
void nextHasOtherOwner( RelationshipGroupRecord referred );
}
interface DynamicConsistencyReport extends ConsistencyReport
{
@Documented( "The next block is not in use." )
void nextNotInUse( DynamicRecord next );
@Warning
@Documented( "The record is not full, but references a next block." )
void recordNotFullReferencesNext();
@Documented( "The length of the block is invalid." )
void invalidLength();
@Warning
@Documented( "The block is empty." )
void emptyBlock();
@Warning
@Documented( "The next block is empty." )
void emptyNextBlock( DynamicRecord next );
@Documented( "The next block references this (the same) record." )
void selfReferentialNext();
@Documented( "The next block of this record is also referenced by another dynamic record." )
void nextMultipleOwners( DynamicRecord otherOwner );
@Documented( "The next block of this record is also referenced by a property record." )
void nextMultipleOwners( PropertyRecord otherOwner );
@Documented( "The next block of this record is also referenced by a relationship type." )
void nextMultipleOwners( RelationshipTypeTokenRecord otherOwner );
@Documented( "The next block of this record is also referenced by a property key." )
void nextMultipleOwners( PropertyKeyTokenRecord otherOwner );
@Documented( "This record not referenced from any other dynamic block, or from any property or name record." )
void orphanDynamicRecord();
}
interface DynamicLabelConsistencyReport extends ConsistencyReport
{
@Documented( "This label record is not referenced by its owning node record or that record is not in use." )
void orphanDynamicLabelRecordDueToInvalidOwner( NodeRecord owningNodeRecord );
@Documented( "This label record does not have an owning node record." )
void orphanDynamicLabelRecord();
}
interface NodeInUseWithCorrectLabelsReport extends ConsistencyReport
{
void nodeNotInUse( NodeRecord referredNodeRecord );
void nodeDoesNotHaveExpectedLabel( NodeRecord referredNodeRecord, long expectedLabelId );
void nodeLabelNotInIndex( NodeRecord referredNodeRecord, long missingLabelId );
}
interface RelationshipInUseWithCorrectRelationshipTypeReport extends ConsistencyReport
{
void relationshipNotInUse( RelationshipRecord referredRelationshipRecord );
void relationshipDoesNotHaveExpectedRelationshipType( RelationshipRecord referredRelationshipRecord, long expectedRelationshipTypeId );
}
interface LabelScanConsistencyReport extends NodeInUseWithCorrectLabelsReport
{
@Override
@Documented( "This label scan document refers to a node record that is not in use." )
void nodeNotInUse( NodeRecord referredNodeRecord );
@Override
@Documented( "This label scan document refers to a node that does not have the expected label." )
void nodeDoesNotHaveExpectedLabel( NodeRecord referredNodeRecord, long expectedLabelId );
@Override
@Documented( "This node record has a label that is not found in the label scan store entry for this node" )
void nodeLabelNotInIndex( NodeRecord referredNodeRecord, long missingLabelId );
@Warning
@Documented( "Label index was not properly shutdown and rebuild is required." )
void dirtyIndex();
}
interface IndexConsistencyReport extends NodeInUseWithCorrectLabelsReport, RelationshipInUseWithCorrectRelationshipTypeReport
{
@Override
@Documented( "This index entry refers to a node record that is not in use." )
void nodeNotInUse( NodeRecord referredNodeRecord );
@Override
@Documented( "This index entry refers to a relationship record that is not in use." )
void relationshipNotInUse( RelationshipRecord referredRelationshipRecord );
@Override
@Documented( "This index entry refers to a node that does not have the expected label." )
void nodeDoesNotHaveExpectedLabel( NodeRecord referredNodeRecord, long expectedLabelId );
@Override
@Documented( "This index entry refers to a relationship that does not have the expected relationship type." )
void relationshipDoesNotHaveExpectedRelationshipType( RelationshipRecord referredRelationshipRecord, long expectedRelationshipTypeId );
@Override
@Documented( "This node record has a label that is not found in the index for this node" )
void nodeLabelNotInIndex( NodeRecord referredNodeRecord, long missingLabelId );
@Warning
@Documented( "Index was not properly shutdown and rebuild is required." )
void dirtyIndex();
@Documented( "This index entry is for a relationship index, but it is used as a constraint index" )
void relationshipConstraintIndex();
}
interface CountsConsistencyReport extends ConsistencyReport
{
@Documented( "The node count does not correspond with the expected count." )
void inconsistentNodeCount( long expectedCount );
@Documented( "The relationship count does not correspond with the expected count." )
void inconsistentRelationshipCount( long expectedCount );
@Documented( "The node key entries in the store does not correspond with the expected number." )
void inconsistentNumberOfNodeKeys( long expectedCount );
@Documented( "The relationship key entries in the store does not correspond with the expected number." )
void inconsistentNumberOfRelationshipKeys( long expectedCount );
}
}