use of org.neo4j.kernel.impl.store.record.PropertyRecord in project neo4j by neo4j.
the class PropertyTraverser method assertPropertyChain.
public boolean assertPropertyChain(PrimitiveRecord primitive, RecordAccess<PropertyRecord, PrimitiveRecord> propertyRecords) {
List<PropertyRecord> toCheck = new LinkedList<>();
long nextIdToFetch = primitive.getNextProp();
while (nextIdToFetch != Record.NO_NEXT_PROPERTY.intValue()) {
PropertyRecord propRecord = propertyRecords.getOrLoad(nextIdToFetch, primitive, cursorContext).forReadingLinkage();
toCheck.add(propRecord);
assert propRecord.inUse() : primitive + "->" + Arrays.toString(toCheck.toArray());
assert propRecord.size() <= PropertyType.getPayloadSize() : propRecord + " size " + propRecord.size();
nextIdToFetch = propRecord.getNextProp();
}
if (toCheck.isEmpty()) {
assert primitive.getNextProp() == Record.NO_NEXT_PROPERTY.intValue() : primitive;
return true;
}
PropertyRecord first = toCheck.get(0);
PropertyRecord last = toCheck.get(toCheck.size() - 1);
assert first.getPrevProp() == Record.NO_PREVIOUS_PROPERTY.intValue() : primitive + "->" + Arrays.toString(toCheck.toArray());
assert last.getNextProp() == Record.NO_NEXT_PROPERTY.intValue() : primitive + "->" + Arrays.toString(toCheck.toArray());
PropertyRecord current;
PropertyRecord previous = first;
for (int i = 1; i < toCheck.size(); i++) {
current = toCheck.get(i);
assert current.getPrevProp() == previous.getId() : primitive + "->" + Arrays.toString(toCheck.toArray());
assert previous.getNextProp() == current.getId() : primitive + "->" + Arrays.toString(toCheck.toArray());
previous = current;
}
return true;
}
use of org.neo4j.kernel.impl.store.record.PropertyRecord in project neo4j by neo4j.
the class FulltextIndexConsistencyCheckIT method mustDiscoverRelationshipInIndexMissingFromStore.
@Disabled("Turns out that this is not something that the consistency checker actually looks for, currently. " + "The test is disabled until the consistency checker is extended with checks that will discover this sort of inconsistency.")
@Test
void mustDiscoverRelationshipInIndexMissingFromStore() throws Exception {
GraphDatabaseService db = createDatabase();
try (Transaction tx = db.beginTx()) {
tx.execute(format(RELATIONSHIP_CREATE, "rels", asStrList("REL"), asStrList("prop"))).close();
tx.commit();
}
long relId;
try (Transaction tx = db.beginTx()) {
tx.schema().awaitIndexesOnline(2, TimeUnit.MINUTES);
Node node = tx.createNode();
Relationship rel = node.createRelationshipTo(node, RelationshipType.withName("REL"));
relId = rel.getId();
rel.setProperty("prop", "value");
tx.commit();
}
NeoStores stores = getNeoStores(db);
RelationshipRecord record = stores.getRelationshipStore().newRecord();
record = stores.getRelationshipStore().getRecord(relId, record, RecordLoad.NORMAL, NULL);
long propId = record.getNextProp();
record.setNextProp(AbstractBaseRecord.NO_ID);
stores.getRelationshipStore().updateRecord(record, NULL);
PropertyRecord propRecord = stores.getPropertyStore().getRecord(propId, stores.getPropertyStore().newRecord(), RecordLoad.NORMAL, NULL);
propRecord.setInUse(false);
stores.getPropertyStore().updateRecord(propRecord, NULL);
managementService.shutdown();
ConsistencyCheckService.Result result = checkConsistency();
assertFalse(result.isSuccessful());
}
use of org.neo4j.kernel.impl.store.record.PropertyRecord in project neo4j by neo4j.
the class SafePropertyChainReader method read.
<PRIMITIVE extends PrimitiveRecord> boolean read(MutableIntObjectMap<Value> intoValues, PRIMITIVE entity, Function<PRIMITIVE, ConsistencyReport.PrimitiveConsistencyReport> primitiveReporter, CursorContext cursorContext) {
lightClear(seenRecords);
long propertyRecordId = entity.getNextProp();
long previousRecordId = NULL_REFERENCE.longValue();
boolean chainIsOk = true;
while (!NULL_REFERENCE.is(propertyRecordId) && !context.isCancelled()) {
if (!seenRecords.add(propertyRecordId)) {
primitiveReporter.apply(entity).propertyChainContainsCircularReference(propertyReader.record());
chainIsOk = false;
break;
}
PropertyRecord propertyRecord = propertyReader.read(propertyRecordId);
if (!propertyRecord.inUse()) {
primitiveReporter.apply(entity).propertyNotInUse(propertyRecord);
reporter.forProperty(context.recordLoader.property(previousRecordId, cursorContext)).nextNotInUse(propertyRecord);
chainIsOk = false;
} else {
if (propertyRecord.getPrevProp() != previousRecordId) {
if (NULL_REFERENCE.is(previousRecordId)) {
primitiveReporter.apply(entity).propertyNotFirstInChain(propertyRecord);
} else {
reporter.forProperty(context.recordLoader.property(previousRecordId, cursorContext)).nextDoesNotReferenceBack(propertyRecord);
// prevDoesNotReferenceBack is not reported, unnecessary double report (same inconsistency from different directions)
}
chainIsOk = false;
}
for (PropertyBlock block : propertyRecord) {
int propertyKeyId = block.getKeyIndexId();
if (!checkValidToken(propertyRecord, propertyKeyId, context.tokenHolders.propertyKeyTokens(), neoStores.getPropertyKeyTokenStore(), (property, token) -> reporter.forProperty(property).invalidPropertyKey(block), (property, token) -> reporter.forProperty(property).keyNotInUse(block, token), cursorContext)) {
chainIsOk = false;
}
PropertyType type = block.forceGetType();
Value value = Values.NO_VALUE;
if (type == null) {
reporter.forProperty(propertyRecord).invalidPropertyType(block);
} else {
try {
switch(type) {
case STRING:
dynamicRecords.clear();
if (safeLoadDynamicRecordChain(record -> dynamicRecords.add(record.copy()), stringReader, seenDynamicRecordIds, block.getSingleValueLong(), stringStoreBlockSize, NO_DYNAMIC_HANDLER, (id, record) -> reporter.forProperty(propertyRecord).stringNotInUse(block, record), (id, record) -> reporter.forDynamicBlock(RecordType.STRING_PROPERTY, stringReader.record()).nextNotInUse(record), (id, record) -> reporter.forProperty(propertyRecord).stringEmpty(block, record), record -> reporter.forDynamicBlock(RecordType.STRING_PROPERTY, record).recordNotFullReferencesNext(), record -> reporter.forDynamicBlock(RecordType.STRING_PROPERTY, record).invalidLength())) {
value = propertyStore.getTextValueFor(dynamicRecords, cursorContext);
}
break;
case ARRAY:
dynamicRecords.clear();
if (safeLoadDynamicRecordChain(record -> dynamicRecords.add(record.copy()), arrayReader, seenDynamicRecordIds, block.getSingleValueLong(), arrayStoreBlockSize, NO_DYNAMIC_HANDLER, (id, record) -> reporter.forProperty(propertyRecord).arrayNotInUse(block, record), (id, record) -> reporter.forDynamicBlock(RecordType.ARRAY_PROPERTY, arrayReader.record()).nextNotInUse(record), (id, record) -> reporter.forProperty(propertyRecord).arrayEmpty(block, record), record -> reporter.forDynamicBlock(RecordType.ARRAY_PROPERTY, record).recordNotFullReferencesNext(), record -> reporter.forDynamicBlock(RecordType.ARRAY_PROPERTY, record).invalidLength())) {
value = propertyStore.getArrayFor(dynamicRecords, cursorContext);
}
break;
default:
value = type.value(block, null, cursorContext);
break;
}
} catch (Exception e) {
reporter.forProperty(propertyRecord).invalidPropertyValue(propertyRecord.getId(), block.getKeyIndexId());
}
}
if (value == Values.NO_VALUE) {
chainIsOk = false;
} else if (propertyKeyId >= 0 && intoValues.put(propertyKeyId, value) != null) {
primitiveReporter.apply(entity).propertyKeyNotUniqueInChain();
chainIsOk = false;
}
}
}
previousRecordId = propertyRecordId;
propertyRecordId = propertyRecord.getNextProp();
}
return chainIsOk;
}
use of org.neo4j.kernel.impl.store.record.PropertyRecord in project neo4j by neo4j.
the class BatchingNeoStoresTest method createRecordIn.
private static <RECORD extends AbstractBaseRecord> void createRecordIn(RecordStore<RECORD> store) {
RECORD record = store.newRecord();
record.setId(store.nextId(NULL));
record.setInUse(true);
if (record instanceof PropertyRecord) {
// Special hack for property store, since it's not enough to simply set a record as in use there
PropertyBlock block = new PropertyBlock();
((PropertyStore) store).encodeValue(block, 0, Values.of(10), NULL, INSTANCE);
((PropertyRecord) record).addPropertyBlock(block);
}
store.updateRecord(record, NULL);
}
use of org.neo4j.kernel.impl.store.record.PropertyRecord in project neo4j by neo4j.
the class LogCommandSerializationV4_0Test method readPropertyCommandWithFixedReferenceFormat.
@Test
void readPropertyCommandWithFixedReferenceFormat() throws IOException {
InMemoryClosableChannel channel = new InMemoryClosableChannel();
PropertyRecord before = new PropertyRecord(1);
PropertyRecord after = new PropertyRecord(1);
before.setUseFixedReferences(true);
after.setUseFixedReferences(true);
new Command.PropertyCommand(writer(), before, after).serialize(channel);
CommandReader reader = createReader();
StorageCommand command = reader.read(channel);
assertTrue(command instanceof Command.PropertyCommand);
Command.PropertyCommand propertyCommand = (Command.PropertyCommand) command;
// Then
assertBeforeAndAfterEquals(propertyCommand, before, after);
assertTrue(propertyCommand.getBefore().isUseFixedReferences());
assertTrue(propertyCommand.getAfter().isUseFixedReferences());
}
Aggregations