private void DisconnectRelationship(RelationshipRecord rel, RecordAccessSet recordChangeSet, ResourceLocker locks) { Disconnect(rel, RelationshipConnection.StartNext, recordChangeSet.RelRecords, locks); Disconnect(rel, RelationshipConnection.StartPrev, recordChangeSet.RelRecords, locks); Disconnect(rel, RelationshipConnection.EndNext, recordChangeSet.RelRecords, locks); Disconnect(rel, RelationshipConnection.EndPrev, recordChangeSet.RelRecords, locks); }
/// <summary> /// Deletes a relationship by its id, returning its properties which are now /// removed. It is assumed that the nodes it connects have already been /// deleted in this /// transaction. /// </summary> /// <param name="id"> The id of the relationship to delete. </param> internal virtual void RelDelete(long id, RecordAccessSet recordChanges, ResourceLocker locks) { RelationshipRecord record = recordChanges.RelRecords.getOrLoad(id, null).forChangingLinkage(); _propertyChainDeleter.deletePropertyChain(record, recordChanges.PropertyRecords); DisconnectRelationship(record, recordChanges, locks); UpdateNodesForDeletedRelationship(record, recordChanges, locks); record.InUse = false; }
internal TransactionRecordState(NeoStores neoStores, IntegrityValidator integrityValidator, RecordChangeSet recordChangeSet, long lastCommittedTxWhenTransactionStarted, ResourceLocker locks, RelationshipCreator relationshipCreator, RelationshipDeleter relationshipDeleter, PropertyCreator propertyCreator, PropertyDeleter propertyDeleter) { this._neoStores = neoStores; this._nodeStore = neoStores.NodeStore; this._relationshipStore = neoStores.RelationshipStore; this._propertyStore = neoStores.PropertyStore; this._relationshipGroupStore = neoStores.RelationshipGroupStore; this._metaDataStore = neoStores.MetaDataStore; this._schemaStore = neoStores.SchemaStore; this._integrityValidator = integrityValidator; this._recordChangeSet = recordChangeSet; this._lastCommittedTxWhenTransactionStarted = lastCommittedTxWhenTransactionStarted; this._locks = locks; this._relationshipCreator = relationshipCreator; this._relationshipDeleter = relationshipDeleter; this._propertyCreator = propertyCreator; this._propertyDeleter = propertyDeleter; }
internal Tracker(NeoStores neoStores) { this.Delegate = new DirectRecordAccessSet(neoStores); this.RelRecordsConflict = new TrackingRecordAccess <RelationshipRecord, Void>(Delegate.RelRecords, this); }
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); } } }
/// <summary> /// Creates a relationship with the given id, from the nodes identified by id /// and of type typeId /// </summary> /// <param name="id"> The id of the relationship to create. </param> /// <param name="type"> The id of the relationship type this relationship will /// have. </param> /// <param name="firstNodeId"> The id of the start node. </param> /// <param name="secondNodeId"> The id of the end node. </param> public virtual void RelationshipCreate(long id, int type, long firstNodeId, long secondNodeId, RecordAccessSet recordChangeSet, ResourceLocker locks) { // TODO could be unnecessary to mark as changed here already, dense nodes may not need to change NodeRecord firstNode = recordChangeSet.NodeRecords.getOrLoad(firstNodeId, null).forChangingLinkage(); NodeRecord secondNode = recordChangeSet.NodeRecords.getOrLoad(secondNodeId, null).forChangingLinkage(); ConvertNodeToDenseIfNecessary(firstNode, recordChangeSet.RelRecords, recordChangeSet.RelGroupRecords, locks); ConvertNodeToDenseIfNecessary(secondNode, recordChangeSet.RelRecords, recordChangeSet.RelGroupRecords, locks); RelationshipRecord record = recordChangeSet.RelRecords.create(id, null).forChangingLinkage(); record.SetLinks(firstNodeId, secondNodeId, type); record.InUse = true; record.SetCreated(); ConnectRelationship(firstNode, secondNode, record, recordChangeSet.RelRecords, recordChangeSet.RelGroupRecords, locks); }