--- /dev/null
+# 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