Search in sources :

Example 31 with IndexDescriptor

use of org.neo4j.internal.schema.IndexDescriptor in project neo4j by neo4j.

the class IndexConfigMigrationIT method getIndexConfig.

@SuppressWarnings("SameParameterValue")
private static Map<String, Value> getIndexConfig(GraphDatabaseAPI db, Transaction tx, Label label) throws IndexNotFoundKernelException {
    IndexDefinitionImpl indexDefinition = (IndexDefinitionImpl) single(tx.schema().getIndexes(label));
    IndexDescriptor index = indexDefinition.getIndexReference();
    IndexingService indexingService = getIndexingService(db);
    IndexProxy indexProxy = indexingService.getIndexProxy(index);
    return indexProxy.indexConfig();
}
Also used : IndexingService(org.neo4j.kernel.impl.api.index.IndexingService) IndexProxy(org.neo4j.kernel.impl.api.index.IndexProxy) IndexDescriptor(org.neo4j.internal.schema.IndexDescriptor) IndexDefinitionImpl(org.neo4j.kernel.impl.coreapi.schema.IndexDefinitionImpl)

Example 32 with IndexDescriptor

use of org.neo4j.internal.schema.IndexDescriptor in project neo4j by neo4j.

the class NonUniqueIndexTest method concurrentIndexPopulationAndInsertsShouldNotProduceDuplicates.

@Test
void concurrentIndexPopulationAndInsertsShouldNotProduceDuplicates() throws Exception {
    // Given
    GraphDatabaseService db = newEmbeddedGraphDatabaseWithSlowJobScheduler();
    try {
        // When
        try (Transaction tx = db.beginTx()) {
            tx.schema().indexFor(label(LABEL)).on(KEY).withName(INDEX_NAME).create();
            tx.commit();
        }
        Node node;
        try (Transaction tx = db.beginTx()) {
            node = tx.createNode(label(LABEL));
            node.setProperty(KEY, VALUE);
            tx.commit();
        }
        try (Transaction tx = db.beginTx()) {
            tx.schema().awaitIndexesOnline(2, MINUTES);
            tx.commit();
        }
        // Then
        try (Transaction tx = db.beginTx()) {
            KernelTransaction ktx = ((InternalTransaction) tx).kernelTransaction();
            IndexDescriptor index = ktx.schemaRead().indexGetForName(INDEX_NAME);
            IndexReadSession indexSession = ktx.dataRead().indexReadSession(index);
            try (NodeValueIndexCursor cursor = ktx.cursors().allocateNodeValueIndexCursor(ktx.cursorContext(), ktx.memoryTracker())) {
                ktx.dataRead().nodeIndexSeek(indexSession, cursor, unconstrained(), PropertyIndexQuery.exact(1, VALUE));
                assertTrue(cursor.next());
                assertEquals(node.getId(), cursor.nodeReference());
                assertFalse(cursor.next());
            }
            tx.commit();
        }
    } finally {
        managementService.shutdown();
    }
}
Also used : GraphDatabaseService(org.neo4j.graphdb.GraphDatabaseService) KernelTransaction(org.neo4j.kernel.api.KernelTransaction) InternalTransaction(org.neo4j.kernel.impl.coreapi.InternalTransaction) Transaction(org.neo4j.graphdb.Transaction) KernelTransaction(org.neo4j.kernel.api.KernelTransaction) NodeValueIndexCursor(org.neo4j.internal.kernel.api.NodeValueIndexCursor) Node(org.neo4j.graphdb.Node) InternalTransaction(org.neo4j.kernel.impl.coreapi.InternalTransaction) IndexDescriptor(org.neo4j.internal.schema.IndexDescriptor) IndexReadSession(org.neo4j.internal.kernel.api.IndexReadSession) Test(org.junit.jupiter.api.Test)

Example 33 with IndexDescriptor

use of org.neo4j.internal.schema.IndexDescriptor in project neo4j by neo4j.

the class AbstractIndexQueryingTest method relationshipIndexSeekMustThrowOnWrongIndexEntityType.

@Test
void relationshipIndexSeekMustThrowOnWrongIndexEntityType() throws IndexNotFoundKernelException {
    IndexDescriptor index = schemaRead.indexGetForName("ftsNodes");
    IndexReadSession indexReadSession = read.indexReadSession(index);
    try (RelationshipValueIndexCursor cursor = cursors.allocateRelationshipValueIndexCursor(NULL, EmptyMemoryTracker.INSTANCE)) {
        assertThrows(IndexNotApplicableKernelException.class, () -> read.relationshipIndexSeek(indexReadSession, cursor, unconstrained(), PropertyIndexQuery.fulltextSearch("search")));
    }
}
Also used : RelationshipValueIndexCursor(org.neo4j.internal.kernel.api.RelationshipValueIndexCursor) IndexDescriptor(org.neo4j.internal.schema.IndexDescriptor) IndexReadSession(org.neo4j.internal.kernel.api.IndexReadSession) Test(org.junit.jupiter.api.Test)

Example 34 with IndexDescriptor

use of org.neo4j.internal.schema.IndexDescriptor in project neo4j by neo4j.

the class SchemaComplianceChecker method checkCorrectlyIndexed.

<ENTITY extends PrimitiveRecord> void checkCorrectlyIndexed(ENTITY entity, long[] entityTokens, IntObjectMap<Value> values, Function<ENTITY, ConsistencyReport.PrimitiveConsistencyReport> reportSupplier) {
    for (IndexDescriptor indexRule : indexes) {
        SchemaDescriptor schema = indexRule.schema();
        Value[] valueArray = RecordLoading.entityIntersectionWithSchema(entityTokens, values, schema);
        if (valueArray == null) {
            continue;
        }
        var reader = indexReaders.reader(indexRule);
        if (indexRule.isUnique()) {
            verifyIndexedUniquely(entity, valueArray, indexRule, reader, reportSupplier);
        } else {
            long count = reader.countIndexedEntities(entity.getId(), cursorContext, schema.getPropertyIds(), valueArray);
            reportIncorrectIndexCount(entity, valueArray, indexRule, count, reportSupplier);
        }
    }
}
Also used : SchemaDescriptor(org.neo4j.internal.schema.SchemaDescriptor) Value(org.neo4j.values.storable.Value) IndexDescriptor(org.neo4j.internal.schema.IndexDescriptor)

Example 35 with IndexDescriptor

use of org.neo4j.internal.schema.IndexDescriptor in project neo4j by neo4j.

the class IndexChecker method checkVsEntities.

private void checkVsEntities(List<IndexContext> indexes, long fromEntityId, long toEntityId) {
    // This is one thread
    CheckerContext noReportingContext = context.withoutReporting();
    try (var cursorContext = new CursorContext(context.pageCacheTracer.createPageCursorTracer(CONSISTENCY_INDEX_ENTITY_CHECK_TAG));
        RecordReader<NodeRecord> nodeReader = new RecordReader<>(context.neoStores.getNodeStore(), true, cursorContext);
        RecordReader<DynamicRecord> labelReader = new RecordReader<>(context.neoStores.getNodeStore().getDynamicLabelStore(), false, cursorContext);
        SafePropertyChainReader propertyReader = new SafePropertyChainReader(noReportingContext, cursorContext)) {
        ProgressListener localScanProgress = scanProgress.threadLocalReporter();
        IntObjectHashMap<Value> allValues = new IntObjectHashMap<>();
        var client = cacheAccess.client();
        int numberOfIndexes = indexes.size();
        for (long entityId = fromEntityId; entityId < toEntityId && !context.isCancelled(); entityId++) {
            NodeRecord nodeRecord = nodeReader.read(entityId);
            if (nodeRecord.inUse()) {
                long[] entityTokens = safeGetNodeLabels(noReportingContext, nodeRecord.getId(), nodeRecord.getLabelField(), labelReader, cursorContext);
                lightClear(allValues);
                boolean propertyChainRead = entityTokens != null && propertyReader.read(allValues, nodeRecord, noReportingContext.reporter::forNode, cursorContext);
                if (propertyChainRead) {
                    for (int i = 0; i < numberOfIndexes; i++) {
                        IndexContext index = indexes.get(i);
                        IndexDescriptor descriptor = index.descriptor;
                        long cachedValue = client.getFromCache(entityId, i);
                        boolean nodeIsInIndex = (cachedValue & IN_USE_MASK) != 0;
                        Value[] values = RecordLoading.entityIntersectionWithSchema(entityTokens, allValues, descriptor.schema());
                        if (index.descriptor.schema().isFulltextSchemaDescriptor()) {
                            // The strategy for fulltext indexes is way simpler. Simply check of the sets of tokens (label tokens and property key tokens)
                            // and if they match the index schema descriptor then the node should be in the index, otherwise not
                            int[] nodePropertyKeys = allValues.keySet().toArray();
                            int[] indexPropertyKeys = index.descriptor.schema().getPropertyIds();
                            boolean nodeShouldBeInIndex = index.descriptor.schema().isAffected(entityTokens) && containsAny(indexPropertyKeys, nodePropertyKeys) && valuesContainTextProperty(values);
                            if (nodeShouldBeInIndex && !nodeIsInIndex) {
                                getReporter(context.recordLoader.node(entityId, cursorContext)).notIndexed(descriptor, new Object[0]);
                            } else if (!nodeShouldBeInIndex && nodeIsInIndex) {
                                // Fulltext indexes created before 4.3.0-drop02 can contain empty documents (added when the schema matched but the values
                                // were not text). The index still works with those empty documents present, so we don't want to report them as
                                // inconsistencies and force rebuilds.
                                // This utilizes the fact that countIndexedEntities in FulltextIndexReader with non-text values will ask
                                // about documents that doesn't contain those property keys - a document found by that query should be an empty
                                // document we just want to ignore.
                                Value[] noValues = new Value[indexPropertyKeys.length];
                                Arrays.fill(noValues, NO_VALUE);
                                long docsWithNoneOfProperties = indexAccessors.readers().reader(descriptor).countIndexedEntities(entityId, cursorContext, indexPropertyKeys, noValues);
                                if (docsWithNoneOfProperties != 1) {
                                    getReporter(context.recordLoader.node(entityId, cursorContext)).notIndexed(descriptor, new Object[0]);
                                }
                            }
                        } else {
                            if (values != null) {
                                // This node should really be in the index, is it?
                                if (!nodeIsInIndex) {
                                    // It wasn't, report it
                                    getReporter(context.recordLoader.node(entityId, cursorContext)).notIndexed(descriptor, Values.asObjects(values));
                                } else if (index.hasValues) {
                                    int cachedChecksum = (int) cachedValue & CHECKSUM_MASK;
                                    int actualChecksum = checksum(values);
                                    if (cachedChecksum != actualChecksum) {
                                        getReporter(context.recordLoader.node(entityId, cursorContext)).notIndexed(descriptor, Values.asObjects(values));
                                    }
                                }
                            } else {
                                if (nodeIsInIndex) {
                                    reporter.forIndexEntry(new IndexEntry(descriptor, context.tokenNameLookup, entityId)).nodeNotInUse(context.recordLoader.node(entityId, cursorContext));
                                }
                            }
                        }
                    }
                }
            // else this would be reported elsewhere
            } else {
                // This node shouldn't be in any index
                for (int i = 0; i < numberOfIndexes; i++) {
                    boolean isInIndex = (client.getFromCache(entityId, i) & IN_USE_MASK) != 0;
                    if (isInIndex) {
                        reporter.forIndexEntry(new IndexEntry(indexes.get(i).descriptor, context.tokenNameLookup, entityId)).nodeNotInUse(context.recordLoader.node(entityId, cursorContext));
                    }
                }
            }
            localScanProgress.add(1);
        }
        localScanProgress.done();
    }
}
Also used : DynamicRecord(org.neo4j.kernel.impl.store.record.DynamicRecord) IntObjectHashMap(org.eclipse.collections.impl.map.mutable.primitive.IntObjectHashMap) IndexEntry(org.neo4j.consistency.store.synthetic.IndexEntry) CursorContext(org.neo4j.io.pagecache.context.CursorContext) IndexDescriptor(org.neo4j.internal.schema.IndexDescriptor) NodeRecord(org.neo4j.kernel.impl.store.record.NodeRecord) ProgressListener(org.neo4j.internal.helpers.progress.ProgressListener) Value(org.neo4j.values.storable.Value)

Aggregations

IndexDescriptor (org.neo4j.internal.schema.IndexDescriptor)404 Test (org.junit.jupiter.api.Test)231 KernelTransaction (org.neo4j.kernel.api.KernelTransaction)81 Value (org.neo4j.values.storable.Value)43 ConstraintDescriptor (org.neo4j.internal.schema.ConstraintDescriptor)33 ArrayList (java.util.ArrayList)31 Transaction (org.neo4j.graphdb.Transaction)31 SchemaDescriptor (org.neo4j.internal.schema.SchemaDescriptor)31 IndexPrototype (org.neo4j.internal.schema.IndexPrototype)30 InternalTransaction (org.neo4j.kernel.impl.coreapi.InternalTransaction)30 TokenRead (org.neo4j.internal.kernel.api.TokenRead)29 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)26 SchemaRead (org.neo4j.internal.kernel.api.SchemaRead)26 IndexUpdater (org.neo4j.kernel.api.index.IndexUpdater)25 IndexProxy (org.neo4j.kernel.impl.api.index.IndexProxy)25 IndexReadSession (org.neo4j.internal.kernel.api.IndexReadSession)23 IndexNotFoundKernelException (org.neo4j.internal.kernel.api.exceptions.schema.IndexNotFoundKernelException)23 LabelSchemaDescriptor (org.neo4j.internal.schema.LabelSchemaDescriptor)23 IndexProviderDescriptor (org.neo4j.internal.schema.IndexProviderDescriptor)22 KernelException (org.neo4j.exceptions.KernelException)20