use of org.neo4j.io.pagecache.context.CursorContext.NULL in project neo4j by neo4j.
the class NodeStoreTest method scanningRecordsShouldVisitEachInUseRecordOnce.
@Test
void scanningRecordsShouldVisitEachInUseRecordOnce() throws IOException {
// GIVEN we have a NodeStore with data that spans several pages...
nodeStore = newNodeStore(fs);
ThreadLocalRandom rng = ThreadLocalRandom.current();
final MutableLongSet nextRelSet = new LongHashSet();
for (int i = 0; i < 10_000; i++) {
// Enough records to span several pages
int nextRelCandidate = rng.nextInt(0, Integer.MAX_VALUE);
if (nextRelSet.add(nextRelCandidate)) {
long nodeId = nodeStore.nextId(NULL);
NodeRecord record = new NodeRecord(nodeId).initialize(true, 20, false, nextRelCandidate, 0);
nodeStore.updateRecord(record, NULL);
if (rng.nextInt(0, 10) < 3) {
nextRelSet.remove(nextRelCandidate);
record.setInUse(false);
nodeStore.updateRecord(record, NULL);
}
}
}
// ...WHEN we now have an interesting set of node records, and we
// visit each and remove that node from our nextRelSet...
Visitor<NodeRecord, IOException> scanner = record -> {
// ...THEN we should observe that no nextRel is ever removed twice...
assertTrue(nextRelSet.remove(record.getNextRel()));
return false;
};
nodeStore.scanAllRecords(scanner, NULL);
// ...NOR do we have anything left in the set afterwards.
assertTrue(nextRelSet.isEmpty());
}
use of org.neo4j.io.pagecache.context.CursorContext.NULL in project neo4j by neo4j.
the class DatabaseStartupTest method startTheDatabaseWithWrongVersionShouldFailWithUpgradeNotAllowed.
@Test
void startTheDatabaseWithWrongVersionShouldFailWithUpgradeNotAllowed() throws Throwable {
// given
// create a store
DatabaseManagementService managementService = new TestDatabaseManagementServiceBuilder(databaseLayout).build();
GraphDatabaseAPI db = (GraphDatabaseAPI) managementService.database(DEFAULT_DATABASE_NAME);
try (Transaction tx = db.beginTx()) {
tx.createNode();
tx.commit();
}
managementService.shutdown();
// mess up the version in the metadatastore
try (FileSystemAbstraction fileSystem = new DefaultFileSystemAbstraction();
ThreadPoolJobScheduler scheduler = new ThreadPoolJobScheduler();
PageCache pageCache = createPageCache(fileSystem, scheduler, PageCacheTracer.NULL)) {
MetaDataStore.setRecord(pageCache, databaseLayout.metadataStore(), MetaDataStore.Position.STORE_VERSION, MetaDataStore.versionStringToLong("bad"), databaseLayout.getDatabaseName(), NULL);
}
managementService = new TestDatabaseManagementServiceBuilder(databaseLayout).build();
GraphDatabaseAPI databaseService = (GraphDatabaseAPI) managementService.database(DEFAULT_DATABASE_NAME);
try {
assertThrows(DatabaseShutdownException.class, databaseService::beginTx);
DatabaseStateService dbStateService = databaseService.getDependencyResolver().resolveDependency(DatabaseStateService.class);
assertTrue(dbStateService.causeOfFailure(databaseService.databaseId()).isPresent());
Throwable throwable = findCauseOrSuppressed(dbStateService.causeOfFailure(databaseService.databaseId()).get(), e -> e instanceof IllegalArgumentException).get();
assertEquals("Unknown store version 'bad'", throwable.getMessage());
} finally {
managementService.shutdown();
}
}
use of org.neo4j.io.pagecache.context.CursorContext.NULL in project neo4j by neo4j.
the class CsvInputBatchImportIT method buildUpExpectedData.
private static void buildUpExpectedData(List<InputEntity> nodeData, List<InputEntity> relationshipData, Map<String, InputEntity> expectedNodes, Map<String, String[]> expectedNodeNames, Map<String, Map<String, Consumer<Object>>> expectedNodePropertyVerifiers, Map<String, Map<String, Map<String, AtomicInteger>>> expectedRelationships, Map<String, AtomicLong> nodeCounts, Map<String, Map<String, Map<String, AtomicLong>>> relationshipCounts) {
for (InputEntity node : nodeData) {
expectedNodes.put((String) node.id(), node);
expectedNodeNames.put(nameOf(node), node.labels());
// Build default verifiers for all the properties that compares the property value using equals
Assertions.assertFalse(node.hasIntPropertyKeyIds);
Map<String, Consumer<Object>> propertyVerifiers = new TreeMap<>();
for (int i = 0; i < node.propertyCount(); i++) {
final Object expectedValue = node.propertyValue(i);
Consumer verify;
if (expectedValue instanceof TemporalAmount) {
// Since there is no straightforward comparison for TemporalAmount we add it to a reference
// point in time and compare the result
verify = actualValue -> {
LocalDateTime referenceTemporal = LocalDateTime.of(0, 1, 1, 0, 0);
LocalDateTime expected = referenceTemporal.plus((TemporalAmount) expectedValue);
LocalDateTime actual = referenceTemporal.plus((TemporalAmount) actualValue);
assertEquals(expected, actual);
};
} else if (expectedValue instanceof Temporal) {
final LocalDate expectedDate = ((Temporal) expectedValue).query(TemporalQueries.localDate());
final LocalTime expectedTime = ((Temporal) expectedValue).query(TemporalQueries.localTime());
final ZoneId expectedZoneId = ((Temporal) expectedValue).query(TemporalQueries.zone());
verify = actualValue -> {
LocalDate actualDate = ((Temporal) actualValue).query(TemporalQueries.localDate());
LocalTime actualTime = ((Temporal) actualValue).query(TemporalQueries.localTime());
ZoneId actualZoneId = ((Temporal) actualValue).query(TemporalQueries.zone());
assertEquals(expectedDate, actualDate);
assertEquals(expectedTime, actualTime);
if (expectedZoneId == null) {
if (actualZoneId != null) {
// If the actual value is zoned it should have the default zone
assertEquals(testDefaultTimeZone.get(), actualZoneId);
}
} else {
assertEquals(expectedZoneId, actualZoneId);
}
};
} else if (expectedValue instanceof float[]) {
verify = actualValue -> assertArrayEquals((float[]) expectedValue, (float[]) actualValue);
} else if (expectedValue.getClass().isArray()) {
verify = actualValue -> assertArrayEquals((Object[]) expectedValue, (Object[]) actualValue);
} else {
verify = actualValue -> assertEquals(expectedValue, actualValue);
}
propertyVerifiers.put((String) node.propertyKey(i), verify);
}
// Special verifier for pointA property
Consumer verifyPointA = actualValue -> {
// The y-coordinate should match the node number modulo 90 (so we don't break wgs boundaries)
PointValue v = (PointValue) actualValue;
double actualY = v.getCoordinates().get(0).getCoordinate().get(1);
double expectedY = indexOf(node) % 90;
String message = actualValue + " does not have y=" + expectedY;
assertEquals(expectedY, actualY, 0.1, message);
message = actualValue + " does not have crs=wgs-84";
assertEquals(CoordinateReferenceSystem.WGS84.getName(), v.getCoordinateReferenceSystem().getName(), message);
};
propertyVerifiers.put("pointA", verifyPointA);
// Special verifier for pointB property
Consumer verifyPointB = actualValue -> {
// The y-coordinate should match the node number
PointValue v = (PointValue) actualValue;
double actualY = v.getCoordinates().get(0).getCoordinate().get(1);
double expectedY = indexOf(node);
String message = actualValue + " does not have y=" + expectedY;
assertEquals(expectedY, actualY, 0.1, message);
message = actualValue + " does not have crs=cartesian";
assertEquals(CoordinateReferenceSystem.Cartesian.getName(), v.getCoordinateReferenceSystem().getName(), message);
};
propertyVerifiers.put("pointB", verifyPointB);
// Special verifier for pointArray property
Consumer verifyPointArray = actualValue -> verifyPointB.accept(((PointValue[]) actualValue)[0]);
propertyVerifiers.put("pointArray", verifyPointArray);
expectedNodePropertyVerifiers.put(nameOf(node), propertyVerifiers);
countNodeLabels(nodeCounts, node.labels());
}
for (InputEntity relationship : relationshipData) {
// Expected relationship counts per node, type and direction
InputEntity startNode = expectedNodes.get(relationship.startId());
InputEntity endNode = expectedNodes.get(relationship.endId());
{
expectedRelationships.get(nameOf(startNode)).get(nameOf(endNode)).get(relationship.stringType).incrementAndGet();
}
// Expected counts per start/end node label ids
// Let's do what CountsState#addRelationship does, roughly
relationshipCounts.get(null).get(null).get(null).incrementAndGet();
relationshipCounts.get(null).get(relationship.stringType).get(null).incrementAndGet();
for (String startNodeLabelName : asSet(startNode.labels())) {
Map<String, Map<String, AtomicLong>> startLabelCounts = relationshipCounts.get(startNodeLabelName);
startLabelCounts.get(null).get(null).incrementAndGet();
Map<String, AtomicLong> typeCounts = startLabelCounts.get(relationship.stringType);
typeCounts.get(null).incrementAndGet();
if (COMPUTE_DOUBLE_SIDED_RELATIONSHIP_COUNTS) {
for (String endNodeLabelName : asSet(endNode.labels())) {
startLabelCounts.get(null).get(endNodeLabelName).incrementAndGet();
typeCounts.get(endNodeLabelName).incrementAndGet();
}
}
}
for (String endNodeLabelName : asSet(endNode.labels())) {
relationshipCounts.get(null).get(null).get(endNodeLabelName).incrementAndGet();
relationshipCounts.get(null).get(relationship.stringType).get(endNodeLabelName).incrementAndGet();
}
}
}
use of org.neo4j.io.pagecache.context.CursorContext.NULL in project neo4j by neo4j.
the class SeekCursorTestBase method shouldCatchupRootWhenNodeHasTooNewGenerationWhileTraversingLeaves.
@Test
void shouldCatchupRootWhenNodeHasTooNewGenerationWhileTraversingLeaves() throws Exception {
// given
MutableBoolean triggered = new MutableBoolean(false);
// We don't care
long oldRightChild = 666;
// a newer right leaf
long rightChild = cursor.getCurrentPageId();
node.initializeLeaf(cursor, stableGeneration, unstableGeneration);
cursor.next();
RootCatchup rootCatchup = fromId -> {
// Use right child as new start over root to terminate test
cursor.next(rightChild);
triggered.setTrue();
return new Root(cursor.getCurrentPageId(), TreeNode.generation(cursor));
};
// a left leaf
long leftChild = cursor.getCurrentPageId();
node.initializeLeaf(cursor, stableGeneration - 1, unstableGeneration - 1);
// with an old pointer to right sibling
TreeNode.setRightSibling(cursor, rightChild, stableGeneration - 1, unstableGeneration - 1);
cursor.next();
// a root
node.initializeInternal(cursor, stableGeneration - 1, unstableGeneration - 1);
long keyInRoot = 10L;
node.insertKeyAndRightChildAt(cursor, key(keyInRoot), oldRightChild, 0, 0, stableGeneration, unstableGeneration, NULL);
TreeNode.setKeyCount(cursor, 1);
// with old pointer to child (simulating reuse of internal node)
node.setChildAt(cursor, leftChild, 0, stableGeneration, unstableGeneration);
// when
KEY from = key(1L);
KEY to = key(20L);
try (SeekCursor<KEY, VALUE> seek = new SeekCursor<>(cursor, node, from, to, layout, stableGeneration - 1, unstableGeneration - 1, generationSupplier, rootCatchup, unstableGeneration, exceptionDecorator, 1, LEAF_LEVEL, SeekCursor.NO_MONITOR, NULL)) {
while (seek.next()) {
seek.key();
}
}
// then
assertTrue(triggered.getValue());
}
use of org.neo4j.io.pagecache.context.CursorContext.NULL in project neo4j by neo4j.
the class SeekCursorTestBase method shouldCatchupRootWhenRootNodeHasTooNewGeneration.
@Test
void shouldCatchupRootWhenRootNodeHasTooNewGeneration() throws Exception {
// given
long id = cursor.getCurrentPageId();
long generation = TreeNode.generation(cursor);
MutableBoolean triggered = new MutableBoolean(false);
RootCatchup rootCatchup = fromId -> {
triggered.setTrue();
return new Root(id, generation);
};
// noinspection EmptyTryBlock
try (SeekCursor<KEY, VALUE> ignored = new SeekCursor<>(cursor, node, key(0), key(1), layout, stableGeneration, unstableGeneration, generationSupplier, rootCatchup, generation - 1, exceptionDecorator, 1, LEAF_LEVEL, SeekCursor.NO_MONITOR, NULL)) {
// do nothing
}
// then
assertTrue(triggered.getValue());
}
Aggregations