//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: private org.neo4j.kernel.impl.store.record.RelationshipGroupRecord readRelationshipGroupRecord(long id, org.neo4j.storageengine.api.ReadableChannel channel) throws java.io.IOException private RelationshipGroupRecord ReadRelationshipGroupRecord(long id, ReadableChannel channel) { sbyte flags = channel.Get(); bool inUse = bitFlag(flags, Record.IN_USE.byteValue()); bool requireSecondaryUnit = bitFlag(flags, Record.REQUIRE_SECONDARY_UNIT); bool hasSecondaryUnit = bitFlag(flags, Record.HAS_SECONDARY_UNIT); bool usesFixedReferenceFormat = bitFlag(flags, Record.USES_FIXED_REFERENCE_FORMAT); int type = unsignedShortToInt(channel.Short); RelationshipGroupRecord record = new RelationshipGroupRecord(id, type); record.InUse = inUse; record.Next = channel.Long; record.FirstOut = channel.Long; record.FirstIn = channel.Long; record.FirstLoop = channel.Long; record.OwningNode = channel.Long; record.RequiresSecondaryUnit = requireSecondaryUnit; if (hasSecondaryUnit) { record.SecondaryUnitId = channel.Long; } record.UseFixedReferences = usesFixedReferenceFormat; return(record); }
private void MarkRandomRelsInGroupNotInUse(long nodeId, TestRelType type) { NodeRecord node = GetNodeRecord(nodeId); assertTrue(node.Dense); long relGroupId = node.NextRel; while (relGroupId != NO_NEXT_RELATIONSHIP.intValue()) { RelationshipGroupRecord relGroup = GetRelGroupRecord(relGroupId); if (type == RelTypeForId(relGroup.Type)) { MarkRandomRelsInChainNotInUse(relGroup.FirstOut); MarkRandomRelsInChainNotInUse(relGroup.FirstIn); MarkRandomRelsInChainNotInUse(relGroup.FirstLoop); return; } relGroupId = relGroup.Next; } throw new System.InvalidOperationException("No relationship group with type: " + type + " found"); }
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)); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void useVariableLengthFormatWhenOneOfTheReferencesReferenceTooBig() throws java.io.IOException //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void UseVariableLengthFormatWhenOneOfTheReferencesReferenceTooBig() { RelationshipGroupRecord source = new RelationshipGroupRecord(1); RelationshipGroupRecord target = new RelationshipGroupRecord(1); VerifyRecordsWithPoisonedReference(source, target, 1L << ((sizeof(int) * 8) + 2)); }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: private void verifyRecordsWithPoisonedReference(org.neo4j.kernel.impl.store.record.RelationshipGroupRecord source, org.neo4j.kernel.impl.store.record.RelationshipGroupRecord target, long poisonedReference) throws java.io.IOException private void VerifyRecordsWithPoisonedReference(RelationshipGroupRecord source, RelationshipGroupRecord target, long poisonedReference) { bool nullPoisoned = poisonedReference == BaseHighLimitRecordFormat.Null; int differentReferences = 5; IList <long> references = BuildReferenceList(differentReferences, poisonedReference); for (int i = 0; i < differentReferences; i++) { _pageCursor.Offset = 0; IEnumerator <long> iterator = references.GetEnumerator(); //JAVA TO C# CONVERTER TODO TASK: Java iterators are only converted within the context of 'while' and 'for' loops: source.Initialize(true, 0, iterator.next(), iterator.next(), iterator.next(), iterator.next(), iterator.next()); WriteReadRecord(source, target); if (nullPoisoned) { assertTrue("Record should use fixed reference format.", target.UseFixedReferences); } else { assertFalse("Record should use variable length reference format.", target.UseFixedReferences); } VerifySame(source, target); Collections.rotate(references, 1); } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void useFixedReferenceFormatWhenOneOfTheReferencesIsMissing() throws java.io.IOException //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void UseFixedReferenceFormatWhenOneOfTheReferencesIsMissing() { RelationshipGroupRecord source = new RelationshipGroupRecord(1); RelationshipGroupRecord target = new RelationshipGroupRecord(1); VerifyRecordsWithPoisonedReference(source, target, NULL); }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: private void writeReadRecord(org.neo4j.kernel.impl.store.record.RelationshipGroupRecord source, org.neo4j.kernel.impl.store.record.RelationshipGroupRecord target, int recordSize) throws java.io.IOException private void WriteReadRecord(RelationshipGroupRecord source, RelationshipGroupRecord target, int recordSize) { _recordFormat.prepare(source, recordSize, _idSequence); _recordFormat.write(source, _pageCursor, recordSize); _pageCursor.Offset = 0; _recordFormat.read(target, _pageCursor, RecordLoad.NORMAL, recordSize); }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: private Command visitRelationshipGroupCommand(org.neo4j.storageengine.api.ReadableChannel channel) throws java.io.IOException private Command VisitRelationshipGroupCommand(ReadableChannel channel) { long id = channel.Long; RelationshipGroupRecord before = ReadRelationshipGroupRecord(id, channel); RelationshipGroupRecord after = ReadRelationshipGroupRecord(id, channel); return(new Command.RelationshipGroupCommand(before, after)); }
public static RelationshipGroupCommand CreateRelationshipGroup(long id, int type) { RelationshipGroupRecord before = new RelationshipGroupRecord(id); RelationshipGroupRecord after = new RelationshipGroupRecord(id, type); after.InUse = true; after.SetCreated(); return(new RelationshipGroupCommand(before, after)); }
public static RecordChangeSet NewChangeSet(params AbstractBaseRecord[] records) { return(new RecordChangeSet(new Loader(FilterType(records, typeof(NodeRecord)).collect(Collectors.toList()), (System.Func <long, object, NodeRecord>)(key, extra) => new NodeRecord(key)), null, new Loader(FilterType(records, typeof(RelationshipRecord)).collect(Collectors.toList()), (System.Func <long, object, RelationshipRecord>)(key, extra) => new RelationshipRecord(key)), new Loader(FilterType(records, typeof(RelationshipGroupRecord)).collect(Collectors.toList()), (System.Func <long, int, RelationshipGroupRecord>)(key, extra) => { RelationshipGroupRecord group = new RelationshipGroupRecord(key); group.Type = extra; return group; }), null, null, null, null)); }
private void ConnectRelationshipToDenseNode(NodeRecord node, RelationshipRecord rel, RecordAccess <RelationshipRecord, Void> relRecords, RecordAccess <RelationshipGroupRecord, int> relGroupRecords, ResourceLocker locks) { RelationshipGroupRecord group = _relGroupGetter.getOrCreateRelationshipGroup(node, rel.Type, relGroupRecords).forChangingData(); DirectionWrapper dir = DirectionIdentifier.wrapDirection(rel, node); long nextRel = dir.getNextRel(group); SetCorrectNextRel(node, rel, nextRel); Connect(node.Id, nextRel, rel, relRecords, locks); dir.setNextRel(group, rel.Id); }
private void VerifySame(RelationshipGroupRecord recordA, RelationshipGroupRecord recordB) { assertEquals("Types should be equal.", recordA.Type, recordB.Type); assertEquals("First In references should be equal.", recordA.FirstIn, recordB.FirstIn); assertEquals("First Loop references should be equal.", recordA.FirstLoop, recordB.FirstLoop); assertEquals("First Out references should be equal.", recordA.FirstOut, recordB.FirstOut); assertEquals("Next references should be equal.", recordA.Next, recordB.Next); assertEquals("Prev references should be equal.", recordA.Prev, recordB.Prev); assertEquals("Owning node references should be equal.", recordA.OwningNode, recordB.OwningNode); }
public static RelationshipGroupRecord RelGroup(long id, params System.Action <RelationshipGroupRecord>[] modifiers) { RelationshipGroupRecord record = new RelationshipGroupRecord(id); record.Initialize(true, 0, Record.NO_NEXT_RELATIONSHIP.longValue(), Record.NO_NEXT_RELATIONSHIP.longValue(), Record.NO_NEXT_RELATIONSHIP.longValue(), -1, Record.NO_NEXT_RELATIONSHIP.longValue()); foreach (System.Action <RelationshipGroupRecord> modifier in modifiers) { modifier(record); } return(record); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void readWriteFixedReferencesRecord() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ReadWriteFixedReferencesRecord() { RelationshipGroupRecord source = new RelationshipGroupRecord(1); RelationshipGroupRecord target = new RelationshipGroupRecord(1); source.Initialize(true, RandomType(), RandomFixedReference(), RandomFixedReference(), RandomFixedReference(), RandomFixedReference(), RandomFixedReference()); WriteReadRecord(source, target); assertTrue("Record should use fixed reference format.", target.UseFixedReferences); VerifySame(source, target); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void useFixedReferenceFormatWhenRecordCanFitInRecordSizeRecord() throws java.io.IOException //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void UseFixedReferenceFormatWhenRecordCanFitInRecordSizeRecord() { RelationshipGroupRecord source = new RelationshipGroupRecord(1); RelationshipGroupRecord target = new RelationshipGroupRecord(1); source.Initialize(true, RandomType(), RandomFixedReference(), RandomFixedReference(), RandomFixedReference(), RandomFixedReference(), RandomFixedReference()); WriteReadRecord(source, target, RelationshipGroupRecordFormat.FixedFormatRecordSize); assertTrue("Record should use fixed reference if can fit in format record.", target.UseFixedReferences); VerifySame(source, target); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void useVariableLengthFormatWhenRecordSizeIsTooSmall() throws java.io.IOException //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void UseVariableLengthFormatWhenRecordSizeIsTooSmall() { RelationshipGroupRecord source = new RelationshipGroupRecord(1); RelationshipGroupRecord target = new RelationshipGroupRecord(1); source.Initialize(true, RandomType(), RandomFixedReference(), RandomFixedReference(), RandomFixedReference(), RandomFixedReference(), RandomFixedReference()); WriteReadRecord(source, target, RelationshipGroupRecordFormat.FixedFormatRecordSize - 1); assertFalse("Record should use variable length reference if format record is too small.", target.UseFixedReferences); VerifySame(source, target); }
private void AssertBatch(RelationshipGroupRecord[] batch, long lastOwningNodeLastBatch) { for (int i = 0; i < batch.Length; i++) { RelationshipGroupRecord record = batch[i]; assertTrue(record.Id > Record.NULL_REFERENCE.longValue()); assertTrue(record.OwningNode > lastOwningNodeLastBatch); assertEquals(1, record.FirstOut); // the mark our store mock sets when preparing if (record.Next == Record.NULL_REFERENCE.longValue()) { // This is the last in the chain, verify that this is either: assertTrue(i == batch.Length - 1 || batch[i + 1].OwningNode > record.OwningNode); } } }
protected internal static IList <RelationshipGroupRecord> Groups(params Group[] groups) { IList <RelationshipGroupRecord> records = new List <RelationshipGroupRecord>(); foreach (Group group in groups) { for (int i = 0; i < group.Count; i++) { RelationshipGroupRecord record = new RelationshipGroupRecord(NULL_REFERENCE.longValue()); record.OwningNode = group.OwningNode; record.Next = group.Count - i - 1; // count: how many come after it (importer does this) records.Add(record); } } return(records); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldDefragmentRelationshipGroupsWhenSomeDense() public virtual void ShouldDefragmentRelationshipGroupsWhenSomeDense() { // GIVEN some nodes which has their groups scattered int nodeCount = 100; int relationshipTypeCount = 50; RecordStore <RelationshipGroupRecord> groupStore = _stores.TemporaryRelationshipGroupStore; RelationshipGroupRecord groupRecord = groupStore.NewRecord(); RecordStore <NodeRecord> nodeStore = _stores.NodeStore; NodeRecord nodeRecord = nodeStore.NewRecord(); long cursor = 0; BitArray initializedNodes = new BitArray(); for (int typeId = relationshipTypeCount - 1; typeId >= 0; typeId--) { for (int nodeId = 0; nodeId < nodeCount; nodeId++, cursor++) { // Reasoning behind this thing is that we want to have roughly 10% of the nodes dense // right from the beginning and then some stray dense nodes coming into this in the // middle of the type range somewhere double comparison = typeId == 0 || initializedNodes.Get(nodeId) ? 0.1 : 0.001; if (_random.NextDouble() < comparison) { // next doesn't matter at all, as we're rewriting it anyway // firstOut/In/Loop we could use in verification phase later groupRecord.Initialize(true, typeId, cursor, cursor + 1, cursor + 2, nodeId, 4); groupRecord.Id = groupStore.nextId(); groupStore.UpdateRecord(groupRecord); if (!initializedNodes.Get(nodeId)) { nodeRecord.Initialize(true, -1, true, groupRecord.Id, 0); nodeRecord.Id = nodeId; nodeStore.UpdateRecord(nodeRecord); nodeStore.HighestPossibleIdInUse = nodeId; initializedNodes.Set(nodeId, true); } } } } // WHEN Defrag(nodeCount, groupStore); // THEN all groups should sit sequentially in the store VerifyGroupsAreSequentiallyOrderedByNode(); }
private void VerifyGroupsAreSequentiallyOrderedByNode() { RelationshipGroupStore store = _stores.RelationshipGroupStore; long firstId = store.NumberOfReservedLowIds; long groupCount = store.HighId - firstId; RelationshipGroupRecord groupRecord = store.NewRecord(); PageCursor groupCursor = store.OpenPageCursorForReading(firstId); long highGroupId = store.HighId; long currentNodeId = -1; int currentTypeId = -1; int newGroupCount = 0; int currentGroupLength = 0; for (long id = firstId; id < highGroupId; id++, newGroupCount++) { store.GetRecordByCursor(id, groupRecord, CHECK, groupCursor); if (!groupRecord.InUse()) { // This will be the case if we have double record units, just assert that fact assertTrue(Units > 1); assertTrue(currentGroupLength > 0); currentGroupLength--; continue; } long nodeId = groupRecord.OwningNode; assertTrue("Expected a group for node >= " + currentNodeId + ", but was " + nodeId + " in " + groupRecord, nodeId >= currentNodeId); if (nodeId != currentNodeId) { currentNodeId = nodeId; currentTypeId = -1; if (Units > 1) { assertEquals(0, currentGroupLength); } currentGroupLength = 0; } currentGroupLength++; assertTrue("Expected this group to have a next of current + " + Units + " OR NULL, " + "but was " + groupRecord.ToString(), groupRecord.Next == groupRecord.Id + 1 || groupRecord.Next == Record.NO_NEXT_RELATIONSHIP.intValue()); assertTrue("Expected " + groupRecord + " to have type > " + currentTypeId, groupRecord.Type > currentTypeId); currentTypeId = groupRecord.Type; } assertEquals(groupCount, newGroupCount); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldReadUnsignedRelationshipTypeId() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldReadUnsignedRelationshipTypeId() { // GIVEN using (PageCursor cursor = new StubPageCursor(1, _recordSize * 10)) { int offset = 10; cursor.Next(); RelationshipGroupRecord group = (new RelationshipGroupRecord(2)).initialize(true, short.MaxValue + offset, 1, 2, 3, 4, 5); cursor.Offset = offset; _format.write(group, cursor, _recordSize); // WHEN RelationshipGroupRecord read = new RelationshipGroupRecord(group.Id); cursor.Offset = offset; _format.read(read, cursor, NORMAL, _recordSize); // THEN assertEquals(group, read); } }
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; }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: private Command visitRelationshipGroupCommand(org.neo4j.storageengine.api.ReadableChannel channel) throws java.io.IOException private Command VisitRelationshipGroupCommand(ReadableChannel channel) { long id = channel.Long; sbyte inUseByte = channel.Get(); bool inUse = inUseByte == Record.IN_USE.byteValue(); if (inUseByte != Record.IN_USE.byteValue() && inUseByte != Record.NOT_IN_USE.byteValue()) { throw new IOException("Illegal in use flag: " + inUseByte); } int type = unsignedShortToInt(channel.Short); RelationshipGroupRecord record = new RelationshipGroupRecord(id, type); record.InUse = inUse; record.Next = channel.Long; record.FirstOut = channel.Long; record.FirstIn = channel.Long; record.FirstLoop = channel.Long; record.OwningNode = channel.Long; return(new Command.RelationshipGroupCommand(null, record)); }
protected internal override object NextBatchOrNull(long ticket, int batchSize) { //JAVA TO C# CONVERTER TODO TASK: Java iterators are only converted within the context of 'while' and 'for' loops: if (!_data.hasNext()) { return(null); } int i = 0; long lastOwner = -1; for ( ; _data.MoveNext(); 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.OwningNode; } else if (i >= batchSize) { // ...and continue including groups in this batch until next owner comes if (item.OwningNode != lastOwner) { break; } } if (i >= _scratch.Length) { _scratch = Arrays.copyOf(_scratch, _scratch.Length * 2); } _scratch[i] = _data.Current; // which is "item", but also advances the iterator _cursor++; } return(Arrays.copyOf(_scratch, i)); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldDefragmentRelationshipGroupsWhenAllDense() public virtual void ShouldDefragmentRelationshipGroupsWhenAllDense() { // GIVEN some nodes which has their groups scattered int nodeCount = 100; int relationshipTypeCount = 50; RecordStore <RelationshipGroupRecord> groupStore = _stores.TemporaryRelationshipGroupStore; RelationshipGroupRecord groupRecord = groupStore.NewRecord(); RecordStore <NodeRecord> nodeStore = _stores.NodeStore; NodeRecord nodeRecord = nodeStore.NewRecord(); long cursor = 0; for (int typeId = relationshipTypeCount - 1; typeId >= 0; typeId--) { for (long nodeId = 0; nodeId < nodeCount; nodeId++, cursor++) { // next doesn't matter at all, as we're rewriting it anyway // firstOut/In/Loop we could use in verification phase later groupRecord.Initialize(true, typeId, cursor, cursor + 1, cursor + 2, nodeId, 4); groupRecord.Id = groupStore.nextId(); groupStore.UpdateRecord(groupRecord); if (typeId == 0) { // first round also create the nodes nodeRecord.Initialize(true, -1, true, groupRecord.Id, 0); nodeRecord.Id = nodeId; nodeStore.UpdateRecord(nodeRecord); nodeStore.HighestPossibleIdInUse = nodeId; } } } // WHEN Defrag(nodeCount, groupStore); // THEN all groups should sit sequentially in the store VerifyGroupsAreSequentiallyOrderedByNode(); }
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); }
protected internal override void Process(RelationshipGroupRecord[] batch, BatchSender sender) { int groupStartIndex = 0; for (int i = 0; i < batch.Length; i++) { RelationshipGroupRecord group = batch[i]; // The iterator over the groups will not produce real next pointers, they are instead // a count meaning how many groups come after it. This encoder will set the real group ids. long count = group.Next; bool lastInChain = count == 0; group.Id = _nextId == -1 ? _nextId = _store.nextId() : _nextId; if (!lastInChain) { group.Next = _nextId = _store.nextId(); } else { group.Next = _nextId = -1; // OK so this group is the last in this chain, which means all the groups in this chain // are now fully populated. We can now prepare these groups so that their potential // secondary units ends up very close by. for (int j = groupStartIndex; j <= i; j++) { _store.prepareForCommit(batch[j]); } groupStartIndex = i + 1; } } Debug.Assert(groupStartIndex == batch.Length); sender.Send(batch); }
private void MarkRelGroupNotInUse(long nodeId, params TestRelType[] types) { NodeRecord node = GetNodeRecord(nodeId); assertTrue(node.Dense); ISet <TestRelType> typesToRemove = asSet(types); long relGroupId = node.NextRel; while (relGroupId != NO_NEXT_RELATIONSHIP.intValue()) { RelationshipGroupRecord relGroup = GetRelGroupRecord(relGroupId); TestRelType type = RelTypeForId(relGroup.Type); if (typesToRemove.Contains(type)) { relGroup.InUse = false; Update(relGroup); } relGroupId = relGroup.Next; } }
private bool GroupIsEmpty(RelationshipGroupRecord group) { return(group.FirstOut == Record.NO_NEXT_RELATIONSHIP.intValue() && group.FirstIn == Record.NO_NEXT_RELATIONSHIP.intValue() && group.FirstLoop == Record.NO_NEXT_RELATIONSHIP.intValue()); }
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); } } }