internal virtual void Single(long reference, Read read) { StoreCursor.single(reference); _type = -1; this._single = reference; Init(read); this._addedRelationships = ImmutableEmptyLongIterator.INSTANCE; }
internal virtual void Scan(int type, Read read) { StoreCursor.scan(type); this._type = type; this._single = NO_ID; Init(read); this._addedRelationships = ImmutableEmptyLongIterator.INSTANCE; }
public override void Close() { if (!Closed) { Read = null; StoreCursor.close(); Pool.accept(this); } }
protected internal override void CollectAddedTxStateSnapshot() { if (_filterState == FilterState.NotInitialized) { StoreCursor.next(); SetupFilterState(); } NodeState nodeState = Read.txState().getNodeState(StoreCursor.originNodeReference()); _addedRelationships = HasTxStateFilter() ? nodeState.GetAddedRelationships(_filterState.direction, _filterType) : nodeState.AddedRelationships; }
public override void Close() { if (!Closed) { Read = null; _filterState = FilterState.None; _filterType = NO_ID; _filterStore = false; StoreCursor.close(); Pool.accept(this); } }
public override string ToString() { if (Closed) { return("RelationshipScanCursor[closed state]"); } else { return("RelationshipScanCursor[id=" + StoreCursor.entityReference() + ", open state with: single=" + _single + ", type=" + _type + ", " + StoreCursor.ToString() + "]"); } }
private void SetupFilterState() { _filterType = StoreCursor.type(); const long source = SourceNodeReference(), target = TargetNodeReference(); if (source == target) { _filterState = FilterState.Loop; } else if (source == StoreCursor.originNodeReference()) { _filterState = FilterState.Outgoing; } else if (target == StoreCursor.originNodeReference()) { _filterState = FilterState.Incoming; } }
public override bool Next() { // Check tx state bool hasChanges = hasChanges(); if (hasChanges && _addedRelationships.hasNext()) { Read.txState().relationshipVisit(_addedRelationships.next(), StoreCursor); return(true); } while (StoreCursor.next()) { if (!hasChanges || !Read.txState().relationshipIsDeletedInThisTx(StoreCursor.entityReference())) { return(true); } } return(false); }
public override bool Next() { bool hasChanges; if (_filterState == FilterState.NotInitialized) { hasChanges = hasChanges(); // <- will setup filter state if needed if (_filterState == FilterState.NotInitialized && _filterStore) { StoreCursor.next(); SetupFilterState(); } if (_filterState != FilterState.NotInitialized && !(hasChanges && Read.txState().relationshipIsDeletedInThisTx(RelationshipReference()))) { return(true); } } else { hasChanges = hasChanges(); } // tx-state relationships if (hasChanges && _addedRelationships.hasNext()) { Read.txState().relationshipVisit(_addedRelationships.next(), StoreCursor); return(true); } while (StoreCursor.next()) { bool skip = (_filterStore && !CorrectTypeAndDirection()) || (hasChanges && Read.txState().relationshipIsDeletedInThisTx(StoreCursor.entityReference())); if (!skip) { return(true); } } return(false); }
public override string ToString() { if (Closed) { return("RelationshipTraversalCursor[closed state]"); } else { string mode = "mode="; if (_filterStore) { mode = mode + "filterStore"; } else { mode = mode + "regular"; } return("RelationshipTraversalCursor[id=" + StoreCursor.entityReference() + ", " + mode + ", " + StoreCursor.ToString() + "]"); } }
public virtual void Release() { StoreCursor.close(); }
private bool CorrectTypeAndDirection() { return((_filterType == ANY_RELATIONSHIP_TYPE || _filterType == StoreCursor.type()) && _filterState.check(SourceNodeReference(), TargetNodeReference(), StoreCursor.originNodeReference())); }
public override long OriginNodeReference() { return(StoreCursor.originNodeReference()); }
public override long NeighbourNodeReference() { return(StoreCursor.neighbourNodeReference()); }
internal virtual void Init(long nodeReference, long reference, Read read) { /* There are 5 different ways a relationship traversal cursor can be initialized: * * 1. From a batched group in a detached way. This happens when the user manually retrieves the relationships * references from the group cursor and passes it to this method and if the group cursor was based on having * batched all the different types in the single (mixed) chain of relationships. * In this case we should pass a reference marked with some flag to the first relationship in the chain that * has the type of the current group in the group cursor. The traversal cursor then needs to read the type * from that first record and use that type as a filter for when reading the rest of the chain. * - NOTE: we probably have to do the same sort of filtering for direction - so we need a flag for that too. * * 2. From a batched group in a DIRECT way. This happens when the traversal cursor is initialized directly from * the group cursor, in this case we can simply initialize the traversal cursor with the buffered state from * the group cursor, so this method here does not have to be involved, and things become pretty simple. * * 3. Traversing all relationships - regardless of type - of a node that has grouped relationships. In this case * the traversal cursor needs to traverse through the group records in order to get to the actual * relationships. The initialization of the cursor (through this here method) should be with a FLAGGED * reference to the (first) group record. * * 4. Traversing a single chain - this is what happens in the cases when * a) Traversing all relationships of a node without grouped relationships. * b) Traversing the relationships of a particular group of a node with grouped relationships. * * 5. There are no relationships - i.e. passing in NO_ID to this method. * * This means that we need reference encodings (flags) for cases: 1, 3, 4, 5 */ RelationshipReferenceEncoding encoding = RelationshipReferenceEncoding.parseEncoding(reference); switch (encoding.innerEnumValue) { case Org.Neo4j.Kernel.Impl.Newapi.RelationshipReferenceEncoding.InnerEnum.NONE: case Org.Neo4j.Kernel.Impl.Newapi.RelationshipReferenceEncoding.InnerEnum.GROUP: StoreCursor.init(nodeReference, reference); InitFiltering(FilterState.None, false); break; case Org.Neo4j.Kernel.Impl.Newapi.RelationshipReferenceEncoding.InnerEnum.FILTER_TX_STATE: // The relationships in tx-state needs to be filtered according to the first relationship we discover, // but let's not have the store cursor bother with this detail. StoreCursor.init(nodeReference, clearEncoding(reference)); InitFiltering(FilterState.NotInitialized, false); break; case Org.Neo4j.Kernel.Impl.Newapi.RelationshipReferenceEncoding.InnerEnum.FILTER: // The relationships needs to be filtered according to the first relationship we discover StoreCursor.init(nodeReference, clearEncoding(reference)); InitFiltering(FilterState.NotInitialized, true); break; case Org.Neo4j.Kernel.Impl.Newapi.RelationshipReferenceEncoding.InnerEnum.NO_OUTGOING_OF_TYPE: // nothing in store, but proceed to check tx-state changes StoreCursor.init(nodeReference, NO_ID); InitFiltering(FilterState.fromRelationshipDirection(OUTGOING), false); this._filterType = ( int )clearEncoding(reference); break; case Org.Neo4j.Kernel.Impl.Newapi.RelationshipReferenceEncoding.InnerEnum.NO_INCOMING_OF_TYPE: // nothing in store, but proceed to check tx-state changes StoreCursor.init(nodeReference, NO_ID); InitFiltering(FilterState.fromRelationshipDirection(INCOMING), false); this._filterType = ( int )clearEncoding(reference); break; case Org.Neo4j.Kernel.Impl.Newapi.RelationshipReferenceEncoding.InnerEnum.NO_LOOP_OF_TYPE: // nothing in store, but proceed to check tx-state changes StoreCursor.init(nodeReference, NO_ID); InitFiltering(FilterState.fromRelationshipDirection(LOOP), false); this._filterType = ( int )clearEncoding(reference); break; default: throw new System.InvalidOperationException("Unknown encoding " + encoding); } Init(read); this._addedRelationships = ImmutableEmptyLongIterator.INSTANCE; }