Search in sources :

Example 1 with Marker

use of org.neo4j.internal.id.IdGenerator.Marker in project neo4j by neo4j.

the class BufferingIdGeneratorFactoryTest method shouldDelayFreeingOfDeletedIds.

@Test
void shouldDelayFreeingOfDeletedIds() {
    // WHEN
    try (Marker marker = idGenerator.marker(NULL)) {
        marker.markDeleted(7);
    }
    verify(actual.markers[STRING_BLOCK.ordinal()]).markDeleted(7);
    verify(actual.markers[STRING_BLOCK.ordinal()]).close();
    verifyNoMoreInteractions(actual.markers[STRING_BLOCK.ordinal()]);
    // after some maintenance and transaction still not closed
    bufferingIdGeneratorFactory.maintenance(NULL);
    verifyNoMoreInteractions(actual.markers[STRING_BLOCK.ordinal()]);
    // although after transactions have all closed
    boundaries.setMostRecentlyReturnedSnapshotToAllClosed();
    bufferingIdGeneratorFactory.maintenance(NULL);
    // THEN
    verify(actual.markers[STRING_BLOCK.ordinal()]).markFree(7);
}
Also used : Marker(org.neo4j.internal.id.IdGenerator.Marker) Test(org.junit.jupiter.api.Test)

Example 2 with Marker

use of org.neo4j.internal.id.IdGenerator.Marker in project neo4j by neo4j.

the class BufferingIdGeneratorFactoryTest method shouldDelayFreeingOfDeletedIdsUntilCheckpoint.

@Test
void shouldDelayFreeingOfDeletedIdsUntilCheckpoint() {
    // WHEN
    try (Marker marker = idGenerator.marker(NULL)) {
        marker.markDeleted(7);
    }
    verify(actual.markers[STRING_BLOCK.ordinal()]).markDeleted(7);
    verify(actual.markers[STRING_BLOCK.ordinal()]).close();
    verifyNoMoreInteractions(actual.markers[STRING_BLOCK.ordinal()]);
    // after some maintenance and transaction still not closed
    idGenerator.checkpoint(NULL);
    verifyNoMoreInteractions(actual.markers[STRING_BLOCK.ordinal()]);
    // although after transactions have all closed
    boundaries.setMostRecentlyReturnedSnapshotToAllClosed();
    idGenerator.checkpoint(NULL);
    // THEN
    verify(actual.markers[STRING_BLOCK.ordinal()]).markFree(7);
}
Also used : Marker(org.neo4j.internal.id.IdGenerator.Marker) Test(org.junit.jupiter.api.Test)

Example 3 with Marker

use of org.neo4j.internal.id.IdGenerator.Marker in project neo4j by neo4j.

the class IndexedIdGeneratorTest method shouldMarkDroppedIdsAsDeletedAndFree.

@Test
void shouldMarkDroppedIdsAsDeletedAndFree() throws IOException {
    // given
    idGenerator.start(NO_FREE_IDS, NULL);
    long id = idGenerator.nextId(NULL);
    long droppedId = idGenerator.nextId(NULL);
    long id2 = idGenerator.nextId(NULL);
    // when
    try (Marker commitMarker = idGenerator.marker(NULL)) {
        commitMarker.markUsed(id);
        commitMarker.markUsed(id2);
    }
    restart();
    // then
    assertEquals(droppedId, idGenerator.nextId(NULL));
}
Also used : Marker(org.neo4j.internal.id.IdGenerator.Marker) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 4 with Marker

use of org.neo4j.internal.id.IdGenerator.Marker in project neo4j by neo4j.

the class IndexedIdGeneratorTest method shouldAwaitConcurrentOngoingMaintenanceIfToldTo.

@Test
void shouldAwaitConcurrentOngoingMaintenanceIfToldTo() throws Exception {
    // given
    idGenerator.close();
    Barrier.Control barrier = new Barrier.Control();
    IndexedIdGenerator.Monitor monitor = new IndexedIdGenerator.Monitor.Adapter() {

        private boolean first = true;

        @Override
        public void cached(long cachedId) {
            if (first) {
                barrier.reached();
                first = false;
            }
            super.cached(cachedId);
        }
    };
    idGenerator = new IndexedIdGenerator(pageCache, file, immediate(), IdType.LABEL_TOKEN, false, () -> 0, MAX_ID, writable(), Config.defaults(), NULL, monitor, DEFAULT_DATABASE_NAME, Sets.immutable.empty());
    idGenerator.start(NO_FREE_IDS, NULL);
    try (Marker marker = idGenerator.marker(NULL)) {
        for (int i = 0; i < 5; i++) {
            marker.markDeleted(i);
            marker.markFree(i);
        }
    }
    // when
    try (OtherThreadExecutor t2 = new OtherThreadExecutor("T2");
        OtherThreadExecutor t3 = new OtherThreadExecutor("T3")) {
        Future<Object> t2Future = t2.executeDontWait(() -> {
            idGenerator.nextId(NULL);
            return null;
        });
        barrier.await();
        // check that a maintenance call blocks
        Future<Object> t3Future = t3.executeDontWait(() -> {
            idGenerator.maintenance(NULL);
            return null;
        });
        t3.waitUntilWaiting(details -> details.isAt(FreeIdScanner.class, "tryLoadFreeIdsIntoCache"));
        barrier.release();
        t2Future.get();
        t3Future.get();
    }
}
Also used : OtherThreadExecutor(org.neo4j.test.OtherThreadExecutor) Barrier(org.neo4j.test.Barrier) Marker(org.neo4j.internal.id.IdGenerator.Marker) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 5 with Marker

use of org.neo4j.internal.id.IdGenerator.Marker in project neo4j by neo4j.

the class IndexedIdGeneratorTest method shouldPrioritizeFreelistOnConcurrentAllocation.

@Test
void shouldPrioritizeFreelistOnConcurrentAllocation() throws Exception {
    // given
    idGenerator.close();
    Barrier.Control barrier = new Barrier.Control();
    AtomicInteger numReserved = new AtomicInteger();
    AtomicInteger numCached = new AtomicInteger();
    AtomicBoolean enabled = new AtomicBoolean(true);
    IndexedIdGenerator.Monitor monitor = new IndexedIdGenerator.Monitor.Adapter() {

        @Override
        public void markedAsReserved(long markedId) {
            numReserved.incrementAndGet();
        }

        @Override
        public void cached(long cachedId) {
            int cached = numCached.incrementAndGet();
            if (cached == numReserved.get() && enabled.get()) {
                enabled.set(false);
                barrier.reached();
            }
        }

        @Override
        public void allocatedFromHigh(long allocatedId) {
            fail("Should not allocate from high ID");
        }
    };
    idGenerator = new IndexedIdGenerator(pageCache, file, immediate(), IdType.LABEL_TOKEN, false, () -> 0, MAX_ID, writable(), Config.defaults(), NULL, monitor, "db", Sets.immutable.empty());
    idGenerator.start(NO_FREE_IDS, NULL);
    // delete and free more than cache-size IDs
    try (Marker marker = idGenerator.marker(NULL)) {
        for (int i = 0; i < IndexedIdGenerator.SMALL_CACHE_CAPACITY + 10; i++) {
            marker.markDeleted(i);
            marker.markFree(i);
        }
    }
    // let one thread call nextId() and block when it has filled the cache (the above monitor will see to that it happens)
    try (OtherThreadExecutor t2 = new OtherThreadExecutor("T2")) {
        Future<Void> nextIdFuture = t2.executeDontWait(() -> {
            long id = idGenerator.nextId(NULL);
            assertEquals(IndexedIdGenerator.SMALL_CACHE_CAPACITY, id);
            return null;
        });
        // and let another thread allocate all those IDs before the T2 thread had a chance to get one of them
        barrier.await();
        for (int i = 0; i < numCached.get(); i++) {
            idGenerator.nextId(NULL);
        }
        // then let first thread continue and it should not allocate off of high id
        barrier.release();
        nextIdFuture.get();
    }
}
Also used : Barrier(org.neo4j.test.Barrier) Marker(org.neo4j.internal.id.IdGenerator.Marker) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) OtherThreadExecutor(org.neo4j.test.OtherThreadExecutor) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Aggregations

Test (org.junit.jupiter.api.Test)7 Marker (org.neo4j.internal.id.IdGenerator.Marker)7 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)4 Barrier (org.neo4j.test.Barrier)2 OtherThreadExecutor (org.neo4j.test.OtherThreadExecutor)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 Race (org.neo4j.test.Race)1 WorkSync (org.neo4j.util.concurrent.WorkSync)1