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;
        }