Search in sources :

Example 16 with IndexEntryUpdate

use of org.neo4j.storageengine.api.IndexEntryUpdate in project neo4j by neo4j.

the class IndexRecoveryIT method shouldBeAbleToRecoverAndUpdateOnlineIndex.

@Test
void shouldBeAbleToRecoverAndUpdateOnlineIndex() throws Exception {
    // Given
    startDb();
    IndexPopulator populator = mock(IndexPopulator.class);
    when(mockedIndexProvider.getPopulator(any(IndexDescriptor.class), any(IndexSamplingConfig.class), any(), any(), any(TokenNameLookup.class))).thenReturn(populator);
    when(populator.sample(any(CursorContext.class))).thenReturn(new IndexSample());
    IndexAccessor mockedAccessor = mock(IndexAccessor.class);
    when(mockedAccessor.newUpdater(any(IndexUpdateMode.class), any(CursorContext.class))).thenReturn(SwallowingIndexUpdater.INSTANCE);
    when(mockedIndexProvider.getOnlineAccessor(any(IndexDescriptor.class), any(IndexSamplingConfig.class), any(TokenNameLookup.class))).thenReturn(mockedAccessor);
    createIndexAndAwaitPopulation(myLabel);
    // rotate logs
    rotateLogsAndCheckPoint();
    // make updates
    Set<IndexEntryUpdate<?>> expectedUpdates = createSomeBananas(myLabel);
    // And Given
    killDb();
    when(mockedIndexProvider.getInitialState(any(IndexDescriptor.class), any(CursorContext.class))).thenReturn(ONLINE);
    GatheringIndexWriter writer = new GatheringIndexWriter();
    when(mockedIndexProvider.getOnlineAccessor(any(IndexDescriptor.class), any(IndexSamplingConfig.class), any(TokenNameLookup.class))).thenReturn(writer);
    // When
    startDb();
    // Then
    try (Transaction transaction = db.beginTx()) {
        assertThat(transaction.schema().getIndexes(myLabel)).hasSize(1);
        assertThat(transaction.schema().getIndexes(myLabel)).extracting(i -> transaction.schema().getIndexState(i)).containsOnly(Schema.IndexState.ONLINE);
    }
    verify(mockedIndexProvider).getPopulator(any(IndexDescriptor.class), any(IndexSamplingConfig.class), any(), any(), any(TokenNameLookup.class));
    // once when we create the index, and once when we restart the db
    int onlineAccessorInvocationCount = 3;
    verify(mockedIndexProvider, times(onlineAccessorInvocationCount)).getOnlineAccessor(any(IndexDescriptor.class), any(IndexSamplingConfig.class), any(TokenNameLookup.class));
    assertEquals(expectedUpdates, writer.batchedUpdates);
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) SchemaIndexTestHelper.singleInstanceIndexProviderFactory(org.neo4j.kernel.impl.api.index.SchemaIndexTestHelper.singleInstanceIndexProviderFactory) CursorContext(org.neo4j.io.pagecache.context.CursorContext) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) TokenNameLookup(org.neo4j.common.TokenNameLookup) IndexPopulator(org.neo4j.kernel.api.index.IndexPopulator) InternalTransaction(org.neo4j.kernel.impl.coreapi.InternalTransaction) DatabaseLayout(org.neo4j.io.layout.DatabaseLayout) DEFAULT_DATABASE_NAME(org.neo4j.configuration.GraphDatabaseSettings.DEFAULT_DATABASE_NAME) Future(java.util.concurrent.Future) LogRotation(org.neo4j.kernel.impl.transaction.log.rotation.LogRotation) IndexUpdater(org.neo4j.kernel.api.index.IndexUpdater) Monitors(org.neo4j.monitoring.Monitors) Arrays.asList(java.util.Arrays.asList) Transaction(org.neo4j.graphdb.Transaction) Path(java.nio.file.Path) RecoveryMonitor(org.neo4j.kernel.recovery.RecoveryMonitor) PageCache(org.neo4j.io.pagecache.PageCache) TokenIndexProviderFactory(org.neo4j.kernel.impl.index.schema.TokenIndexProviderFactory) Recovery(org.neo4j.kernel.recovery.Recovery) Set(java.util.Set) FileUtils(org.neo4j.io.fs.FileUtils) TestDirectory(org.neo4j.test.rule.TestDirectory) Executors.newSingleThreadExecutor(java.util.concurrent.Executors.newSingleThreadExecutor) IndexEntryUpdate(org.neo4j.storageengine.api.IndexEntryUpdate) Neo4jLayoutExtension(org.neo4j.test.extension.Neo4jLayoutExtension) Schema(org.neo4j.graphdb.schema.Schema) SimpleTriggerInfo(org.neo4j.kernel.impl.transaction.log.checkpoint.SimpleTriggerInfo) GraphDatabaseAPI(org.neo4j.kernel.internal.GraphDatabaseAPI) Test(org.junit.jupiter.api.Test) GraphDatabaseSettings.default_schema_provider(org.neo4j.configuration.GraphDatabaseSettings.default_schema_provider) INSTANCE(org.neo4j.memory.EmptyMemoryTracker.INSTANCE) PROVIDER_DESCRIPTOR(org.neo4j.kernel.impl.api.index.TestIndexProviderDescriptor.PROVIDER_DESCRIPTOR) SchemaDescriptor(org.neo4j.internal.schema.SchemaDescriptor) IndexDescriptor(org.neo4j.internal.schema.IndexDescriptor) DatabaseManagementService(org.neo4j.dbms.api.DatabaseManagementService) Mockito.mock(org.mockito.Mockito.mock) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) CollectingIndexUpdater(org.neo4j.kernel.impl.index.schema.CollectingIndexUpdater) Label(org.neo4j.graphdb.Label) Config.defaults(org.neo4j.configuration.Config.defaults) InternalIndexState(org.neo4j.internal.kernel.api.InternalIndexState) CheckPointer(org.neo4j.kernel.impl.transaction.log.checkpoint.CheckPointer) MINUTES(java.util.concurrent.TimeUnit.MINUTES) IndexAccessor(org.neo4j.kernel.api.index.IndexAccessor) Node(org.neo4j.graphdb.Node) IndexProvider(org.neo4j.kernel.api.index.IndexProvider) Values(org.neo4j.values.storable.Values) HashSet(java.util.HashSet) TestDatabaseManagementServiceBuilder(org.neo4j.test.TestDatabaseManagementServiceBuilder) Inject(org.neo4j.test.extension.Inject) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) ONLINE(org.neo4j.internal.kernel.api.InternalIndexState.ONLINE) ExecutorService(java.util.concurrent.ExecutorService) IndexSample(org.neo4j.kernel.api.index.IndexSample) Semaphore(java.util.concurrent.Semaphore) IOException(java.io.IOException) Mockito.times(org.mockito.Mockito.times) LabelSchemaDescriptor(org.neo4j.internal.schema.LabelSchemaDescriptor) LogAppendEvent(org.neo4j.kernel.impl.transaction.tracing.LogAppendEvent) StoreMigrationParticipant(org.neo4j.storageengine.migration.StoreMigrationParticipant) Mockito.when(org.mockito.Mockito.when) Label.label(org.neo4j.graphdb.Label.label) Mockito.verify(org.mockito.Mockito.verify) ExecutionException(java.util.concurrent.ExecutionException) AfterEach(org.junit.jupiter.api.AfterEach) ExtensionFactory(org.neo4j.kernel.extension.ExtensionFactory) Mockito.never(org.mockito.Mockito.never) KernelTransaction(org.neo4j.kernel.api.KernelTransaction) IndexDefinition(org.neo4j.graphdb.schema.IndexDefinition) FileSystemAbstraction(org.neo4j.io.fs.FileSystemAbstraction) IndexEntryUpdate(org.neo4j.storageengine.api.IndexEntryUpdate) IndexAccessor(org.neo4j.kernel.api.index.IndexAccessor) CursorContext(org.neo4j.io.pagecache.context.CursorContext) IndexDescriptor(org.neo4j.internal.schema.IndexDescriptor) IndexPopulator(org.neo4j.kernel.api.index.IndexPopulator) TokenNameLookup(org.neo4j.common.TokenNameLookup) IndexSample(org.neo4j.kernel.api.index.IndexSample) InternalTransaction(org.neo4j.kernel.impl.coreapi.InternalTransaction) Transaction(org.neo4j.graphdb.Transaction) KernelTransaction(org.neo4j.kernel.api.KernelTransaction) Test(org.junit.jupiter.api.Test)

Example 17 with IndexEntryUpdate

use of org.neo4j.storageengine.api.IndexEntryUpdate in project neo4j by neo4j.

the class BlockBasedIndexPopulatorTest method shouldBuildNonUniqueSampleAsPartOfScanCompleted.

@Test
void shouldBuildNonUniqueSampleAsPartOfScanCompleted() throws IndexEntryConflictException, IOException {
    // given
    ThreadSafePeakMemoryTracker memoryTracker = new ThreadSafePeakMemoryTracker();
    ByteBufferFactory bufferFactory = new ByteBufferFactory(UnsafeDirectByteBufferAllocator::new, 100);
    BlockBasedIndexPopulator<GenericKey, NativeIndexValue> populator = instantiatePopulator(NO_MONITOR, bufferFactory, memoryTracker);
    Collection<IndexEntryUpdate<?>> populationUpdates = batchOfUpdates();
    populator.add(populationUpdates, NULL);
    // when
    populator.scanCompleted(nullInstance, populationWorkScheduler, NULL);
    // Also a couple of updates afterwards
    int numberOfUpdatesAfterCompleted = 4;
    try (IndexUpdater updater = populator.newPopulatingUpdater(NULL)) {
        for (int i = 0; i < numberOfUpdatesAfterCompleted; i++) {
            updater.process(IndexEntryUpdate.add(10_000 + i, SCHEMA_DESCRIPTOR, intValue(i)));
        }
    }
    populator.close(true, NULL);
    // then
    IndexSample sample = populator.sample(NULL);
    assertEquals(populationUpdates.size(), sample.indexSize());
    assertEquals(populationUpdates.size(), sample.sampleSize());
    assertEquals(populationUpdates.size(), sample.uniqueValues());
    assertEquals(numberOfUpdatesAfterCompleted, sample.updates());
}
Also used : IndexEntryUpdate(org.neo4j.storageengine.api.IndexEntryUpdate) IndexSample(org.neo4j.kernel.api.index.IndexSample) ThreadSafePeakMemoryTracker(org.neo4j.memory.ThreadSafePeakMemoryTracker) IndexUpdater(org.neo4j.kernel.api.index.IndexUpdater) ByteBufferFactory(org.neo4j.io.memory.ByteBufferFactory) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 18 with IndexEntryUpdate

use of org.neo4j.storageengine.api.IndexEntryUpdate in project neo4j by neo4j.

the class BlockBasedIndexPopulatorTest method shouldDeallocateAllAllocatedMemoryOnDrop.

@Test
void shouldDeallocateAllAllocatedMemoryOnDrop() throws IndexEntryConflictException, IOException {
    // given
    ThreadSafePeakMemoryTracker memoryTracker = new ThreadSafePeakMemoryTracker();
    ByteBufferFactory bufferFactory = new ByteBufferFactory(UnsafeDirectByteBufferAllocator::new, 100);
    BlockBasedIndexPopulator<GenericKey, NativeIndexValue> populator = instantiatePopulator(NO_MONITOR, bufferFactory, memoryTracker);
    boolean closed = false;
    try {
        // when
        Collection<IndexEntryUpdate<?>> updates = batchOfUpdates();
        populator.add(updates, NULL);
        int nextId = updates.size();
        externalUpdates(populator, nextId, nextId + 10);
        nextId = nextId + 10;
        long memoryBeforeScanCompleted = memoryTracker.usedNativeMemory();
        populator.scanCompleted(nullInstance, populationWorkScheduler, NULL);
        externalUpdates(populator, nextId, nextId + 10);
        // then
        assertTrue(memoryTracker.peakMemoryUsage() > memoryBeforeScanCompleted, "expected some memory to have been temporarily allocated in scanCompleted");
        populator.drop();
        closed = true;
        bufferFactory.close();
        assertEquals(0, memoryTracker.usedNativeMemory());
    } finally {
        if (!closed) {
            populator.close(true, NULL);
        }
    }
}
Also used : IndexEntryUpdate(org.neo4j.storageengine.api.IndexEntryUpdate) ThreadSafePeakMemoryTracker(org.neo4j.memory.ThreadSafePeakMemoryTracker) ByteBufferFactory(org.neo4j.io.memory.ByteBufferFactory) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 19 with IndexEntryUpdate

use of org.neo4j.storageengine.api.IndexEntryUpdate in project neo4j by neo4j.

the class GenericAccessorPointsTest method mustHandlePointArraysWithinSameTile.

/**
 * This test verify that we correctly handle unique point arrays where every point in every array belong to the same tile on the space filling curve.
 * We verify this by asserting that we always get exactly one hit on an exact match and that the value is what we expect.
 */
@Test
void mustHandlePointArraysWithinSameTile() throws IndexEntryConflictException, IndexNotApplicableKernelException {
    // given
    // Many random points that all are close enough to each other to belong to the same tile on the space filling curve.
    int nbrOfValues = 10000;
    PointValue origin = Values.pointValue(WGS84, 0.0, 0.0);
    Long derivedValueForCenterPoint = curve.derivedValueFor(origin.coordinate());
    double[] centerPoint = curve.centerPointFor(derivedValueForCenterPoint);
    double xWidthMultiplier = curve.getTileWidth(0, curve.getMaxLevel()) / 2;
    double yWidthMultiplier = curve.getTileWidth(1, curve.getMaxLevel()) / 2;
    List<Value> pointArrays = new ArrayList<>();
    List<IndexEntryUpdate<?>> updates = new ArrayList<>();
    for (int i = 0; i < nbrOfValues; i++) {
        int arrayLength = random.nextInt(5) + 1;
        PointValue[] pointValues = new PointValue[arrayLength];
        for (int j = 0; j < arrayLength; j++) {
            double x = (random.nextDouble() * 2 - 1) * xWidthMultiplier;
            double y = (random.nextDouble() * 2 - 1) * yWidthMultiplier;
            PointValue value = Values.pointValue(WGS84, centerPoint[0] + x, centerPoint[1] + y);
            assertDerivedValue(derivedValueForCenterPoint, value);
            pointValues[j] = value;
        }
        PointArray array = Values.pointArray(pointValues);
        pointArrays.add(array);
        updates.add(IndexEntryUpdate.add(i, descriptor, array));
    }
    processAll(updates);
    // then
    exactMatchOnAllValues(pointArrays);
}
Also used : IndexEntryUpdate(org.neo4j.storageengine.api.IndexEntryUpdate) PointValue(org.neo4j.values.storable.PointValue) Value(org.neo4j.values.storable.Value) PointValue(org.neo4j.values.storable.PointValue) ArrayList(java.util.ArrayList) PointArray(org.neo4j.values.storable.PointArray) Test(org.junit.jupiter.api.Test)

Example 20 with IndexEntryUpdate

use of org.neo4j.storageengine.api.IndexEntryUpdate in project neo4j by neo4j.

the class GenericAccessorPointsTest method mustHandlePointsWithinSameTile.

/**
 * This test verify that we correctly handle unique points that all belong to the same tile on the space filling curve.
 * All points share at least one dimension coordinate with another point to exercise minimal splitter.
 * We verify this by asserting that we always get exactly one hit on an exact match and that the value is what we expect.
 */
@Test
void mustHandlePointsWithinSameTile() throws IndexEntryConflictException, IndexNotApplicableKernelException {
    // given
    // Many random points that all are close enough to each other to belong to the same tile on the space filling curve.
    int nbrOfValues = 10000;
    PointValue origin = Values.pointValue(WGS84, 0.0, 0.0);
    Long derivedValueForCenterPoint = curve.derivedValueFor(origin.coordinate());
    double[] centerPoint = curve.centerPointFor(derivedValueForCenterPoint);
    double xWidthMultiplier = curve.getTileWidth(0, curve.getMaxLevel()) / 2;
    double yWidthMultiplier = curve.getTileWidth(1, curve.getMaxLevel()) / 2;
    List<Value> pointValues = new ArrayList<>();
    List<IndexEntryUpdate<?>> updates = new ArrayList<>();
    long nodeId = 1;
    for (int i = 0; i < nbrOfValues / 4; i++) {
        double x1 = (random.nextDouble() * 2 - 1) * xWidthMultiplier;
        double x2 = (random.nextDouble() * 2 - 1) * xWidthMultiplier;
        double y1 = (random.nextDouble() * 2 - 1) * yWidthMultiplier;
        double y2 = (random.nextDouble() * 2 - 1) * yWidthMultiplier;
        PointValue value11 = Values.pointValue(WGS84, centerPoint[0] + x1, centerPoint[1] + y1);
        PointValue value12 = Values.pointValue(WGS84, centerPoint[0] + x1, centerPoint[1] + y2);
        PointValue value21 = Values.pointValue(WGS84, centerPoint[0] + x2, centerPoint[1] + y1);
        PointValue value22 = Values.pointValue(WGS84, centerPoint[0] + x2, centerPoint[1] + y2);
        assertDerivedValue(derivedValueForCenterPoint, value11, value12, value21, value22);
        nodeId = addPointsToLists(pointValues, updates, nodeId, value11, value12, value21, value22);
    }
    processAll(updates);
    // then
    exactMatchOnAllValues(pointValues);
}
Also used : IndexEntryUpdate(org.neo4j.storageengine.api.IndexEntryUpdate) PointValue(org.neo4j.values.storable.PointValue) Value(org.neo4j.values.storable.Value) PointValue(org.neo4j.values.storable.PointValue) ArrayList(java.util.ArrayList) Test(org.junit.jupiter.api.Test)

Aggregations

IndexEntryUpdate (org.neo4j.storageengine.api.IndexEntryUpdate)24 Test (org.junit.jupiter.api.Test)18 IndexDescriptor (org.neo4j.internal.schema.IndexDescriptor)6 IndexSample (org.neo4j.kernel.api.index.IndexSample)6 IndexUpdater (org.neo4j.kernel.api.index.IndexUpdater)6 Value (org.neo4j.values.storable.Value)6 ArrayList (java.util.ArrayList)5 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)4 IndexPopulator (org.neo4j.kernel.api.index.IndexPopulator)4 ByteBufferFactory (org.neo4j.io.memory.ByteBufferFactory)3 ThreadSafePeakMemoryTracker (org.neo4j.memory.ThreadSafePeakMemoryTracker)3 ValueIndexEntryUpdate (org.neo4j.storageengine.api.ValueIndexEntryUpdate)3 PointValue (org.neo4j.values.storable.PointValue)3 IOException (java.io.IOException)2 HashSet (java.util.HashSet)2 ExecutorService (java.util.concurrent.ExecutorService)2 TokenNameLookup (org.neo4j.common.TokenNameLookup)2 Transaction (org.neo4j.graphdb.Transaction)2 LabelSchemaDescriptor (org.neo4j.internal.schema.LabelSchemaDescriptor)2 KernelTransaction (org.neo4j.kernel.api.KernelTransaction)2