Search in sources :

Example 6 with NodeValueIterator

use of org.neo4j.kernel.impl.index.schema.NodeValueIterator in project neo4j by neo4j.

the class DatabaseIndexAccessorTest method results.

private static NodeValueIterator results(ValueIndexReader reader, PropertyIndexQuery... queries) throws IndexNotApplicableKernelException {
    NodeValueIterator results = new NodeValueIterator();
    reader.query(NULL_CONTEXT, results, unconstrained(), queries);
    return results;
}
Also used : NodeValueIterator(org.neo4j.kernel.impl.index.schema.NodeValueIterator)

Example 7 with NodeValueIterator

use of org.neo4j.kernel.impl.index.schema.NodeValueIterator in project neo4j by neo4j.

the class LuceneSchemaIndexPopulationIT method partitionedIndexPopulation.

@ParameterizedTest
@ValueSource(ints = { 7, 11, 14, 20, 35, 58 })
void partitionedIndexPopulation(int affectedNodes) throws Exception {
    Path rootFolder = testDir.directory("partitionIndex" + affectedNodes).resolve("uniqueIndex" + affectedNodes);
    try (SchemaIndex uniqueIndex = LuceneSchemaIndexBuilder.create(descriptor, writable(), Config.defaults()).withFileSystem(fileSystem).withIndexRootFolder(rootFolder).build()) {
        uniqueIndex.open();
        // index is empty and not yet exist
        assertEquals(0, uniqueIndex.allDocumentsReader().maxCount());
        assertFalse(uniqueIndex.exists());
        try (LuceneIndexAccessor indexAccessor = new LuceneIndexAccessor(uniqueIndex, descriptor, SIMPLE_TOKEN_LOOKUP)) {
            generateUpdates(indexAccessor, affectedNodes);
            indexAccessor.force(NULL);
            // now index is online and should contain updates data
            assertTrue(uniqueIndex.isOnline());
            try (var indexReader = indexAccessor.newValueReader();
                NodeValueIterator results = new NodeValueIterator();
                IndexSampler indexSampler = indexReader.createSampler()) {
                indexReader.query(NULL_CONTEXT, results, unconstrained(), PropertyIndexQuery.exists(1));
                long[] nodes = PrimitiveLongCollections.asArray(results);
                assertEquals(affectedNodes, nodes.length);
                IndexSample sample = indexSampler.sampleIndex(NULL);
                assertEquals(affectedNodes, sample.indexSize());
                assertEquals(affectedNodes, sample.uniqueValues());
                assertEquals(affectedNodes, sample.sampleSize());
            }
        }
    }
}
Also used : Path(java.nio.file.Path) NodeValueIterator(org.neo4j.kernel.impl.index.schema.NodeValueIterator) LuceneIndexAccessor(org.neo4j.kernel.api.impl.schema.LuceneIndexAccessor) IndexSample(org.neo4j.kernel.api.index.IndexSample) SchemaIndex(org.neo4j.kernel.api.impl.schema.SchemaIndex) IndexSampler(org.neo4j.kernel.api.index.IndexSampler) ValueSource(org.junit.jupiter.params.provider.ValueSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 8 with NodeValueIterator

use of org.neo4j.kernel.impl.index.schema.NodeValueIterator in project neo4j by neo4j.

the class SimpleIndexPopulatorCompatibility method shouldPopulateAndUpdate.

@Test
public void shouldPopulateAndUpdate() throws Exception {
    // GIVEN
    withPopulator(indexProvider.getPopulator(descriptor, indexSamplingConfig, heapBufferFactory(1024), INSTANCE, tokenNameLookup), p -> p.add(updates(valueSet1), NULL));
    try (IndexAccessor accessor = indexProvider.getOnlineAccessor(descriptor, indexSamplingConfig, tokenNameLookup)) {
        // WHEN
        try (IndexUpdater updater = accessor.newUpdater(IndexUpdateMode.ONLINE, NULL)) {
            List<ValueIndexEntryUpdate<?>> updates = updates(valueSet2);
            for (ValueIndexEntryUpdate<?> update : updates) {
                updater.process(update);
            }
        }
        // THEN
        try (ValueIndexReader reader = accessor.newValueReader()) {
            int propertyKeyId = descriptor.schema().getPropertyId();
            for (NodeAndValue entry : Iterables.concat(valueSet1, valueSet2)) {
                try (NodeValueIterator nodes = new NodeValueIterator()) {
                    reader.query(NULL_CONTEXT, nodes, unconstrained(), PropertyIndexQuery.exact(propertyKeyId, entry.value));
                    assertEquals(entry.nodeId, nodes.next());
                    assertFalse(nodes.hasNext());
                }
            }
        }
    }
}
Also used : NodeValueIterator(org.neo4j.kernel.impl.index.schema.NodeValueIterator) ValueIndexEntryUpdate(org.neo4j.storageengine.api.ValueIndexEntryUpdate) Test(org.junit.Test)

Example 9 with NodeValueIterator

use of org.neo4j.kernel.impl.index.schema.NodeValueIterator in project neo4j by neo4j.

the class SimpleIndexPopulatorCompatibility method shouldPopulateAndRemoveEntriesWithSimilarMinimalSplitter.

/**
 * This test target a bug around minimal splitter in gbpTree and unique index populator. It goes like this:
 * Given a set of updates (value,entityId):
 * - ("A01",1), ("A90",3), ("A9",2)
 * If ("A01",1) and ("A90",3) would cause a split to occur they would produce a minimal splitter ("A9",3).
 * Note that the value in this minimal splitter is equal to our last update ("A9",2).
 * When making insertions with the unique populator we don't compare entityId which would means ("A9",2)
 * ends up to the right of ("A9",3), even though it belongs to the left because of entityId being smaller.
 * At this point the tree is in an inconsistent (key on wrong side of splitter).
 *
 * To work around this problem the entityId is only kept in minimal splitter if strictly necessary to divide
 * left from right. This means the minimal splitter between ("A01",1) and ("A90",3) is ("A9",-1) and ("A9",2)
 * will correctly be placed on the right side of this splitter.
 *
 * To trigger this scenario this test first insert a bunch of values that are all unique and that will cause a
 * split to happen. This is the firstBatch.
 * The second batch are constructed so that at least one of them will have a value equal to the splitter key
 * constructed during the firstBatch.
 * It's important that the secondBatch has ids that are lower than the first batch to align with example described above.
 */
@Test
public void shouldPopulateAndRemoveEntriesWithSimilarMinimalSplitter() throws Exception {
    String prefix = "Work out your own salvation. Do not depend on others. ";
    int nbrOfNodes = 200;
    long nodeId = 0;
    // Second batch has lower ids
    List<NodeAndValue> secondBatch = new ArrayList<>();
    for (int i = 0; i < nbrOfNodes; i++) {
        secondBatch.add(new NodeAndValue(nodeId++, stringValue(prefix + i)));
    }
    // First batch has higher ids and minimal splitter among values in first batch will be found among second batch
    List<NodeAndValue> firstBatch = new ArrayList<>();
    for (int i = 0; i < nbrOfNodes; i++) {
        firstBatch.add(new NodeAndValue(nodeId++, stringValue(prefix + i + " " + i)));
    }
    withPopulator(indexProvider.getPopulator(descriptor, indexSamplingConfig, heapBufferFactory(1024), INSTANCE, tokenNameLookup), p -> {
        p.add(updates(firstBatch), NULL);
        p.add(updates(secondBatch), NULL);
    // Index should be consistent
    });
    List<NodeAndValue> toRemove = new ArrayList<>();
    toRemove.addAll(firstBatch);
    toRemove.addAll(secondBatch);
    Collections.shuffle(toRemove);
    // And we should be able to remove the entries in any order
    try (IndexAccessor accessor = indexProvider.getOnlineAccessor(descriptor, indexSamplingConfig, tokenNameLookup)) {
        // WHEN
        try (IndexUpdater updater = accessor.newUpdater(IndexUpdateMode.ONLINE, NULL)) {
            for (NodeAndValue nodeAndValue : toRemove) {
                updater.process(IndexEntryUpdate.remove(nodeAndValue.nodeId, descriptor, nodeAndValue.value));
            }
        }
        // THEN
        try (ValueIndexReader reader = accessor.newValueReader()) {
            int propertyKeyId = descriptor.schema().getPropertyId();
            for (NodeAndValue nodeAndValue : toRemove) {
                NodeValueIterator nodes = new NodeValueIterator();
                reader.query(NULL_CONTEXT, nodes, unconstrained(), PropertyIndexQuery.exact(propertyKeyId, nodeAndValue.value));
                boolean anyHits = false;
                StringJoiner nodesStillLeft = new StringJoiner(", ", "[", "]");
                while (nodes.hasNext()) {
                    anyHits = true;
                    nodesStillLeft.add(Long.toString(nodes.next()));
                }
                assertFalse("Expected this query to have zero hits but found " + nodesStillLeft, anyHits);
            }
        }
    }
}
Also used : NodeValueIterator(org.neo4j.kernel.impl.index.schema.NodeValueIterator) ArrayList(java.util.ArrayList) StringJoiner(java.util.StringJoiner) Test(org.junit.Test)

Example 10 with NodeValueIterator

use of org.neo4j.kernel.impl.index.schema.NodeValueIterator in project neo4j by neo4j.

the class NonUniqueDatabaseIndexPopulatorTest method addUpdates.

@Test
void addUpdates() throws Exception {
    populator = newPopulator();
    List<IndexEntryUpdate<?>> updates = Arrays.asList(add(1, labelSchemaDescriptor, "foo"), add(2, labelSchemaDescriptor, "bar"), add(42, labelSchemaDescriptor, "bar"));
    populator.add(updates, NULL);
    index.maybeRefreshBlocking();
    try (ValueIndexReader reader = index.getIndexReader();
        NodeValueIterator allEntities = new NodeValueIterator()) {
        int propertyKeyId = labelSchemaDescriptor.getPropertyId();
        reader.query(NULL_CONTEXT, allEntities, unconstrained(), PropertyIndexQuery.exists(propertyKeyId));
        assertArrayEquals(new long[] { 1, 2, 42 }, PrimitiveLongCollections.asArray(allEntities));
    }
}
Also used : NodeValueIterator(org.neo4j.kernel.impl.index.schema.NodeValueIterator) IndexEntryUpdate(org.neo4j.storageengine.api.IndexEntryUpdate) ValueIndexReader(org.neo4j.kernel.api.index.ValueIndexReader) Test(org.junit.jupiter.api.Test)

Aggregations

NodeValueIterator (org.neo4j.kernel.impl.index.schema.NodeValueIterator)11 Test (org.junit.jupiter.api.Test)4 Test (org.junit.Test)3 IndexEntryUpdate (org.neo4j.storageengine.api.IndexEntryUpdate)2 Path (java.nio.file.Path)1 ArrayList (java.util.ArrayList)1 StringJoiner (java.util.StringJoiner)1 LongSet (org.eclipse.collections.api.set.primitive.LongSet)1 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)1 ValueSource (org.junit.jupiter.params.provider.ValueSource)1 PropertyIndexQuery (org.neo4j.internal.kernel.api.PropertyIndexQuery)1 IndexNotApplicableKernelException (org.neo4j.internal.kernel.api.exceptions.schema.IndexNotApplicableKernelException)1 SchemaDescriptor (org.neo4j.internal.schema.SchemaDescriptor)1 LuceneIndexAccessor (org.neo4j.kernel.api.impl.schema.LuceneIndexAccessor)1 SchemaIndex (org.neo4j.kernel.api.impl.schema.SchemaIndex)1 IndexProgressor (org.neo4j.kernel.api.index.IndexProgressor)1 IndexSample (org.neo4j.kernel.api.index.IndexSample)1 IndexSampler (org.neo4j.kernel.api.index.IndexSampler)1 ValueIndexReader (org.neo4j.kernel.api.index.ValueIndexReader)1 IndexSamplingConfig (org.neo4j.kernel.impl.api.index.IndexSamplingConfig)1