コード例 #1
0
        public virtual RelationshipGroupPosition GetRelationshipGroup(NodeRecord node, int type, RecordAccess <RelationshipGroupRecord, int> relGroupRecords)
        {
            long groupId         = node.NextRel;
            long previousGroupId = Record.NO_NEXT_RELATIONSHIP.intValue();
            RecordAccess_RecordProxy <RelationshipGroupRecord, int> previous = null;
            RecordAccess_RecordProxy <RelationshipGroupRecord, int> current;

            while (groupId != Record.NO_NEXT_RELATIONSHIP.intValue())
            {
                current = relGroupRecords.GetOrLoad(groupId, null);
                RelationshipGroupRecord record = current.ForReadingData();
                record.Prev = previousGroupId;                         // not persistent so not a "change"
                if (record.Type == type)
                {
                    return(new RelationshipGroupPosition(previous, current));
                }
                else if (record.Type > type)
                {                         // The groups are sorted in the chain, so if we come too far we can return
                    // empty handed right away
                    return(new RelationshipGroupPosition(previous, null));
                }
                previousGroupId = groupId;
                groupId         = record.Next;
                previous        = current;
            }
            return(new RelationshipGroupPosition(previous, null));
        }
コード例 #2
0
ファイル: PropertyDeleter.cs プロジェクト: Neo4Net/Neo4Net
        /// <summary>
        /// Removes property with given {@code propertyKey} from property chain owner by the primitive found in
        /// {@code primitiveProxy}.
        /// </summary>
        /// <param name="primitiveProxy"> access to the primitive record pointing to the start of the property chain. </param>
        /// <param name="propertyKey"> the property key token id to look for and remove. </param>
        /// <param name="propertyRecords"> access to records. </param>
        /// <exception cref="IllegalStateException"> if property key was not found in the property chain. </exception>
        public virtual void RemoveProperty <P>(RecordAccess_RecordProxy <P, Void> primitiveProxy, int propertyKey, RecordAccess <PropertyRecord, PrimitiveRecord> propertyRecords) where P : Org.Neo4j.Kernel.impl.store.record.PrimitiveRecord
        {
            PrimitiveRecord primitive  = primitiveProxy.ForReadingData();
            long            propertyId = _traverser.findPropertyRecordContaining(primitive, propertyKey, propertyRecords, true);

            RemoveProperty(primitiveProxy, propertyKey, propertyRecords, primitive, propertyId);
        }
コード例 #3
0
        private RECORD Prepared <RECORD, T1>(RecordAccess_RecordProxy <T1> proxy, RecordStore <RECORD> store) where RECORD : Org.Neo4j.Kernel.impl.store.record.AbstractBaseRecord
        {
            RECORD after = proxy.ForReadingLinkage();

            store.PrepareForCommit(after);
            return(after);
        }
コード例 #4
0
 public TrackingRecordProxy(RecordAccess_RecordProxy <RECORD, ADDITIONAL> @delegate, bool created, Tracker tracker)
 {
     this.@delegate = @delegate;
     this._created  = created;
     this._tracker  = tracker;
     this._changed  = created;
 }
コード例 #5
0
        internal virtual void DropSchemaRule(SchemaRule rule)
        {
            RecordAccess_RecordProxy <SchemaRecord, SchemaRule> change = _recordChangeSet.SchemaRuleChanges.getOrLoad(rule.Id, rule);
            SchemaRecord records = change.ForChangingData();

            foreach (DynamicRecord record in records)
            {
                record.InUse = false;
            }
            records.InUse = false;
        }
コード例 #6
0
        public override RecordAccess_RecordProxy <RECORD, ADDITIONAL> GetOrLoad(long key, ADDITIONAL additionalData)
        {
            RecordAccess_RecordProxy <RECORD, ADDITIONAL> result = _recordChanges.get(key);

            if (result == null)
            {
                RECORD record = _loader.load(key, additionalData);
                result = new RecordChange <RECORD, ADDITIONAL>(_recordChanges, _changeCounter, key, record, _loader, false, additionalData);
            }
            return(result);
        }
コード例 #7
0
ファイル: PropertyDeleter.cs プロジェクト: Neo4Net/Neo4Net
        /// <summary>
        /// Removes property with given {@code propertyKey} from property chain owner by the primitive found in
        /// {@code primitiveProxy} if it exists.
        /// </summary>
        /// <param name="primitiveProxy"> access to the primitive record pointing to the start of the property chain. </param>
        /// <param name="propertyKey"> the property key token id to look for and remove. </param>
        /// <param name="propertyRecords"> access to records. </param>
        /// <returns> {@code true} if the property was found and removed, otherwise {@code false}. </returns>
        public virtual bool RemovePropertyIfExists <P>(RecordAccess_RecordProxy <P, Void> primitiveProxy, int propertyKey, RecordAccess <PropertyRecord, PrimitiveRecord> propertyRecords) where P : Org.Neo4j.Kernel.impl.store.record.PrimitiveRecord
        {
            PrimitiveRecord primitive  = primitiveProxy.ForReadingData();
            long            propertyId = _traverser.findPropertyRecordContaining(primitive, propertyKey, propertyRecords, false);

            if (!Record.NO_NEXT_PROPERTY.@is(propertyId))
            {
                RemoveProperty(primitiveProxy, propertyKey, propertyRecords, primitive, propertyId);
                return(true);
            }
            return(false);
        }
コード例 #8
0
        private void ChangeSchemaRule(SchemaRule rule, SchemaRule updatedRule)
        {
            //Read the current record
            RecordAccess_RecordProxy <SchemaRecord, SchemaRule> change = _recordChangeSet.SchemaRuleChanges.getOrLoad(rule.Id, rule);
            SchemaRecord records = change.ForReadingData();

            //Register the change of the record
            RecordAccess_RecordProxy <SchemaRecord, SchemaRule> recordChange = _recordChangeSet.SchemaRuleChanges.setRecord(rule.Id, records, updatedRule);
            SchemaRecord dynamicRecords = recordChange.ForChangingData();

            //Update the record
            dynamicRecords.DynamicRecords = _schemaStore.allocateFrom(updatedRule);
        }
コード例 #9
0
            internal virtual RECORD PrepareForChange()
            {
                EnsureHasBeforeRecordImage();
                if (!this.ChangedConflict)
                {
                    RecordAccess_RecordProxy <RECORD, ADDITIONAL> previous = this.AllChanges.put(KeyConflict, this);

                    if (previous == null || !previous.Changed)
                    {
                        ChangeCounter.increment();
                    }

                    this.ChangedConflict = true;
                }
                return(this.Record);
            }
コード例 #10
0
ファイル: PropertyDeleter.cs プロジェクト: Neo4Net/Neo4Net
        public virtual void DeletePropertyChain(PrimitiveRecord primitive, RecordAccess <PropertyRecord, PrimitiveRecord> propertyRecords)
        {
            long nextProp = primitive.NextProp;

            while (nextProp != Record.NO_NEXT_PROPERTY.intValue())
            {
                RecordAccess_RecordProxy <PropertyRecord, PrimitiveRecord> propertyChange = propertyRecords.GetOrLoad(nextProp, primitive);

                // TODO forChanging/forReading piggy-backing
                PropertyRecord propRecord = propertyChange.ForChangingData();
                DeletePropertyRecordIncludingValueRecords(propRecord);
                nextProp           = propRecord.NextProp;
                propRecord.Changed = primitive;
            }
            primitive.NextProp = Record.NO_NEXT_PROPERTY.intValue();
        }
コード例 #11
0
        private void DeleteGroup(RecordAccess_RecordProxy <NodeRecord, Void> nodeChange, RelationshipGroupRecord group, RecordAccess <RelationshipGroupRecord, int> relGroupRecords)
        {
            long previous = group.Prev;
            long next     = group.Next;

            if (previous == Record.NO_NEXT_RELATIONSHIP.intValue())
            {               // This is the first one, just point the node to the next group
                nodeChange.ForChangingLinkage().NextRel = next;
            }
            else
            {               // There are others before it, point the previous to the next group
                RelationshipGroupRecord previousRecord = relGroupRecords.GetOrLoad(previous, null).forChangingLinkage();
                previousRecord.Next = 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.Prev = previous;
            }
            group.InUse = false;
        }
コード例 #12
0
        public virtual RecordAccess_RecordProxy <RelationshipGroupRecord, int> GetOrCreateRelationshipGroup(NodeRecord node, int type, RecordAccess <RelationshipGroupRecord, int> relGroupRecords)
        {
            RelationshipGroupPosition existingGroup = GetRelationshipGroup(node, type, relGroupRecords);
            RecordAccess_RecordProxy <RelationshipGroupRecord, int> change = existingGroup.Group();

            if (change == null)
            {
                Debug.Assert(node.Dense, "Node " + node + " should have been dense at this point");
                long id = _idGenerator.nextId();
                change = relGroupRecords.Create(id, type);
                RelationshipGroupRecord record = change.ForChangingData();
                record.InUse = true;
                record.SetCreated();
                record.OwningNode = node.Id;

                // Attach it...
                RecordAccess_RecordProxy <RelationshipGroupRecord, int> closestPreviousChange = existingGroup.ClosestPrevious();
                if (closestPreviousChange != null)
                {                         // ...after the closest previous one
                    RelationshipGroupRecord closestPrevious = closestPreviousChange.ForChangingLinkage();
                    record.Next          = closestPrevious.Next;
                    record.Prev          = closestPrevious.Id;
                    closestPrevious.Next = id;
                }
                else
                {                         // ...first in the chain
                    long firstGroupId = node.NextRel;
                    if (firstGroupId != Record.NO_NEXT_RELATIONSHIP.intValue())
                    {                              // There are others, make way for this new group
                        RelationshipGroupRecord previousFirstRecord = relGroupRecords.GetOrLoad(firstGroupId, type).forReadingData();
                        record.Next = previousFirstRecord.Id;
                        previousFirstRecord.Prev = id;
                    }
                    node.NextRel = id;
                }
            }
            return(change);
        }
コード例 #13
0
        private void ConvertNodeToDenseIfNecessary(NodeRecord node, RecordAccess <RelationshipRecord, Void> relRecords, RecordAccess <RelationshipGroupRecord, int> relGroupRecords, ResourceLocker locks)
        {
            if (node.Dense)
            {
                return;
            }
            long relId = node.NextRel;

            if (relId != Record.NO_NEXT_RELATIONSHIP.intValue())
            {
                RecordAccess_RecordProxy <RelationshipRecord, Void> relChange = relRecords.GetOrLoad(relId, null);
                RelationshipRecord rel = relChange.ForReadingLinkage();
                if (RelCount(node.Id, rel) >= _denseNodeThreshold)
                {
                    locks.AcquireExclusive(LockTracer.NONE, ResourceTypes.RELATIONSHIP, relId);
                    // Re-read the record after we've locked it since another transaction might have
                    // changed in the meantime.
                    relChange = relRecords.GetOrLoad(relId, null);

                    ConvertNodeToDenseNode(node, relChange.ForChangingLinkage(), relRecords, relGroupRecords, locks);
                }
            }
        }
コード例 #14
0
ファイル: PropertyDeleter.cs プロジェクト: Neo4Net/Neo4Net
        private void RemoveProperty <P>(RecordAccess_RecordProxy <P, Void> primitiveProxy, int propertyKey, RecordAccess <PropertyRecord, PrimitiveRecord> propertyRecords, PrimitiveRecord primitive, long propertyId) where P : Org.Neo4j.Kernel.impl.store.record.PrimitiveRecord
        {
            RecordAccess_RecordProxy <PropertyRecord, PrimitiveRecord> recordChange = propertyRecords.GetOrLoad(propertyId, primitive);
            PropertyRecord propRecord = recordChange.ForChangingData();

            if (!propRecord.InUse())
            {
                throw new System.InvalidOperationException("Unable to delete property[" + propertyId + "] since it is already deleted.");
            }

            PropertyBlock block = propRecord.RemovePropertyBlock(propertyKey);

            if (block == null)
            {
                throw new System.InvalidOperationException("Property with index[" + propertyKey + "] is not present in property[" + propertyId + "]");
            }

            foreach (DynamicRecord valueRecord in block.ValueRecords)
            {
                Debug.Assert(valueRecord.InUse());
                valueRecord.SetInUse(false, block.Type.intValue());
                propRecord.AddDeletedRecord(valueRecord);
            }
            if (propRecord.Size() > 0)
            {
                /*
                 * There are remaining blocks in the record. We do not unlink yet.
                 */
                propRecord.Changed = primitive;
                Debug.Assert(_traverser.assertPropertyChain(primitive, propertyRecords));
            }
            else
            {
                UnlinkPropertyRecord(propRecord, propertyRecords, primitiveProxy);
            }
        }
コード例 #15
0
        private void UpdateNodesForDeletedRelationship(RelationshipRecord rel, RecordAccessSet recordChanges, ResourceLocker locks)
        {
            RecordAccess_RecordProxy <NodeRecord, Void> startNodeChange = recordChanges.NodeRecords.getOrLoad(rel.FirstNode, null);
            RecordAccess_RecordProxy <NodeRecord, Void> endNodeChange   = recordChanges.NodeRecords.getOrLoad(rel.SecondNode, null);

            NodeRecord startNode = recordChanges.NodeRecords.getOrLoad(rel.FirstNode, null).forReadingLinkage();
            NodeRecord endNode   = recordChanges.NodeRecords.getOrLoad(rel.SecondNode, null).forReadingLinkage();
            bool       loop      = startNode.Id == endNode.Id;

            if (!startNode.Dense)
            {
                if (rel.FirstInFirstChain)
                {
                    startNode         = startNodeChange.ForChangingLinkage();
                    startNode.NextRel = rel.FirstNextRel;
                }
                DecrementTotalRelationshipCount(startNode.Id, rel, startNode.NextRel, recordChanges.RelRecords, locks);
            }
            else
            {
                RecordAccess_RecordProxy <RelationshipGroupRecord, int> groupChange = _relGroupGetter.getRelationshipGroup(startNode, rel.Type, recordChanges.RelGroupRecords).group();
                Debug.Assert(groupChange != null, "Relationship group " + rel.Type + " should have existed here");
                RelationshipGroupRecord group = groupChange.ForReadingData();
                DirectionWrapper        dir   = DirectionIdentifier.wrapDirection(rel, startNode);
                if (rel.FirstInFirstChain)
                {
                    group = groupChange.ForChangingData();
                    dir.setNextRel(group, rel.FirstNextRel);
                    if (GroupIsEmpty(group))
                    {
                        DeleteGroup(startNodeChange, group, recordChanges.RelGroupRecords);
                    }
                }
                DecrementTotalRelationshipCount(startNode.Id, rel, dir.getNextRel(group), recordChanges.RelRecords, locks);
            }

            if (!endNode.Dense)
            {
                if (rel.FirstInSecondChain)
                {
                    endNode         = endNodeChange.ForChangingLinkage();
                    endNode.NextRel = rel.SecondNextRel;
                }
                if (!loop)
                {
                    DecrementTotalRelationshipCount(endNode.Id, rel, endNode.NextRel, recordChanges.RelRecords, locks);
                }
            }
            else
            {
                RecordAccess_RecordProxy <RelationshipGroupRecord, int> groupChange = _relGroupGetter.getRelationshipGroup(endNode, rel.Type, recordChanges.RelGroupRecords).group();
                DirectionWrapper dir = DirectionIdentifier.wrapDirection(rel, endNode);
                Debug.Assert(groupChange != null || loop, "Group has been deleted");
                if (groupChange != null)
                {
                    RelationshipGroupRecord group;
                    if (rel.FirstInSecondChain)
                    {
                        group = groupChange.ForChangingData();
                        dir.setNextRel(group, rel.SecondNextRel);
                        if (GroupIsEmpty(group))
                        {
                            DeleteGroup(endNodeChange, group, recordChanges.RelGroupRecords);
                        }
                    }
                }                         // Else this is a loop-rel and the group was deleted when dealing with the start node
                if (!loop)
                {
                    DecrementTotalRelationshipCount(endNode.Id, rel, dir.getNextRel(groupChange.ForChangingData()), recordChanges.RelRecords, locks);
                }
            }
        }
コード例 #16
0
        public override RecordAccess_RecordProxy <RECORD, ADDITIONAL> GetIfLoaded(long key)
        {
            RecordAccess_RecordProxy <RECORD, ADDITIONAL> actual = @delegate.GetIfLoaded(key);

            return(actual == null ? null : new TrackingRecordProxy <RECORD, ADDITIONAL>(actual, false, _tracker));
        }
コード例 #17
0
 protected internal override RecordAccess_RecordProxy <RECORD, ADDITIONAL> underlyingObjectToObject(RecordAccess_RecordProxy <RECORD, ADDITIONAL> actual)
 {
     return(new TrackingRecordProxy <RECORD, ADDITIONAL>(actual, false, _outerInstance.tracker));
 }
コード例 #18
0
        /// <summary>
        /// Removes the given property identified by its index from the relationship
        /// with the given id.
        /// </summary>
        /// <param name="relId"> The id of the relationship that is to have the property
        ///            removed. </param>
        /// <param name="propertyKey"> The index key of the property. </param>
        internal virtual void RelRemoveProperty(long relId, int propertyKey)
        {
            RecordAccess_RecordProxy <RelationshipRecord, Void> rel = _recordChangeSet.RelRecords.getOrLoad(relId, null);

            _propertyDeleter.removeProperty(rel, propertyKey, _recordChangeSet.PropertyRecords);
        }
コード例 #19
0
        /// <summary>
        /// Removes the given property identified by indexKeyId of the node with the
        /// given id.
        /// </summary>
        /// <param name="nodeId"> The id of the node that is to have the property removed. </param>
        /// <param name="propertyKey"> The index key of the property. </param>
        public virtual void NodeRemoveProperty(long nodeId, int propertyKey)
        {
            RecordAccess_RecordProxy <NodeRecord, Void> node = _recordChangeSet.NodeRecords.getOrLoad(nodeId, null);

            _propertyDeleter.removeProperty(node, propertyKey, _recordChangeSet.PropertyRecords);
        }
コード例 #20
0
        /// <summary>
        /// Adds a property to the given relationship, with the given index and
        /// value. </summary>
        ///  <param name="relId"> The id of the relationship to which to add the property. </param>
        /// <param name="propertyKey"> The index of the key of the property to add. </param>
        /// <param name="value"> The value of the property. </param>
        internal virtual void RelAddProperty(long relId, int propertyKey, Value value)
        {
            RecordAccess_RecordProxy <RelationshipRecord, Void> rel = _recordChangeSet.RelRecords.getOrLoad(relId, null);

            _propertyCreator.primitiveSetProperty(rel, propertyKey, value, _recordChangeSet.PropertyRecords);
        }
コード例 #21
0
 public RelationshipGroupPosition(RecordAccess_RecordProxy <RelationshipGroupRecord, int> closestPrevious, RecordAccess_RecordProxy <RelationshipGroupRecord, int> group)
 {
     this.ClosestPreviousConflict = closestPrevious;
     this.GroupConflict           = group;
 }
コード例 #22
0
        /// <summary>
        /// Adds a property to the given node, with the given index and value. </summary>
        ///  <param name="nodeId"> The id of the node to which to add the property. </param>
        /// <param name="propertyKey"> The index of the key of the property to add. </param>
        /// <param name="value"> The value of the property. </param>
        internal virtual void NodeAddProperty(long nodeId, int propertyKey, Value value)
        {
            RecordAccess_RecordProxy <NodeRecord, Void> node = _recordChangeSet.NodeRecords.getOrLoad(nodeId, null);

            _propertyCreator.primitiveSetProperty(node, propertyKey, value, _recordChangeSet.PropertyRecords);
        }
コード例 #23
0
ファイル: PropertyDeleter.cs プロジェクト: Neo4Net/Neo4Net
        private void UnlinkPropertyRecord <P>(PropertyRecord propRecord, RecordAccess <PropertyRecord, PrimitiveRecord> propertyRecords, RecordAccess_RecordProxy <P, Void> primitiveRecordChange) where P : Org.Neo4j.Kernel.impl.store.record.PrimitiveRecord
        {
            P primitive = primitiveRecordChange.ForReadingLinkage();

            Debug.Assert(_traverser.assertPropertyChain(primitive, propertyRecords));
            Debug.Assert(propRecord.Size() == 0);
            long prevProp = propRecord.PrevProp;
            long nextProp = propRecord.NextProp;

            if (primitive.NextProp == propRecord.Id)
            {
                Debug.Assert(propRecord.PrevProp == Record.NO_PREVIOUS_PROPERTY.intValue(), propRecord + " for ");
                +primitive;
                primitiveRecordChange.ForChangingLinkage().NextProp = nextProp;
            }
            if (prevProp != Record.NO_PREVIOUS_PROPERTY.intValue())
            {
                PropertyRecord prevPropRecord = propertyRecords.GetOrLoad(prevProp, primitive).forChangingLinkage();
                Debug.Assert(prevPropRecord.InUse(), prevPropRecord + "->" + propRecord + " for " + primitive);
                prevPropRecord.NextProp = nextProp;
                prevPropRecord.Changed  = primitive;
            }
            if (nextProp != Record.NO_NEXT_PROPERTY.intValue())
            {
                PropertyRecord nextPropRecord = propertyRecords.GetOrLoad(nextProp, primitive).forChangingLinkage();
                Debug.Assert(nextPropRecord.InUse(), propRecord + "->" + nextPropRecord + " for " + primitive);
                nextPropRecord.PrevProp = prevProp;
                nextPropRecord.Changed  = primitive;
            }
            propRecord.InUse = false;

            /*
             *  The following two are not needed - the above line does all the work (PropertyStore
             *  does not write out the prev/next for !inUse records). It is nice to set this
             *  however to check for consistency when assertPropertyChain().
             */
            propRecord.PrevProp = Record.NO_PREVIOUS_PROPERTY.intValue();
            propRecord.NextProp = Record.NO_NEXT_PROPERTY.intValue();
            propRecord.Changed  = primitive;
            Debug.Assert(_traverser.assertPropertyChain(primitive, propertyRecords));
        }
コード例 #24
0
ファイル: PropertyCreator.cs プロジェクト: Neo4Net/Neo4Net
        public virtual void PrimitiveSetProperty <P>(RecordAccess_RecordProxy <P, Void> primitiveRecordChange, int propertyKey, Value value, RecordAccess <PropertyRecord, PrimitiveRecord> propertyRecords) where P : Org.Neo4j.Kernel.impl.store.record.PrimitiveRecord
        {
            PropertyBlock block     = EncodePropertyValue(propertyKey, value);
            P             primitive = primitiveRecordChange.ForReadingLinkage();

            Debug.Assert(_traverser.assertPropertyChain(primitive, propertyRecords));
            int newBlockSizeInBytes = block.Size;

            // Traverse the existing property chain. Tracking two things along the way:
            // - (a) Free space for this block (candidateHost)
            // - (b) Existence of a block with the property key
            // Chain traversal can be aborted only if:
            // - (1) (b) occurs and new property block fits where the current is
            // - (2) (a) occurs and (b) has occurred, but new property block didn't fit
            // - (3) (b) occurs and (a) has occurred
            // - (4) Chain ends
            RecordAccess_RecordProxy <PropertyRecord, PrimitiveRecord> freeHostProxy     = null;
            RecordAccess_RecordProxy <PropertyRecord, PrimitiveRecord> existingHostProxy = null;
            long prop = primitive.NextProp;

            while (prop != Record.NO_NEXT_PROPERTY.intValue())                 // <-- (4)
            {
                RecordAccess_RecordProxy <PropertyRecord, PrimitiveRecord> proxy = propertyRecords.GetOrLoad(prop, primitive);
                PropertyRecord propRecord = proxy.ForReadingLinkage();
                Debug.Assert(propRecord.InUse(), propRecord);

                // (a) search for free space
                if (PropertyFitsInside(newBlockSizeInBytes, propRecord))
                {
                    freeHostProxy = proxy;
                    if (existingHostProxy != null)
                    {
                        // (2)
                        PropertyRecord freeHost = proxy.ForChangingData();
                        freeHost.AddPropertyBlock(block);
                        freeHost.Changed = primitive;
                        Debug.Assert(_traverser.assertPropertyChain(primitive, propertyRecords));
                        return;
                    }
                }

                // (b) search for existence of property key
                PropertyBlock existingBlock = propRecord.GetPropertyBlock(propertyKey);
                if (existingBlock != null)
                {
                    // We found an existing property and whatever happens we have to remove the existing
                    // block so that we can add the new one, where ever we decide to place it
                    existingHostProxy = proxy;
                    PropertyRecord existingHost = existingHostProxy.ForChangingData();
                    RemoveProperty(primitive, existingHost, existingBlock);

                    // Now see if we at this point can add the new block
                    if (newBlockSizeInBytes <= existingBlock.Size || PropertyFitsInside(newBlockSizeInBytes, existingHost))                                  // fallback check
                    {
                        // (1) yes we could add it right into the host of the existing block
                        existingHost.AddPropertyBlock(block);
                        Debug.Assert(_traverser.assertPropertyChain(primitive, propertyRecords));
                        return;
                    }
                    else if (freeHostProxy != null)
                    {
                        // (3) yes we could add it to a previously found host with sufficiently free space in it
                        PropertyRecord freeHost = freeHostProxy.ForChangingData();
                        freeHost.AddPropertyBlock(block);
                        freeHost.Changed = primitive;
                        Debug.Assert(_traverser.assertPropertyChain(primitive, propertyRecords));
                        return;
                    }
                    // else we can't add it at this point
                }

                // Continue down the chain
                prop = propRecord.NextProp;
            }

            // At this point we haven't added the property block, although we may have found room for it
            // along the way. If we didn't then just create a new record, it's fine
            PropertyRecord freeHost;

            if (freeHostProxy == null)
            {
                // We couldn't find free space along the way, so create a new host record
                freeHost       = propertyRecords.Create(_propertyRecordIdGenerator.nextId(), primitive).forChangingData();
                freeHost.InUse = true;
                if (primitive.NextProp != Record.NO_NEXT_PROPERTY.intValue())
                {
                    // This isn't the first property record for the entity, re-shuffle the first one so that
                    // the new one becomes the first
                    PropertyRecord prevProp = propertyRecords.GetOrLoad(primitive.NextProp, primitive).forChangingLinkage();
                    Debug.Assert(prevProp.PrevProp == Record.NO_PREVIOUS_PROPERTY.intValue());
                    prevProp.PrevProp = freeHost.Id;
                    freeHost.NextProp = prevProp.Id;
                    prevProp.Changed  = primitive;
                }

                // By the way, this is the only condition where the primitive record also needs to change
                primitiveRecordChange.ForChangingLinkage().NextProp = freeHost.Id;
            }
            else
            {
                freeHost = freeHostProxy.ForChangingData();
            }

            // At this point we know that we have a host record with sufficient space in it for the block
            // to add, so simply add it
            freeHost.AddPropertyBlock(block);
            Debug.Assert(_traverser.assertPropertyChain(primitive, propertyRecords));
        }
コード例 #25
0
        /// <summary>
        /// Removes the given property identified by indexKeyId of the graph with the
        /// given id.
        /// </summary>
        /// <param name="propertyKey"> The index key of the property. </param>
        internal virtual void GraphRemoveProperty(int propertyKey)
        {
            RecordAccess_RecordProxy <NeoStoreRecord, Void> recordChange = OrLoadNeoStoreRecord;

            _propertyDeleter.removeProperty(recordChange, propertyKey, _recordChangeSet.PropertyRecords);
        }