public override object Read(IPackStreamReader reader, byte signature, long size) { // List of unique nodes var uniqNodes = new INode[(int)reader.ReadListHeader()]; for (var i = 0; i < uniqNodes.Length; i++) { var node = reader.Read() as INode; Throw.ProtocolException.IfFalse(node != null, "receivedNode"); uniqNodes[i] = node; } // List of unique relationships, without start/end information var uniqRels = new Relationship[(int)reader.ReadListHeader()]; for (var i = 0; i < uniqRels.Length; i++) { var uniqRel = reader.Read() as Relationship; Throw.ProtocolException.IfFalse(uniqRel != null, "receivedUnboundRelationship"); uniqRels[i] = uniqRel; } // Path sequence var length = (int)reader.ReadListHeader(); // Knowing the sequence length, we can create the arrays that will represent the nodes, rels and segments in their "path order" var segments = new ISegment[length / 2]; var nodes = new INode[segments.Length + 1]; var rels = new IRelationship[segments.Length]; var prevNode = uniqNodes[0]; nodes[0] = prevNode; for (var i = 0; i < segments.Length; i++) { var relIdx = (int)reader.ReadLong(); var nextNode = uniqNodes[(int)reader.ReadLong()]; // Start node is always 0, and isn't encoded in the sequence // Negative rel index means this rel was traversed "inversed" from its direction Relationship rel; if (relIdx < 0) { rel = uniqRels[(-relIdx) - 1]; // -1 because rel idx are 1-indexed rel.SetStartAndEnd(nextNode.Id, prevNode.Id); } else { rel = uniqRels[relIdx - 1]; rel.SetStartAndEnd(prevNode.Id, nextNode.Id); } nodes[i + 1] = nextNode; rels[i] = rel; segments[i] = new Segment(prevNode, rel, nextNode); prevNode = nextNode; } return(new Path(segments.ToList(), nodes.ToList(), rels.ToList())); }
private IPath UnpackPath() { // List of unique nodes var uniqNodes = new INode[(int)_unpacker.UnpackListHeader()]; for (int i = 0; i < uniqNodes.Length; i++) { Throw.ArgumentException.IfNotEqual(NodeFields, _unpacker.UnpackStructHeader(), nameof(NodeFields), $"received{nameof(NodeFields)}"); Throw.ArgumentException.IfNotEqual(NODE, _unpacker.UnpackStructSignature(), nameof(NODE), $"received{nameof(NODE)}"); uniqNodes[i] = UnpackNode(); } // List of unique relationships, without start/end information var uniqRels = new Relationship[(int)_unpacker.UnpackListHeader()]; for (int i = 0; i < uniqRels.Length; i++) { Throw.ArgumentException.IfNotEqual(UnboundRelationshipFields, _unpacker.UnpackStructHeader(), nameof(UnboundRelationshipFields), $"received{nameof(UnboundRelationshipFields)}"); Throw.ArgumentException.IfNotEqual(UNBOUND_RELATIONSHIP, _unpacker.UnpackStructSignature(), nameof(UNBOUND_RELATIONSHIP), $"received{nameof(UNBOUND_RELATIONSHIP)}"); var urn = _unpacker.UnpackLong(); var relType = _unpacker.UnpackString(); var props = UnpackMap(); uniqRels[i] = new Relationship(urn, -1, -1, relType, props); } // Path sequence var length = (int)_unpacker.UnpackListHeader(); // Knowing the sequence length, we can create the arrays that will represent the nodes, rels and segments in their "path order" var segments = new ISegment[length / 2]; var nodes = new INode[segments.Length + 1]; var rels = new IRelationship[segments.Length]; var prevNode = uniqNodes[0]; INode nextNode; // Start node is always 0, and isn't encoded in the sequence Relationship rel; nodes[0] = prevNode; for (int i = 0; i < segments.Length; i++) { int relIdx = (int)_unpacker.UnpackLong(); nextNode = uniqNodes[(int)_unpacker.UnpackLong()]; // Negative rel index means this rel was traversed "inversed" from its direction if (relIdx < 0) { rel = uniqRels[(-relIdx) - 1]; // -1 because rel idx are 1-indexed rel.SetStartAndEnd(nextNode.Id, prevNode.Id); } else { rel = uniqRels[relIdx - 1]; rel.SetStartAndEnd(prevNode.Id, nextNode.Id); } nodes[i + 1] = nextNode; rels[i] = rel; segments[i] = new Segment(prevNode, rel, nextNode); prevNode = nextNode; } return(new Path(segments.ToList(), nodes.ToList(), rels.ToList())); }