neo4j/graph: Add a sequential identification scheme.
authorJean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
Sat, 20 Dec 2014 19:27:30 +0000 (14:27 -0500)
committerJean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
Mon, 29 Dec 2014 20:53:44 +0000 (15:53 -0500)
Signed-off-by: Jean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>

lib/neo4j/graph/sequential_id.nit [new file with mode: 0644]

diff --git a/lib/neo4j/graph/sequential_id.nit b/lib/neo4j/graph/sequential_id.nit
new file mode 100644 (file)
index 0000000..3b3559a
--- /dev/null
@@ -0,0 +1,79 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# This file is free software, which comes along with NIT. This software is
+# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. You can modify it is you want, provided this header
+# is kept unaltered, and a notification of the changes is added.
+# You are allowed to redistribute it and sell it, alone or is a part of
+# another product.
+
+# Provides a sequential identification scheme for Neo4j nodes.
+module neo4j::graph::sequential_id
+
+import graph
+private import pipeline
+
+
+# A Neo4j node collection using a sequential identification scheme.
+#
+# The local IDs are sequential numbers (integers) starting at `1`.
+#
+# Note: When loading nodes, the local IDs should forms a mostly contiguous
+# range starting at `1`. Else, this collection will consume a lot of memory.
+# Futhermore, the local IDs **must** be positive.
+#
+# ~~~nit
+# var nodes = new SequentialNodeCollection("id")
+# var a = nodes.create_node
+# var b = new NeoNode
+# var c = new NeoNode
+#
+# nodes.register b
+# c["id"] = 4
+# nodes.add c
+# assert a["id"] == 1
+# assert b["id"] == 2
+# assert c["id"] == 4
+# assert nodes.to_a == [a, b, c]
+# ~~~
+class SequentialNodeCollection
+       super NeoNodeCollection
+
+       redef type ID_TYPE: Int
+
+       private var nodes = new Array[nullable NeoNode]
+
+       redef fun iterator do return new NullSkipper[NeoNode](self.nodes.iterator)
+
+       redef fun get_or_null(id) do
+               if id < 0 or id > nodes.length then return null
+               return nodes[id]
+       end
+
+       redef fun register(node) do
+               nodes.add node
+               id_of(node) = nodes.length
+       end
+
+       redef fun add(node) do
+               var id = node[id_property]
+               assert id isa Int else
+                       sys.stderr.write "The local ID must be an `Int`.\n"
+               end
+               assert id >= 0 else
+                       sys.stderr.write "The local ID must be greater or equal to 0. Got {id}.\n"
+               end
+               # Pad with nulls.
+               var delta = id - nodes.length
+               while delta > 0 do
+                       nodes.add null
+                       delta -= 1
+               end
+               nodes[id] = node
+       end
+
+       redef fun remove_at(id) do
+               nodes[id] = null
+       end
+end