use of org.neo4j.kernel.impl.store.record.RelationshipRecord in project neo4j by neo4j.
the class LogCommandSerializationV3_0_10 method readRelationshipRecord.
private static RelationshipRecord readRelationshipRecord(long id, ReadableChannel channel) throws IOException {
byte flags = channel.get();
boolean inUse = bitFlag(flags, Record.IN_USE.byteValue());
boolean requiresSecondaryUnit = bitFlag(flags, Record.REQUIRE_SECONDARY_UNIT);
boolean hasSecondaryUnit = bitFlag(flags, Record.HAS_SECONDARY_UNIT);
boolean usesFixedReferenceFormat = bitFlag(flags, Record.USES_FIXED_REFERENCE_FORMAT);
RelationshipRecord record;
if (inUse) {
record = new RelationshipRecord(id);
record.setLinks(channel.getLong(), channel.getLong(), channel.getInt());
record.setInUse(true);
record.setRequiresSecondaryUnit(requiresSecondaryUnit);
record.setFirstPrevRel(channel.getLong());
record.setFirstNextRel(channel.getLong());
record.setSecondPrevRel(channel.getLong());
record.setSecondNextRel(channel.getLong());
record.setNextProp(channel.getLong());
byte extraByte = channel.get();
record.setFirstInFirstChain((extraByte & 0x1) > 0);
record.setFirstInSecondChain((extraByte & 0x2) > 0);
if (hasSecondaryUnit) {
record.setSecondaryUnitIdOnLoad(channel.getLong());
}
record.setUseFixedReferences(usesFixedReferenceFormat);
} else {
record = new RelationshipRecord(id);
record.setLinks(-1, -1, channel.getInt());
record.setInUse(false);
}
if (bitFlag(flags, Record.CREATED_IN_TX)) {
record.setCreated();
}
return record;
}
use of org.neo4j.kernel.impl.store.record.RelationshipRecord in project neo4j by neo4j.
the class LogCommandSerializationV3_0_10 method readRelationshipCommand.
@Override
protected Command readRelationshipCommand(ReadableChannel channel) throws IOException {
long id = channel.getLong();
RelationshipRecord before = readRelationshipRecord(id, channel);
if (before == null) {
return null;
}
RelationshipRecord after = readRelationshipRecord(id, channel);
if (after == null) {
return null;
}
if (!before.inUse() && after.inUse()) {
after.setCreated();
}
return new Command.RelationshipCommand(this, before, after);
}
use of org.neo4j.kernel.impl.store.record.RelationshipRecord 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.RelationshipRecord in project neo4j by neo4j.
the class RelationshipChecker method check.
private void check(LongRange nodeIdRange, boolean firstRound, long fromRelationshipId, long toRelationshipId, boolean checkToEndOfIndex) throws Exception {
RelationshipCounter counter = observedCounts.instantiateRelationshipCounter();
long[] typeHolder = new long[1];
try (var cursorContext = new CursorContext(context.pageCacheTracer.createPageCursorTracer(RELATIONSHIP_RANGE_CHECKER_TAG));
RecordReader<RelationshipRecord> relationshipReader = new RecordReader<>(context.neoStores.getRelationshipStore(), true, cursorContext);
BoundedIterable<EntityTokenRange> relationshipTypeReader = getRelationshipTypeIndexReader(fromRelationshipId, toRelationshipId, checkToEndOfIndex, cursorContext);
SafePropertyChainReader property = new SafePropertyChainReader(context, cursorContext);
SchemaComplianceChecker schemaComplianceChecker = new SchemaComplianceChecker(context, mandatoryProperties, indexes, cursorContext, context.memoryTracker)) {
ProgressListener localProgress = progress.threadLocalReporter();
CacheAccess.Client client = cacheAccess.client();
MutableIntObjectMap<Value> propertyValues = new IntObjectHashMap<>();
Iterator<EntityTokenRange> relationshipTypeRangeIterator = relationshipTypeReader.iterator();
EntityTokenIndexCheckState typeIndexState = new EntityTokenIndexCheckState(null, fromRelationshipId - 1);
for (long relationshipId = fromRelationshipId; relationshipId < toRelationshipId && !context.isCancelled(); relationshipId++) {
localProgress.add(1);
RelationshipRecord relationshipRecord = relationshipReader.read(relationshipId);
if (!relationshipRecord.inUse()) {
continue;
}
// Start/end nodes
long startNode = relationshipRecord.getFirstNode();
boolean startNodeIsWithinRange = nodeIdRange.isWithinRangeExclusiveTo(startNode);
boolean startNodeIsNegativeOnFirstRound = startNode < 0 && firstRound;
if (startNodeIsWithinRange || startNodeIsNegativeOnFirstRound) {
checkRelationshipVsNode(client, relationshipRecord, startNode, relationshipRecord.isFirstInFirstChain(), (relationship, node) -> reporter.forRelationship(relationship).sourceNodeNotInUse(node), (relationship, node) -> reporter.forRelationship(relationship).sourceNodeDoesNotReferenceBack(node), (relationship, node) -> reporter.forNode(node).relationshipNotFirstInSourceChain(relationship), (relationship, node) -> reporter.forRelationship(relationship).sourceNodeHasNoRelationships(node), relationship -> reporter.forRelationship(relationship).illegalSourceNode(), cursorContext);
}
long endNode = relationshipRecord.getSecondNode();
boolean endNodeIsWithinRange = nodeIdRange.isWithinRangeExclusiveTo(endNode);
boolean endNodeIsNegativeOnFirstRound = endNode < 0 && firstRound;
if (endNodeIsWithinRange || endNodeIsNegativeOnFirstRound) {
checkRelationshipVsNode(client, relationshipRecord, endNode, relationshipRecord.isFirstInSecondChain(), (relationship, node) -> reporter.forRelationship(relationship).targetNodeNotInUse(node), (relationship, node) -> reporter.forRelationship(relationship).targetNodeDoesNotReferenceBack(node), (relationship, node) -> reporter.forNode(node).relationshipNotFirstInTargetChain(relationship), (relationship, node) -> reporter.forRelationship(relationship).targetNodeHasNoRelationships(node), relationship -> reporter.forRelationship(relationship).illegalTargetNode(), cursorContext);
}
if (firstRound) {
if (startNode >= context.highNodeId) {
reporter.forRelationship(relationshipRecord).sourceNodeNotInUse(context.recordLoader.node(startNode, cursorContext));
}
if (endNode >= context.highNodeId) {
reporter.forRelationship(relationshipRecord).targetNodeNotInUse(context.recordLoader.node(endNode, cursorContext));
}
// Properties
typeHolder[0] = relationshipRecord.getType();
lightClear(propertyValues);
boolean propertyChainIsOk = property.read(propertyValues, relationshipRecord, reporter::forRelationship, cursorContext);
if (propertyChainIsOk) {
schemaComplianceChecker.checkContainsMandatoryProperties(relationshipRecord, typeHolder, propertyValues, reporter::forRelationship);
// gets checked this way, larger indexes will be checked in IndexChecker
if (context.consistencyFlags.isCheckIndexes()) {
schemaComplianceChecker.checkCorrectlyIndexed((RelationshipRecord) relationshipRecord, typeHolder, propertyValues, reporter::forRelationship);
}
}
// Type and count
checkValidToken(relationshipRecord, relationshipRecord.getType(), tokenHolders.relationshipTypeTokens(), neoStores.getRelationshipTypeTokenStore(), (rel, token) -> reporter.forRelationship(rel).illegalRelationshipType(), (rel, token) -> reporter.forRelationship(rel).relationshipTypeNotInUse(token), cursorContext);
observedCounts.incrementRelationshipTypeCounts(counter, relationshipRecord);
// Relationship type index
if (relationshipTypeReader.maxCount() != 0) {
checkRelationshipVsRelationshipTypeIndex(relationshipRecord, relationshipTypeRangeIterator, typeIndexState, relationshipId, relationshipRecord.getType(), fromRelationshipId, cursorContext);
}
}
observedCounts.incrementRelationshipNodeCounts(counter, relationshipRecord, startNodeIsWithinRange, endNodeIsWithinRange);
}
if (firstRound && !context.isCancelled() && relationshipTypeReader.maxCount() != 0) {
reportRemainingRelationshipTypeIndexEntries(relationshipTypeRangeIterator, typeIndexState, checkToEndOfIndex ? Long.MAX_VALUE : toRelationshipId, cursorContext);
}
localProgress.done();
}
}
use of org.neo4j.kernel.impl.store.record.RelationshipRecord in project neo4j by neo4j.
the class PageCachePrefetchingTest method scanningWithPreFetchMustGiveScannerFewerPageFaultsWhenScannerIsSlow.
@Test
void scanningWithPreFetchMustGiveScannerFewerPageFaultsWhenScannerIsSlow() throws Exception {
RecordFormat<RelationshipRecord> format = Standard.LATEST_RECORD_FORMATS.relationship();
RelationshipRecord record = format.newRecord();
int recordSize = format.getRecordSize(NoStoreHeader.NO_STORE_HEADER);
int recordsPerPage = PageCache.PAGE_SIZE / recordSize;
SplittableRandom rng = new SplittableRandom(13);
// This scanner is a bit on the slow side:
scanner = cursor -> {
for (int j = 0; j < recordsPerPage; j++) {
try {
record.initialize(rng.nextBoolean(), rng.nextInt(), rng.nextInt(), rng.nextInt(), rng.nextInt() & 0xFFFF, rng.nextInt(), rng.nextInt(), rng.nextInt(), rng.nextInt(), rng.nextBoolean(), rng.nextBoolean());
format.write(record, cursor, recordSize, recordsPerPage);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
};
runScan(file, cursorContext, "Warmup", PF_READ_AHEAD);
long faultsWithPreFetch = runScan(file, cursorContext, "Scanner With Prefetch", PF_READ_AHEAD);
long faultsWithoutPreFetch = runScan(file, cursorContext, "Scanner Without Prefetch", 0);
assertThat(faultsWithPreFetch).as("faults").isLessThan(faultsWithoutPreFetch);
}
Aggregations