use of org.neo4j.io.pagecache.context.CursorContext.NULL in project neo4j by neo4j.
the class EncodingIdMapperTest method tracePageCacheAccessOnCollisions.
@Test
public void tracePageCacheAccessOnCollisions() {
EncodingIdMapper.Monitor monitor = mock(EncodingIdMapper.Monitor.class);
Encoder encoder = mock(Encoder.class);
when(encoder.encode(any())).thenReturn(12345L);
var pageCacheTracer = new DefaultPageCacheTracer();
IdMapper mapper = mapper(encoder, Radix.STRING, monitor, pageCacheTracer);
PropertyValueLookup ids = (nodeId, cursorContext) -> {
cursorContext.getCursorTracer().beginPin(false, 1, null).done();
return nodeId + "";
};
int expectedCollisions = 2;
for (int i = 0; i < expectedCollisions; i++) {
mapper.put(ids.lookupProperty(i, NULL), i, Group.GLOBAL);
}
ProgressListener progress = mock(ProgressListener.class);
Collector collector = mock(Collector.class);
mapper.prepare(ids, collector, progress);
verifyNoMoreInteractions(collector);
verify(monitor).numberOfCollisions(expectedCollisions);
assertEquals(expectedCollisions, pageCacheTracer.pins());
assertEquals(expectedCollisions, pageCacheTracer.unpins());
}
use of org.neo4j.io.pagecache.context.CursorContext.NULL in project neo4j by neo4j.
the class EncodingIdMapperTest method shouldPutFromMultipleThreads.
@Test
public void shouldPutFromMultipleThreads() throws Throwable {
// GIVEN
IdMapper idMapper = mapper(new StringEncoder(), Radix.STRING, EncodingIdMapper.NO_MONITOR);
AtomicLong highNodeId = new AtomicLong();
int batchSize = 1234;
Race race = new Race();
PropertyValueLookup inputIdLookup = (id, cursorContext) -> String.valueOf(id);
int countPerThread = 30_000;
race.addContestants(processors, () -> {
int cursor = batchSize;
long nextNodeId = 0;
for (int j = 0; j < countPerThread; j++) {
if (cursor == batchSize) {
nextNodeId = highNodeId.getAndAdd(batchSize);
cursor = 0;
}
long nodeId = nextNodeId++;
cursor++;
idMapper.put(inputIdLookup.lookupProperty(nodeId, NULL), nodeId, Group.GLOBAL);
}
});
// WHEN
race.go();
idMapper.prepare(inputIdLookup, mock(Collector.class), ProgressListener.NONE);
// THEN
int count = processors * countPerThread;
int countWithGapsWorstCase = count + batchSize * processors;
int correctHits = 0;
for (long nodeId = 0; nodeId < countWithGapsWorstCase; nodeId++) {
long result = idMapper.get(inputIdLookup.lookupProperty(nodeId, NULL), Group.GLOBAL);
if (result != -1) {
assertEquals(nodeId, result);
correctHits++;
}
}
assertEquals(count, correctHits);
}
use of org.neo4j.io.pagecache.context.CursorContext.NULL in project neo4j by neo4j.
the class IdContextFactoryBuilderTest method createContextWithCustomIdGeneratorFactoryWhenProvided.
@Test
void createContextWithCustomIdGeneratorFactoryWhenProvided() throws IOException {
IdGeneratorFactory idGeneratorFactory = mock(IdGeneratorFactory.class);
Config config = defaults();
IdContextFactory contextFactory = IdContextFactoryBuilder.of(fs, jobScheduler, config, PageCacheTracer.NULL).withIdGenerationFactoryProvider(any -> idGeneratorFactory).build();
DatabaseIdContext idContext = contextFactory.createIdContext(databaseIdRepository.getByName("database").get());
IdGeneratorFactory bufferedGeneratorFactory = idContext.getIdGeneratorFactory();
assertThat(idContext.getIdController()).isInstanceOf(BufferedIdController.class);
assertThat(bufferedGeneratorFactory).isInstanceOf(BufferingIdGeneratorFactory.class);
((BufferingIdGeneratorFactory) bufferedGeneratorFactory).initialize(() -> mock(KernelTransactionsSnapshot.class));
Path file = testDirectory.file("a");
IdType idType = IdType.NODE;
LongSupplier highIdSupplier = () -> 0;
int maxId = 100;
idGeneratorFactory.open(pageCache, file, idType, highIdSupplier, maxId, writable(), config, NULL, immutable.empty());
verify(idGeneratorFactory).open(pageCache, file, idType, highIdSupplier, maxId, writable(), config, NULL, immutable.empty());
}
use of org.neo4j.io.pagecache.context.CursorContext.NULL in project neo4j by neo4j.
the class IndexedIdGeneratorTest method shouldNotStartWithoutFileIfReadOnly.
@Test
void shouldNotStartWithoutFileIfReadOnly() {
Path file = directory.file("non-existing");
final IllegalStateException e = assertThrows(IllegalStateException.class, () -> new IndexedIdGenerator(pageCache, file, immediate(), IdType.LABEL_TOKEN, false, () -> 0, MAX_ID, readOnly(), Config.defaults(), DEFAULT_DATABASE_NAME, NULL));
assertTrue(Exceptions.contains(e, t -> t instanceof ReadOnlyDbException));
assertTrue(Exceptions.contains(e, t -> t instanceof TreeFileNotFoundException));
assertTrue(Exceptions.contains(e, t -> t instanceof IllegalStateException));
}
use of org.neo4j.io.pagecache.context.CursorContext.NULL in project neo4j by neo4j.
the class DelayedBufferTest method shouldNotReleaseValuesUntilCrossedThreshold.
@Test
void shouldNotReleaseValuesUntilCrossedThreshold() {
// GIVEN
VerifyingConsumer consumer = new VerifyingConsumer(30);
final AtomicLong txOpened = new AtomicLong();
final AtomicLong txClosed = new AtomicLong();
Supplier<Long> chunkThreshold = txOpened::get;
Predicate<Long> safeThreshold = value -> txClosed.get() >= value;
DelayedBuffer<Long> buffer = new DelayedBuffer<>(chunkThreshold, safeThreshold, 100, consumer);
// Transaction spans like these:
// 1 |-1--------2-------3---|
// 2 |4--5---------|
// 3 |---------6----|
// 4 |7--8-|
// 5 |--------9-------10-|
// 6 |--11----|
// 7 |-12---13---14--|
// TIME|1-2-3-4-5-6-7-8-9-a-b-c-d-e-f-g-h-i-j|
// POI ^ ^ ^ ^ ^ ^
// A B C D E F
// A
// <-- TX 1
txOpened.incrementAndGet();
buffer.offer(1);
// <-- TX 2
txOpened.incrementAndGet();
buffer.offer(4);
buffer.maintenance(NULL);
assertEquals(0, consumer.chunksAccepted());
// B
buffer.offer(5);
// <-- TX 3
txOpened.incrementAndGet();
// <-- TX 4
txOpened.incrementAndGet();
buffer.offer(7);
buffer.maintenance(NULL);
assertEquals(0, consumer.chunksAccepted());
// C
// <-- TX 5
txOpened.incrementAndGet();
buffer.offer(2);
buffer.offer(8);
// TX 4 closes, but TXs with lower ids are still open
buffer.maintenance(NULL);
assertEquals(0, consumer.chunksAccepted());
// D
// TX 2 closes, but TXs with lower ids are still open
buffer.offer(6);
// <-- TX 6
txOpened.incrementAndGet();
buffer.offer(9);
buffer.offer(3);
// <-- TX 7
txOpened.incrementAndGet();
buffer.offer(11);
// TX 3 closes, but TXs with lower ids are still open
buffer.offer(12);
// since 1-4 have now all closed
txClosed.set(4);
buffer.maintenance(NULL);
consumer.assertHaveOnlySeen(1, 4, 5, 7);
// E
buffer.offer(10);
// TX 6 closes, but TXs with lower ids are still open
buffer.offer(13);
// since 1-6 have now all closed
txClosed.set(6);
buffer.maintenance(NULL);
consumer.assertHaveOnlySeen(1, 2, 4, 5, 7, 8);
// F
buffer.offer(14);
// since 1-7 have now all closed
txClosed.set(7);
buffer.maintenance(NULL);
consumer.assertHaveOnlySeen(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
}
Aggregations