/// <summary> /// A label has been changed, figure out what updates are needed to tx state. /// </summary> /// <param name="labelId"> The id of the changed label </param> /// <param name="existingPropertyKeyIds"> all property key ids the node has, sorted by id </param> /// <param name="node"> cursor to the node where the change was applied </param> /// <param name="propertyCursor"> cursor to the properties of node </param> /// <param name="changeType"> The type of change event </param> internal virtual void OnLabelChange(int labelId, int[] existingPropertyKeyIds, NodeCursor node, PropertyCursor propertyCursor, LabelChangeType changeType) { Debug.Assert(NoSchemaChangedInTx()); // Check all indexes of the changed label ICollection <SchemaDescriptor> indexes = _indexingService.getRelatedIndexes(new long[] { labelId }, existingPropertyKeyIds, NODE); if (indexes.Count > 0) { MutableIntObjectMap <Value> materializedProperties = IntObjectMaps.mutable.empty(); foreach (SchemaDescriptor index in indexes) { int[] indexPropertyIds = index.Schema().PropertyIds; Value[] values = GetValueTuple(node, propertyCursor, NO_SUCH_PROPERTY_KEY, NO_VALUE, indexPropertyIds, materializedProperties); switch (changeType) { case Org.Neo4j.Kernel.Impl.Newapi.IndexTxStateUpdater.LabelChangeType.AddedLabel: _indexingService.validateBeforeCommit(index.Schema(), values); _read.txState().indexDoUpdateEntry(index.Schema(), node.NodeReference(), null, ValueTuple.of(values)); break; case Org.Neo4j.Kernel.Impl.Newapi.IndexTxStateUpdater.LabelChangeType.RemovedLabel: _read.txState().indexDoUpdateEntry(index.Schema(), node.NodeReference(), ValueTuple.of(values), null); break; default: throw new System.InvalidOperationException(changeType + " is not a supported event"); } } } }
/// <summary> /// Counts the number of incoming relationships from node where the cursor is positioned. /// <para> /// NOTE: The number of incoming relationships also includes eventual loops. /// /// </para> /// </summary> /// <param name="nodeCursor"> a cursor positioned at the node whose relationships we're counting </param> /// <param name="cursors"> a factory for cursors </param> /// <returns> the number of incoming - including loops - relationships from the node </returns> public static int CountIncoming(NodeCursor nodeCursor, CursorFactory cursors) { if (nodeCursor.Dense) { using (RelationshipGroupCursor group = cursors.AllocateRelationshipGroupCursor()) { nodeCursor.Relationships(group); int count = 0; while (group.next()) { count += group.IncomingCount() + group.LoopCount(); } return(count); } } else { using (RelationshipTraversalCursor traversal = cursors.AllocateRelationshipTraversalCursor()) { int count = 0; nodeCursor.AllRelationships(traversal); while (traversal.next()) { if (traversal.TargetNodeReference() == nodeCursor.NodeReference()) { count++; } } return(count); } } }
/// <summary> /// Counts the number of outgoing relationships of the given type from node where the cursor is positioned. /// <para> /// NOTE: The number of outgoing relationships also includes eventual loops. /// /// </para> /// </summary> /// <param name="nodeCursor"> a cursor positioned at the node whose relationships we're counting </param> /// <param name="cursors"> a factory for cursors </param> /// <param name="type"> the type of the relationship we're counting </param> /// <returns> the number of outgoing - including loops - relationships from the node with the given type </returns> public static int CountOutgoing(NodeCursor nodeCursor, CursorFactory cursors, int type) { if (nodeCursor.Dense) { using (RelationshipGroupCursor group = cursors.AllocateRelationshipGroupCursor()) { nodeCursor.Relationships(group); while (group.next()) { if (group.Type() == type) { return(group.OutgoingCount() + group.LoopCount()); } } return(0); } } else { using (RelationshipTraversalCursor traversal = cursors.AllocateRelationshipTraversalCursor()) { int count = 0; nodeCursor.AllRelationships(traversal); while (traversal.next()) { if (traversal.SourceNodeReference() == nodeCursor.NodeReference() && traversal.Type() == type) { count++; } } return(count); } } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldTraverseRelationshipsOfGivenType() public virtual void ShouldTraverseRelationshipsOfGivenType() { // given using (NodeCursor node = cursors.allocateNodeCursor(), RelationshipGroupCursor group = cursors.allocateRelationshipGroupCursor(), RelationshipTraversalCursor relationship = cursors.allocateRelationshipTraversalCursor()) { int empty = 0; // when read.allNodesScan(node); while (node.Next()) { node.Relationships(group); bool none = true; while (group.next()) { none = false; Sizes degree = new Sizes(); group.Outgoing(relationship); while (relationship.next()) { assertEquals("node #" + node.NodeReference() + " relationship should have same label as group", group.Type(), relationship.Type()); degree.Outgoing++; } group.Incoming(relationship); while (relationship.next()) { assertEquals("node #" + node.NodeReference() + "relationship should have same label as group", group.Type(), relationship.Type()); degree.Incoming++; } group.Loops(relationship); while (relationship.next()) { assertEquals("node #" + node.NodeReference() + "relationship should have same label as group", group.Type(), relationship.Type()); degree.Loop++; } // then assertNotEquals("all", 0, degree.Incoming + degree.Outgoing + degree.Loop); assertEquals("node #" + node.NodeReference() + " outgoing", group.OutgoingCount(), degree.Outgoing); assertEquals("node #" + node.NodeReference() + " incoming", group.IncomingCount(), degree.Incoming); assertEquals("node #" + node.NodeReference() + " loop", group.LoopCount(), degree.Loop); assertEquals("node #" + node.NodeReference() + " all = incoming + outgoing - loop", group.TotalCount(), degree.Incoming + degree.Outgoing + degree.Loop); } if (none) { empty++; } } // then assertEquals("number of empty nodes", 1, empty); } }
internal virtual void OnPropertyRemove(NodeCursor node, PropertyCursor propertyCursor, long[] labels, int propertyKeyId, int[] existingPropertyKeyIds, Value value) { Debug.Assert(NoSchemaChangedInTx()); ICollection <SchemaDescriptor> indexes = _indexingService.getRelatedIndexes(labels, propertyKeyId, NODE); if (indexes.Count > 0) { MutableIntObjectMap <Value> materializedProperties = IntObjectMaps.mutable.empty(); NodeSchemaMatcher.OnMatchingSchema(indexes.GetEnumerator(), propertyKeyId, existingPropertyKeyIds, index => { Value[] values = GetValueTuple(node, propertyCursor, propertyKeyId, value, index.schema().PropertyIds, materializedProperties); _read.txState().indexDoUpdateEntry(index.schema(), node.NodeReference(), ValueTuple.of(values), null); }); } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldAccessNodesByReference() public virtual void ShouldAccessNodesByReference() { // given using (NodeCursor nodes = cursors.allocateNodeCursor()) { foreach (long id in _nodeIds) { // when read.singleNode(id, nodes); // then assertTrue("should access defined node", nodes.Next()); assertEquals("should access the correct node", id, nodes.NodeReference()); assertFalse("should only access a single node", nodes.Next()); } } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldScanNodes() public virtual void ShouldScanNodes() { // given IList <long> ids = new List <long>(); using (NodeCursor nodes = cursors.allocateNodeCursor()) { // when read.allNodesScan(nodes); while (nodes.Next()) { ids.Add(nodes.NodeReference()); } } // then assertEquals(_nodeIds, ids); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldNotAccessNonExistentProperties() public virtual void ShouldNotAccessNonExistentProperties() { // given using (NodeCursor node = cursors.allocateNodeCursor(), PropertyCursor props = cursors.allocatePropertyCursor()) { // when read.singleNode(_bare, node); assertTrue("node by reference", node.Next()); assertFalse("no properties", HasProperties(node, props)); node.Properties(props); assertFalse("no properties by direct method", props.Next()); read.nodeProperties(node.NodeReference(), node.PropertiesReference(), props); assertFalse("no properties via property ref", props.Next()); assertFalse("only one node", node.Next()); } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void shouldSeeNodeInTransaction() throws Exception //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: public virtual void ShouldSeeNodeInTransaction() { long nodeId; using (Transaction tx = beginTransaction()) { nodeId = tx.DataWrite().nodeCreate(); using (NodeCursor node = tx.Cursors().allocateNodeCursor()) { tx.DataRead().singleNode(nodeId, node); assertTrue("should access node", node.Next()); assertEquals(nodeId, node.NodeReference()); assertFalse("should only find one node", node.Next()); } tx.Success(); } using (Org.Neo4j.Graphdb.Transaction ignore = graphDb.beginTx()) { assertEquals(nodeId, graphDb.getNodeById(nodeId).Id); } }
private void AssertAccessSingleProperty(long nodeId, object expectedValue, ValueGroup expectedValueType) { // given using (NodeCursor node = cursors.allocateNodeCursor(), PropertyCursor props = cursors.allocatePropertyCursor()) { // when read.singleNode(nodeId, node); assertTrue("node by reference", node.Next()); assertTrue("has properties", HasProperties(node, props)); node.Properties(props); assertTrue("has properties by direct method", props.Next()); assertEquals("correct value", expectedValue, props.PropertyValue()); assertEquals("correct value type ", expectedValueType, props.PropertyType()); assertFalse("single property", props.Next()); read.nodeProperties(node.NodeReference(), node.PropertiesReference(), props); assertTrue("has properties via property ref", props.Next()); assertEquals("correct value", expectedValue, props.PropertyValue()); assertFalse("single property", props.Next()); } }
internal virtual void OnPropertyChange(NodeCursor node, PropertyCursor propertyCursor, long[] labels, int propertyKeyId, int[] existingPropertyKeyIds, Value beforeValue, Value afterValue) { Debug.Assert(NoSchemaChangedInTx()); ICollection <SchemaDescriptor> indexes = _indexingService.getRelatedIndexes(labels, propertyKeyId, NODE); if (indexes.Count > 0) { MutableIntObjectMap <Value> materializedProperties = IntObjectMaps.mutable.empty(); NodeSchemaMatcher.OnMatchingSchema(indexes.GetEnumerator(), propertyKeyId, existingPropertyKeyIds, index => { int[] propertyIds = index.PropertyIds; Value[] valuesAfter = GetValueTuple(node, propertyCursor, propertyKeyId, afterValue, propertyIds, materializedProperties); // The valuesBefore tuple is just like valuesAfter, except is has the afterValue instead of the beforeValue Value[] valuesBefore = valuesAfter.Clone(); int k = ArrayUtils.IndexOf(propertyIds, propertyKeyId); valuesBefore[k] = beforeValue; _indexingService.validateBeforeCommit(index, valuesAfter); _read.txState().indexDoUpdateEntry(index, node.NodeReference(), ValueTuple.of(valuesBefore), ValueTuple.of(valuesAfter)); }); } }