Search in sources :

Example 51 with RelationshipGroupRecord

use of org.neo4j.kernel.impl.store.record.RelationshipGroupRecord in project neo4j by neo4j.

the class ReadGroupsFromCacheStep method nextBatchOrNull.

@Override
protected Object nextBatchOrNull(long ticket, int batchSize) {
    if (!data.hasNext()) {
        return null;
    }
    int i = 0;
    long lastOwner = -1;
    for (; data.hasNext(); i++) {
        // Logic below makes it so that all groups for a specific node ends up in the same batch,
        // which means that batches are slightly bigger (varying) than the requested size.
        RelationshipGroupRecord item = data.peek();
        if (i == batchSize - 1) {
            // Remember which owner this "last" group has...
            lastOwner = item.getOwningNode();
        } else if (i >= batchSize) {
            // ...and continue including groups in this batch until next owner comes
            if (item.getOwningNode() != lastOwner) {
                break;
            }
        }
        if (i >= scratch.length) {
            scratch = Arrays.copyOf(scratch, scratch.length * 2);
        }
        // which is "item", but also advances the iterator
        scratch[i] = data.next();
        cursor++;
    }
    return Arrays.copyOf(scratch, i);
}
Also used : RelationshipGroupRecord(org.neo4j.kernel.impl.store.record.RelationshipGroupRecord)

Example 52 with RelationshipGroupRecord

use of org.neo4j.kernel.impl.store.record.RelationshipGroupRecord in project neo4j by neo4j.

the class RelationshipGroupCache method iterator.

/**
     * @return cached {@link RelationshipGroupRecord} sorted by node id and then type id.
     */
@Override
public Iterator<RelationshipGroupRecord> iterator() {
    return new PrefetchingIterator<RelationshipGroupRecord>() {

        private long cursor;

        private long nodeId = fromNodeId;

        private int countLeftForThisNode = groupCount(nodeId);

        {
            findNextNodeWithGroupsIfNeeded();
        }

        @Override
        protected RelationshipGroupRecord fetchNextOrNull() {
            while (cursor < highCacheId) {
                RelationshipGroupRecord group = null;
                if (cache.getByte(cursor, 0) == 1) {
                    // Here we have an alive group
                    group = new RelationshipGroupRecord(-1).initialize(true, cache.get3ByteInt(cursor, 1), cache.get6ByteLong(cursor, 1 + 3), cache.get6ByteLong(cursor, 1 + 3 + 6), cache.get6ByteLong(cursor, 1 + 3 + 6 + 6), nodeId, // so this isn't at all "next" in the true sense of chain next.
                    countLeftForThisNode - 1);
                }
                cursor++;
                countLeftForThisNode--;
                findNextNodeWithGroupsIfNeeded();
                if (group != null) {
                    return group;
                }
            }
            return null;
        }

        private void findNextNodeWithGroupsIfNeeded() {
            if (countLeftForThisNode == 0) {
                do {
                    nodeId++;
                    countLeftForThisNode = nodeId >= groupCountCache.length() ? 0 : groupCount(nodeId);
                } while (countLeftForThisNode == 0 && nodeId < groupCountCache.length());
            }
        }
    };
}
Also used : PrefetchingIterator(org.neo4j.helpers.collection.PrefetchingIterator) RelationshipGroupRecord(org.neo4j.kernel.impl.store.record.RelationshipGroupRecord)

Example 53 with RelationshipGroupRecord

use of org.neo4j.kernel.impl.store.record.RelationshipGroupRecord in project neo4j by neo4j.

the class RelationshipDeleter method updateNodesForDeletedRelationship.

private void updateNodesForDeletedRelationship(RelationshipRecord rel, RecordAccessSet recordChanges, ResourceLocker locks) {
    RecordProxy<Long, NodeRecord, Void> startNodeChange = recordChanges.getNodeRecords().getOrLoad(rel.getFirstNode(), null);
    RecordProxy<Long, NodeRecord, Void> endNodeChange = recordChanges.getNodeRecords().getOrLoad(rel.getSecondNode(), null);
    NodeRecord startNode = recordChanges.getNodeRecords().getOrLoad(rel.getFirstNode(), null).forReadingLinkage();
    NodeRecord endNode = recordChanges.getNodeRecords().getOrLoad(rel.getSecondNode(), null).forReadingLinkage();
    boolean loop = startNode.getId() == endNode.getId();
    if (!startNode.isDense()) {
        if (rel.isFirstInFirstChain()) {
            startNode = startNodeChange.forChangingLinkage();
            startNode.setNextRel(rel.getFirstNextRel());
        }
        decrementTotalRelationshipCount(startNode.getId(), rel, startNode.getNextRel(), recordChanges.getRelRecords(), locks);
    } else {
        RecordProxy<Long, RelationshipGroupRecord, Integer> groupChange = relGroupGetter.getRelationshipGroup(startNode, rel.getType(), recordChanges.getRelGroupRecords()).group();
        assert groupChange != null : "Relationship group " + rel.getType() + " should have existed here";
        RelationshipGroupRecord group = groupChange.forReadingData();
        DirectionWrapper dir = DirectionIdentifier.wrapDirection(rel, startNode);
        if (rel.isFirstInFirstChain()) {
            group = groupChange.forChangingData();
            dir.setNextRel(group, rel.getFirstNextRel());
            if (groupIsEmpty(group)) {
                deleteGroup(startNodeChange, group, recordChanges.getRelGroupRecords());
            }
        }
        decrementTotalRelationshipCount(startNode.getId(), rel, dir.getNextRel(group), recordChanges.getRelRecords(), locks);
    }
    if (!endNode.isDense()) {
        if (rel.isFirstInSecondChain()) {
            endNode = endNodeChange.forChangingLinkage();
            endNode.setNextRel(rel.getSecondNextRel());
        }
        if (!loop) {
            decrementTotalRelationshipCount(endNode.getId(), rel, endNode.getNextRel(), recordChanges.getRelRecords(), locks);
        }
    } else {
        RecordProxy<Long, RelationshipGroupRecord, Integer> groupChange = relGroupGetter.getRelationshipGroup(endNode, rel.getType(), recordChanges.getRelGroupRecords()).group();
        DirectionWrapper dir = DirectionIdentifier.wrapDirection(rel, endNode);
        assert groupChange != null || loop : "Group has been deleted";
        if (groupChange != null) {
            RelationshipGroupRecord group = groupChange.forReadingData();
            if (rel.isFirstInSecondChain()) {
                group = groupChange.forChangingData();
                dir.setNextRel(group, rel.getSecondNextRel());
                if (groupIsEmpty(group)) {
                    deleteGroup(endNodeChange, group, recordChanges.getRelGroupRecords());
                }
            }
        }
        // Else this is a loop-rel and the group was deleted when dealing with the start node
        if (!loop) {
            decrementTotalRelationshipCount(endNode.getId(), rel, dir.getNextRel(groupChange.forChangingData()), recordChanges.getRelRecords(), locks);
        }
    }
}
Also used : NodeRecord(org.neo4j.kernel.impl.store.record.NodeRecord) DirectionWrapper(org.neo4j.kernel.impl.util.DirectionWrapper) RelationshipGroupRecord(org.neo4j.kernel.impl.store.record.RelationshipGroupRecord)

Example 54 with RelationshipGroupRecord

use of org.neo4j.kernel.impl.store.record.RelationshipGroupRecord in project neo4j by neo4j.

the class RelationshipDeleter method deleteGroup.

private void deleteGroup(RecordProxy<Long, NodeRecord, Void> nodeChange, RelationshipGroupRecord group, RecordAccess<Long, RelationshipGroupRecord, Integer> relGroupRecords) {
    long previous = group.getPrev();
    long next = group.getNext();
    if (previous == Record.NO_NEXT_RELATIONSHIP.intValue()) {
        // This is the first one, just point the node to the next group
        nodeChange.forChangingLinkage().setNextRel(next);
    } else {
        // There are others before it, point the previous to the next group
        RelationshipGroupRecord previousRecord = relGroupRecords.getOrLoad(previous, null).forChangingLinkage();
        previousRecord.setNext(next);
    }
    if (next != Record.NO_NEXT_RELATIONSHIP.intValue()) {
        // There are groups after this one, point that next group to the previous of the group to be deleted
        RelationshipGroupRecord nextRecord = relGroupRecords.getOrLoad(next, null).forChangingLinkage();
        nextRecord.setPrev(previous);
    }
    group.setInUse(false);
}
Also used : RelationshipGroupRecord(org.neo4j.kernel.impl.store.record.RelationshipGroupRecord)

Example 55 with RelationshipGroupRecord

use of org.neo4j.kernel.impl.store.record.RelationshipGroupRecord in project neo4j by neo4j.

the class RelationshipGroupGetter method getRelationshipGroup.

public RelationshipGroupPosition getRelationshipGroup(NodeRecord node, int type, RecordAccess<Long, RelationshipGroupRecord, Integer> relGroupRecords) {
    long groupId = node.getNextRel();
    long previousGroupId = Record.NO_NEXT_RELATIONSHIP.intValue();
    RecordProxy<Long, RelationshipGroupRecord, Integer> previous = null, current = null;
    while (groupId != Record.NO_NEXT_RELATIONSHIP.intValue()) {
        current = relGroupRecords.getOrLoad(groupId, null);
        RelationshipGroupRecord record = current.forReadingData();
        // not persistent so not a "change"
        record.setPrev(previousGroupId);
        if (record.getType() == type) {
            return new RelationshipGroupPosition(previous, current);
        } else if (record.getType() > type) {
            // empty handed right away
            return new RelationshipGroupPosition(previous, null);
        }
        previousGroupId = groupId;
        groupId = record.getNext();
        previous = current;
    }
    return new RelationshipGroupPosition(previous, null);
}
Also used : RelationshipGroupRecord(org.neo4j.kernel.impl.store.record.RelationshipGroupRecord)

Aggregations

RelationshipGroupRecord (org.neo4j.kernel.impl.store.record.RelationshipGroupRecord)83 Test (org.junit.Test)42 NodeRecord (org.neo4j.kernel.impl.store.record.NodeRecord)24 GraphStoreFixture (org.neo4j.consistency.checking.GraphStoreFixture)11 IdGenerator (org.neo4j.consistency.checking.GraphStoreFixture.IdGenerator)11 TransactionDataBuilder (org.neo4j.consistency.checking.GraphStoreFixture.TransactionDataBuilder)11 ConsistencySummaryStatistics (org.neo4j.consistency.report.ConsistencySummaryStatistics)11 RelationshipRecord (org.neo4j.kernel.impl.store.record.RelationshipRecord)10 Command (org.neo4j.kernel.impl.transaction.command.Command)5 IOException (java.io.IOException)4 InMemoryClosableChannel (org.neo4j.kernel.impl.transaction.log.InMemoryClosableChannel)4 File (java.io.File)3 Node (org.neo4j.graphdb.Node)3 Relationship (org.neo4j.graphdb.Relationship)3 Transaction (org.neo4j.graphdb.Transaction)3 RecordStorageEngine (org.neo4j.kernel.impl.storageengine.impl.recordstorage.RecordStorageEngine)3 NeoStores (org.neo4j.kernel.impl.store.NeoStores)3 RelationshipStore (org.neo4j.kernel.impl.store.RelationshipStore)3 PropertyRecord (org.neo4j.kernel.impl.store.record.PropertyRecord)3 RelationshipGroupCommand (org.neo4j.kernel.impl.transaction.command.Command.RelationshipGroupCommand)3