Search in sources :

Example 1 with StorageNodeCursor

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

the class OnlineIndexUpdates method gatherUpdatesFromCommandsForNode.

private EntityUpdates gatherUpdatesFromCommandsForNode(long nodeId, NodeCommand nodeChanges, EntityCommandGrouper<NodeCommand>.Cursor propertyCommandsForNode) {
    long[] nodeLabelsBefore;
    long[] nodeLabelsAfter;
    if (nodeChanges != null) {
        // Special case since the node may not be heavy, i.e. further loading may be required
        nodeLabelsBefore = parseLabelsField(nodeChanges.getBefore()).get(nodeStore, cursorContext);
        nodeLabelsAfter = parseLabelsField(nodeChanges.getAfter()).get(nodeStore, cursorContext);
    } else {
        /* If the node doesn't exist here then we've most likely encountered this scenario:
             * - TX1: Node N exists and has property record P
             * - rotate log
             * - TX2: P gets changed
             * - TX3: N gets deleted (also P, but that's irrelevant for this scenario)
             * - N is persisted to disk for some reason
             * - crash
             * - recover
             * - TX2: P has changed and updates to indexes are gathered. As part of that it tries to read
             *        the labels of N (which does not exist a.t.m.).
             *
             * We can actually (if we disregard any potential inconsistencies) just assume that
             * if this happens and we're in recovery mode that the node in question will be deleted
             * in an upcoming transaction, so just skip this update.
             */
        StorageNodeCursor nodeCursor = loadNode(nodeId);
        nodeLabelsBefore = nodeLabelsAfter = nodeCursor.labels();
    }
    // First get possible Label changes
    boolean complete = providesCompleteListOfProperties(nodeChanges);
    EntityUpdates.Builder nodePropertyUpdates = EntityUpdates.forEntity(nodeId, complete).withTokens(nodeLabelsBefore).withTokensAfter(nodeLabelsAfter);
    // Then look for property changes
    converter.convertPropertyRecord(propertyCommandsForNode, nodePropertyUpdates);
    return nodePropertyUpdates.build();
}
Also used : EntityUpdates(org.neo4j.storageengine.api.EntityUpdates) StorageNodeCursor(org.neo4j.storageengine.api.StorageNodeCursor)

Example 2 with StorageNodeCursor

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

the class RecordStorageReaderLabelTest method shouldBeAbleToListLabelsForNode.

@Test
void shouldBeAbleToListLabelsForNode() throws Exception {
    // GIVEN
    long nodeId;
    nodeId = createNode(map(), label1, label2);
    int labelId1 = labelId(label1);
    int labelId2 = labelId(label2);
    // THEN
    StorageNodeCursor nodeCursor = storageReader.allocateNodeCursor(NULL);
    nodeCursor.single(nodeId);
    assertTrue(nodeCursor.next());
    assertEquals(newSetWith(labelId1, labelId2), newSetWith(nodeCursor.labels()));
}
Also used : StorageNodeCursor(org.neo4j.storageengine.api.StorageNodeCursor) Test(org.junit.jupiter.api.Test)

Example 3 with StorageNodeCursor

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

the class RecordStorageReaderPropertyTest method shouldGetAllNodeProperties.

@Test
void shouldGetAllNodeProperties() throws Exception {
    // GIVEN
    String longString = "AlalalalalongAlalalalalongAlalalalalongAlalalalalongAlalalalalongAlalalalalongAlalalalalongAlalalalalong";
    Object[] properties = { longString, createNew(String.class), createNew(long.class), createNew(int.class), createNew(byte.class), createNew(short.class), createNew(boolean.class), createNew(char.class), createNew(float.class), createNew(double.class), array(0, String.class), array(0, long.class), array(0, int.class), array(0, byte.class), array(0, short.class), array(0, boolean.class), array(0, char.class), array(0, float.class), array(0, double.class), array(1, String.class), array(1, long.class), array(1, int.class), array(1, byte.class), array(1, short.class), array(1, boolean.class), array(1, char.class), array(1, float.class), array(1, double.class), array(256, String.class), array(256, long.class), array(256, int.class), array(256, byte.class), array(256, short.class), array(256, boolean.class), array(256, char.class), array(256, float.class), array(256, double.class) };
    for (Object value : properties) {
        // given
        long nodeId = createNode(singletonMap("prop", value), label1);
        // when
        try (StorageNodeCursor node = storageReader.allocateNodeCursor(NULL)) {
            node.single(nodeId);
            assertTrue(node.next());
            try (StoragePropertyCursor props = storageReader.allocatePropertyCursor(NULL, INSTANCE)) {
                node.properties(props);
                if (props.next()) {
                    Value propVal = props.propertyValue();
                    // then
                    assertTrue(propVal.equals(Values.of(value)), propVal + ".equals(" + value + ")");
                } else {
                    fail();
                }
            }
        }
    }
}
Also used : StoragePropertyCursor(org.neo4j.storageengine.api.StoragePropertyCursor) Value(org.neo4j.values.storable.Value) StorageNodeCursor(org.neo4j.storageengine.api.StorageNodeCursor) Test(org.junit.jupiter.api.Test)

Example 4 with StorageNodeCursor

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

the class RecordStorageReaderRelTypesAndDegreeTest method testDegreeByDirectionAndTypeForDenseNodeWithPartiallyDeletedRelGroupChain.

protected void testDegreeByDirectionAndTypeForDenseNodeWithPartiallyDeletedRelGroupChain(TestRelType... typesToDelete) throws Exception {
    int inRelCount = randomRelCount();
    int outRelCount = randomRelCount();
    int loopRelCount = randomRelCount();
    long nodeId = createNode(inRelCount, outRelCount, loopRelCount);
    StorageNodeCursor cursor = newCursor(nodeId);
    for (TestRelType type : typesToDelete) {
        markRelGroupNotInUse(nodeId, type);
        switch(type) {
            case IN:
                inRelCount = 0;
                break;
            case OUT:
                outRelCount = 0;
                break;
            case LOOP:
                loopRelCount = 0;
                break;
            default:
                throw new IllegalArgumentException("Unknown type: " + type);
        }
    }
    assertEquals(0, degreeForDirectionAndType(cursor, OUTGOING, relTypeId(IN)));
    assertEquals(outRelCount, degreeForDirectionAndType(cursor, OUTGOING, relTypeId(OUT)));
    assertEquals(loopRelCount, degreeForDirectionAndType(cursor, OUTGOING, relTypeId(LOOP)));
    assertEquals(0, degreeForDirectionAndType(cursor, INCOMING, relTypeId(OUT)));
    assertEquals(inRelCount, degreeForDirectionAndType(cursor, INCOMING, relTypeId(IN)));
    assertEquals(loopRelCount, degreeForDirectionAndType(cursor, INCOMING, relTypeId(LOOP)));
    assertEquals(inRelCount, degreeForDirectionAndType(cursor, BOTH, relTypeId(IN)));
    assertEquals(outRelCount, degreeForDirectionAndType(cursor, BOTH, relTypeId(OUT)));
    assertEquals(loopRelCount, degreeForDirectionAndType(cursor, BOTH, relTypeId(LOOP)));
}
Also used : StorageNodeCursor(org.neo4j.storageengine.api.StorageNodeCursor)

Example 5 with StorageNodeCursor

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

the class RecordStorageReaderRelTypesAndDegreeTest method testDegreeByDirectionForDenseNodeWithPartiallyDeletedRelChains.

protected void testDegreeByDirectionForDenseNodeWithPartiallyDeletedRelChains(boolean modifyInChain, boolean modifyOutChain, boolean modifyLoopChain) throws Exception {
    int inRelCount = randomRelCount();
    int outRelCount = randomRelCount();
    int loopRelCount = randomRelCount();
    long nodeId = createNode(inRelCount, outRelCount, loopRelCount);
    StorageNodeCursor cursor = newCursor(nodeId);
    if (modifyInChain) {
        markRandomRelsInGroupNotInUse(nodeId, IN);
    }
    if (modifyOutChain) {
        markRandomRelsInGroupNotInUse(nodeId, OUT);
    }
    if (modifyLoopChain) {
        markRandomRelsInGroupNotInUse(nodeId, LOOP);
    }
    assertEquals(outRelCount + loopRelCount, degreeForDirection(cursor, OUTGOING));
    assertEquals(inRelCount + loopRelCount, degreeForDirection(cursor, INCOMING));
    assertEquals(inRelCount + outRelCount + loopRelCount, degreeForDirection(cursor, BOTH));
}
Also used : StorageNodeCursor(org.neo4j.storageengine.api.StorageNodeCursor)

Aggregations

StorageNodeCursor (org.neo4j.storageengine.api.StorageNodeCursor)29 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)12 StubStorageCursors (org.neo4j.storageengine.api.StubStorageCursors)12 Test (org.junit.jupiter.api.Test)8 ValueSource (org.junit.jupiter.params.provider.ValueSource)7 SimpleStageControl (org.neo4j.internal.batchimport.staging.SimpleStageControl)7 GeneratedIndexUpdates (org.neo4j.kernel.impl.transaction.state.storeview.GenerateIndexUpdatesStep.GeneratedIndexUpdates)7 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)5 CursorEntityIdIterator (org.neo4j.kernel.impl.transaction.state.storeview.PropertyAwareEntityStoreScan.CursorEntityIdIterator)5 StoragePropertyCursor (org.neo4j.storageengine.api.StoragePropertyCursor)5 HashSet (java.util.HashSet)4 Value (org.neo4j.values.storable.Value)3 HashMap (java.util.HashMap)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 MutableLongSet (org.eclipse.collections.api.set.primitive.MutableLongSet)2 EntityUpdates (org.neo4j.storageengine.api.EntityUpdates)2 Values.intValue (org.neo4j.values.storable.Values.intValue)2 Values.stringValue (org.neo4j.values.storable.Values.stringValue)2 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 MutableLongList (org.eclipse.collections.api.list.primitive.MutableLongList)1