Search in sources :

Example 1 with Rebuilder

use of org.neo4j.internal.counts.GBPTreeGenericCountsStore.Rebuilder in project neo4j by neo4j.

the class GBPTreeGenericCountsStoreTest method shouldDeleteAndMarkForRebuildOnCorruptStore.

@Test
void shouldDeleteAndMarkForRebuildOnCorruptStore() throws Exception {
    // given
    try (CountUpdater updater = countsStore.updater(BASE_TX_ID + 1, NULL)) {
        updater.increment(nodeKey(LABEL_ID_1), 9);
    }
    closeCountsStore();
    try (StoreChannel channel = fs.open(countsStoreFile(), Set.of(StandardOpenOption.WRITE))) {
        ByteBuffer buffer = ByteBuffer.wrap(new byte[8192]);
        for (int i = 0; buffer.hasRemaining(); i++) {
            buffer.put((byte) i);
        }
        buffer.flip();
        channel.writeAll(buffer, 0);
    }
    // when
    Rebuilder countsBuilder = mock(Rebuilder.class);
    when(countsBuilder.lastCommittedTxId()).thenReturn(BASE_TX_ID);
    doAnswer(invocationOnMock -> {
        CountUpdater updater = invocationOnMock.getArgument(0, CountUpdater.class);
        updater.increment(nodeKey(LABEL_ID_1), 3);
        return null;
    }).when(countsBuilder).rebuild(any(), any(), any());
    openCountsStore(countsBuilder);
    // then rebuild store instead of throwing exception
    verify(countsBuilder).rebuild(any(), any(), any());
    assertEquals(3, countsStore.read(nodeKey(LABEL_ID_1), NULL));
}
Also used : StoreChannel(org.neo4j.io.fs.StoreChannel) ByteBuffer(java.nio.ByteBuffer) Rebuilder(org.neo4j.internal.counts.GBPTreeGenericCountsStore.Rebuilder) Test(org.junit.jupiter.api.Test)

Example 2 with Rebuilder

use of org.neo4j.internal.counts.GBPTreeGenericCountsStore.Rebuilder in project neo4j by neo4j.

the class GBPTreeGenericCountsStoreTest method shouldRebuildOnMismatchingLastCommittedTxId.

@Test
void shouldRebuildOnMismatchingLastCommittedTxId() throws IOException {
    // given some pre-state
    long countsStoreTxId = BASE_TX_ID + 1;
    try (CountUpdater updater = countsStore.updater(countsStoreTxId, NULL)) {
        updater.increment(nodeKey(1), 1);
    }
    // when
    countsStore.checkpoint(NULL);
    closeCountsStore();
    MutableBoolean rebuildTriggered = new MutableBoolean();
    openCountsStore(new Rebuilder() {

        @Override
        public long lastCommittedTxId() {
            return countsStoreTxId + 1;
        }

        @Override
        public void rebuild(CountUpdater updater, CursorContext cursorContext, MemoryTracker memoryTracker) {
            rebuildTriggered.setTrue();
        }
    });
    // then
    assertThat(rebuildTriggered.booleanValue()).isTrue();
}
Also used : MutableBoolean(org.apache.commons.lang3.mutable.MutableBoolean) CursorContext(org.neo4j.io.pagecache.context.CursorContext) Rebuilder(org.neo4j.internal.counts.GBPTreeGenericCountsStore.Rebuilder) MemoryTracker(org.neo4j.memory.MemoryTracker) Test(org.junit.jupiter.api.Test)

Example 3 with Rebuilder

use of org.neo4j.internal.counts.GBPTreeGenericCountsStore.Rebuilder in project neo4j by neo4j.

the class GBPTreeGenericCountsStoreTest method shouldNotRebuildOnMismatchingLastCommittedTxIdButMatchingAfterRecovery.

@Test
void shouldNotRebuildOnMismatchingLastCommittedTxIdButMatchingAfterRecovery() throws IOException {
    // given some pre-state
    long countsStoreTxId = BASE_TX_ID + 1;
    CountsKey key = nodeKey(1);
    try (CountUpdater updater = countsStore.updater(countsStoreTxId, NULL)) {
        updater.increment(key, 1);
    }
    // leaving a gap intentionally
    try (CountUpdater updater = countsStore.updater(countsStoreTxId + 2, NULL)) {
        updater.increment(key, 3);
    }
    countsStore.checkpoint(NULL);
    // when
    closeCountsStore();
    MutableBoolean rebuildTriggered = new MutableBoolean();
    instantiateCountsStore(new Rebuilder() {

        @Override
        public long lastCommittedTxId() {
            return countsStoreTxId + 2;
        }

        @Override
        public void rebuild(CountUpdater updater, CursorContext cursorContext, MemoryTracker memoryTracker) {
            rebuildTriggered.setTrue();
        }
    }, writable(), NO_MONITOR);
    // and do recovery
    try (CountUpdater updater = countsStore.updater(countsStoreTxId + 1, NULL)) {
        updater.increment(key, 7);
    }
    // already applied
    assertThat(countsStore.updater(countsStoreTxId + 2, NULL)).isNull();
    countsStore.start(NULL, INSTANCE);
    // then
    assertThat(rebuildTriggered.booleanValue()).isFalse();
    assertThat(countsStore.read(key, NULL)).isEqualTo(11);
}
Also used : MutableBoolean(org.apache.commons.lang3.mutable.MutableBoolean) CursorContext(org.neo4j.io.pagecache.context.CursorContext) Rebuilder(org.neo4j.internal.counts.GBPTreeGenericCountsStore.Rebuilder) MemoryTracker(org.neo4j.memory.MemoryTracker) Test(org.junit.jupiter.api.Test)

Example 4 with Rebuilder

use of org.neo4j.internal.counts.GBPTreeGenericCountsStore.Rebuilder in project neo4j by neo4j.

the class GBPTreeGenericCountsStoreTest method shouldNotApplyTransactionOnCreatedCountsStoreDuringRecovery.

@Test
void shouldNotApplyTransactionOnCreatedCountsStoreDuringRecovery() throws IOException {
    // given
    int labelId = 123;
    incrementNodeCount(BASE_TX_ID + 1, labelId, 4);
    countsStore.checkpoint(NULL);
    incrementNodeCount(BASE_TX_ID + 2, labelId, -2);
    closeCountsStore();
    deleteCountsStore();
    GBPTreeCountsStore.Monitor monitor = mock(GBPTreeCountsStore.Monitor.class);
    // instantiate, but don't start
    instantiateCountsStore(new Rebuilder() {

        @Override
        public void rebuild(CountUpdater updater, CursorContext cursorContext, MemoryTracker memoryTracker) {
            updater.increment(nodeKey(labelId), 2);
        }

        @Override
        public long lastCommittedTxId() {
            return BASE_TX_ID + 2;
        }
    }, writable(), monitor);
    // when doing recovery of the last transaction (since this is on an empty counts store then making the count negative, i.e. 0 - 2)
    // applying this negative delta would have failed in the updater.
    incrementNodeCount(BASE_TX_ID + 2, labelId, -2);
    verify(monitor).ignoredTransaction(BASE_TX_ID + 2);
    countsStore.start(NULL, INSTANCE);
    // then
    assertEquals(2, countsStore.read(nodeKey(labelId), NULL));
}
Also used : CursorContext(org.neo4j.io.pagecache.context.CursorContext) Rebuilder(org.neo4j.internal.counts.GBPTreeGenericCountsStore.Rebuilder) MemoryTracker(org.neo4j.memory.MemoryTracker) Test(org.junit.jupiter.api.Test)

Aggregations

Test (org.junit.jupiter.api.Test)4 Rebuilder (org.neo4j.internal.counts.GBPTreeGenericCountsStore.Rebuilder)4 CursorContext (org.neo4j.io.pagecache.context.CursorContext)3 MemoryTracker (org.neo4j.memory.MemoryTracker)3 MutableBoolean (org.apache.commons.lang3.mutable.MutableBoolean)2 ByteBuffer (java.nio.ByteBuffer)1 StoreChannel (org.neo4j.io.fs.StoreChannel)1