Search in sources :

Example 1 with DynamicNodeLabels

use of org.neo4j.kernel.impl.store.DynamicNodeLabels in project neo4j by neo4j.

the class NodeInUseWithCorrectLabelsCheck method checkReference.

@Override
public void checkReference(RECORD record, NodeRecord nodeRecord, CheckerEngine<RECORD, REPORT> engine, RecordAccess records) {
    if (nodeRecord.inUse()) {
        NodeLabels nodeLabels = NodeLabelsField.parseLabelsField(nodeRecord);
        if (nodeLabels instanceof DynamicNodeLabels) {
            DynamicNodeLabels dynamicNodeLabels = (DynamicNodeLabels) nodeLabels;
            long firstRecordId = dynamicNodeLabels.getFirstDynamicRecordId();
            RecordReference<DynamicRecord> firstRecordReference = records.nodeLabels(firstRecordId);
            ExpectedNodeLabelsChecker expectedNodeLabelsChecker = new ExpectedNodeLabelsChecker(nodeRecord);
            LabelChainWalker<RECORD, REPORT> checker = new LabelChainWalker<>(expectedNodeLabelsChecker);
            engine.comparativeCheck(firstRecordReference, checker);
            // I think this is empty in production
            nodeRecord.getDynamicLabelRecords();
        } else {
            long[] storeLabels = nodeLabels.get(null);
            REPORT report = engine.report();
            validateLabelIds(nodeRecord, storeLabels, report);
        }
    } else {
        engine.report().nodeNotInUse(nodeRecord);
    }
}
Also used : DynamicRecord(org.neo4j.kernel.impl.store.record.DynamicRecord) LabelChainWalker(org.neo4j.consistency.checking.LabelChainWalker) DynamicNodeLabels(org.neo4j.kernel.impl.store.DynamicNodeLabels) DynamicNodeLabels(org.neo4j.kernel.impl.store.DynamicNodeLabels) NodeLabels(org.neo4j.kernel.impl.store.NodeLabels)

Example 2 with DynamicNodeLabels

use of org.neo4j.kernel.impl.store.DynamicNodeLabels in project neo4j by neo4j.

the class NodeLabelReader method getListOfLabels.

public static <RECORD extends AbstractBaseRecord, REPORT extends ConsistencyReport> Set<Long> getListOfLabels(NodeRecord nodeRecord, RecordAccess records, CheckerEngine<RECORD, REPORT> engine) {
    final Set<Long> labels = new HashSet<>();
    NodeLabels nodeLabels = NodeLabelsField.parseLabelsField(nodeRecord);
    if (nodeLabels instanceof DynamicNodeLabels) {
        DynamicNodeLabels dynamicNodeLabels = (DynamicNodeLabels) nodeLabels;
        long firstRecordId = dynamicNodeLabels.getFirstDynamicRecordId();
        RecordReference<DynamicRecord> firstRecordReference = records.nodeLabels(firstRecordId);
        engine.comparativeCheck(firstRecordReference, new LabelChainWalker<>(new LabelChainWalker.Validator<RECORD, REPORT>() {

            @Override
            public void onRecordNotInUse(DynamicRecord dynamicRecord, CheckerEngine<RECORD, REPORT> engine) {
            }

            @Override
            public void onRecordChainCycle(DynamicRecord record, CheckerEngine<RECORD, REPORT> engine) {
            }

            @Override
            public void onWellFormedChain(long[] labelIds, CheckerEngine<RECORD, REPORT> engine, RecordAccess records) {
                copyToSet(labelIds, labels);
            }
        }));
    } else {
        copyToSet(nodeLabels.get(null), labels);
    }
    return labels;
}
Also used : DynamicRecord(org.neo4j.kernel.impl.store.record.DynamicRecord) RecordAccess(org.neo4j.consistency.store.RecordAccess) DynamicNodeLabels(org.neo4j.kernel.impl.store.DynamicNodeLabels) CheckerEngine(org.neo4j.consistency.checking.CheckerEngine) DynamicNodeLabels(org.neo4j.kernel.impl.store.DynamicNodeLabels) InlineNodeLabels(org.neo4j.kernel.impl.store.InlineNodeLabels) NodeLabels(org.neo4j.kernel.impl.store.NodeLabels) HashSet(java.util.HashSet)

Example 3 with DynamicNodeLabels

use of org.neo4j.kernel.impl.store.DynamicNodeLabels in project neo4j by neo4j.

the class NodeLabelsFieldTest method shouldHandleRandomAddsAndRemoves.

/*
     * There was this issue that DynamicNodeLabels#add would consider even unused dynamic records when
     * reading existing label ids before making the change. Previously this would create a duplicate
     * last label id (the one formerly being in the second record).
     *
     * This randomized test found this issue every time when it existed and it will potentially find other
     * unforeseen issues as well.
     */
@Test
public void shouldHandleRandomAddsAndRemoves() throws Exception {
    // GIVEN
    Set<Integer> key = new HashSet<>();
    NodeRecord node = new NodeRecord(0);
    node.setInUse(true);
    // WHEN
    for (int i = 0; i < 100_000; i++) {
        NodeLabels labels = NodeLabelsField.parseLabelsField(node);
        int labelId = random.nextInt(200);
        if (random.nextBoolean()) {
            if (!key.contains(labelId)) {
                labels.add(labelId, nodeStore, nodeStore.getDynamicLabelStore());
                key.add(labelId);
            }
        } else {
            if (key.remove(labelId)) {
                labels.remove(labelId, nodeStore);
            }
        }
    }
    // THEN
    NodeLabels labels = NodeLabelsField.parseLabelsField(node);
    long[] readLabelIds = labels.get(nodeStore);
    for (long labelId : readLabelIds) {
        assertTrue("Found an unexpected label " + labelId, key.remove((int) labelId));
    }
    assertTrue(key.isEmpty());
}
Also used : NodeRecord(org.neo4j.kernel.impl.store.record.NodeRecord) NodeLabels(org.neo4j.kernel.impl.store.NodeLabels) DynamicNodeLabels(org.neo4j.kernel.impl.store.DynamicNodeLabels) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 4 with DynamicNodeLabels

use of org.neo4j.kernel.impl.store.DynamicNodeLabels in project neo4j by neo4j.

the class NodeLabelsFieldTest method shouldHandleRandomAddsAndRemoves.

/*
     * There was this issue that DynamicNodeLabels#add would consider even unused dynamic records when
     * reading existing label ids before making the change. Previously this would create a duplicate
     * last label id (the one formerly being in the second record).
     *
     * This randomized test found this issue every time when it existed and it will potentially find other
     * unforeseen issues as well.
     */
@Test
void shouldHandleRandomAddsAndRemoves() {
    // GIVEN
    Set<Integer> key = new HashSet<>();
    NodeRecord node = new NodeRecord(0);
    node.setInUse(true);
    // WHEN
    for (int i = 0; i < 100_000; i++) {
        NodeLabels labels = NodeLabelsField.parseLabelsField(node);
        int labelId = random.nextInt(200);
        if (random.nextBoolean()) {
            if (!key.contains(labelId)) {
                labels.add(labelId, nodeStore, nodeStore.getDynamicLabelStore(), NULL, INSTANCE);
                key.add(labelId);
            }
        } else {
            if (key.remove(labelId)) {
                labels.remove(labelId, nodeStore, NULL, INSTANCE);
            }
        }
    }
    // THEN
    NodeLabels labels = NodeLabelsField.parseLabelsField(node);
    long[] readLabelIds = labels.get(nodeStore, NULL);
    for (long labelId : readLabelIds) {
        assertTrue(key.remove((int) labelId), "Found an unexpected label " + labelId);
    }
    assertTrue(key.isEmpty());
}
Also used : NodeRecord(org.neo4j.kernel.impl.store.record.NodeRecord) DynamicNodeLabels(org.neo4j.kernel.impl.store.DynamicNodeLabels) NodeLabels(org.neo4j.kernel.impl.store.NodeLabels) HashSet(java.util.HashSet) Test(org.junit.jupiter.api.Test)

Aggregations

DynamicNodeLabels (org.neo4j.kernel.impl.store.DynamicNodeLabels)4 NodeLabels (org.neo4j.kernel.impl.store.NodeLabels)4 HashSet (java.util.HashSet)3 DynamicRecord (org.neo4j.kernel.impl.store.record.DynamicRecord)2 NodeRecord (org.neo4j.kernel.impl.store.record.NodeRecord)2 Test (org.junit.Test)1 Test (org.junit.jupiter.api.Test)1 CheckerEngine (org.neo4j.consistency.checking.CheckerEngine)1 LabelChainWalker (org.neo4j.consistency.checking.LabelChainWalker)1 RecordAccess (org.neo4j.consistency.store.RecordAccess)1 InlineNodeLabels (org.neo4j.kernel.impl.store.InlineNodeLabels)1