Skip to content

Commit 0c35b4e

Browse files
committed
feat: add set_max_node_id, tests
1 parent 430721c commit 0c35b4e

File tree

4 files changed

+98
-0
lines changed

4 files changed

+98
-0
lines changed

kvdbclient/attributes.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,13 @@ class Connectivity:
132132
serializer=serializers.NumPyArray(dtype=basetypes.NODE_ID, shape=(-1, 2)),
133133
)
134134

135+
# new edges as a result of supervoxel split
136+
SplitEdges = _Attribute(
137+
key=b"split_edges",
138+
family_id="4",
139+
serializer=serializers.NumPyArray(dtype=basetypes.NODE_ID, shape=(-1, 2)),
140+
)
141+
135142

136143
class Hierarchy:
137144
Child = _Attribute(
@@ -166,6 +173,18 @@ class Hierarchy:
166173
key=b"stale_ts", family_id="3", serializer=serializers.Pickle()
167174
)
168175

176+
FormerIdentity = _Attribute(
177+
key=b"former_ids",
178+
family_id="0",
179+
serializer=serializers.NumPyArray(dtype=basetypes.NODE_ID),
180+
)
181+
182+
NewIdentity = _Attribute(
183+
key=b"new_ids",
184+
family_id="0",
185+
serializer=serializers.NumPyArray(dtype=basetypes.NODE_ID),
186+
)
187+
169188

170189
class TableMeta:
171190
key = b"meta"

kvdbclient/base.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,13 @@ def create_node_id(
541541
) -> basetypes.NODE_ID:
542542
return self.create_node_ids(chunk_id, 1, root_chunk=root_chunk)[0]
543543

544+
def set_max_node_id(
545+
self, chunk_id: np.uint64, node_id: np.uint64
546+
) -> None:
547+
"""Set max segment ID for a given chunk."""
548+
size = int(np.uint64(chunk_id) ^ np.uint64(node_id))
549+
self._get_ids_range(serialize_uint64(chunk_id, counter=True), size)
550+
544551
def get_max_node_id(
545552
self, chunk_id: basetypes.CHUNK_ID, root_chunk=False
546553
) -> basetypes.NODE_ID:

tests/test_bigtable_client.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,42 @@ def test_get_max_node_id(self, bt_client):
400400
max_id = bt_client.get_max_node_id(chunk_id)
401401
assert max_id > chunk_id
402402

403+
def test_set_max_node_id_fresh(self, bt_client):
404+
"""On a fresh counter, set_max_node_id sets the counter to the segment ID."""
405+
chunk_id = np.uint64(1 << 32)
406+
node_id = chunk_id | np.uint64(10)
407+
bt_client.set_max_node_id(chunk_id, node_id)
408+
max_id = bt_client.get_max_node_id(chunk_id)
409+
assert max_id == node_id
410+
411+
def test_set_max_node_id_then_create_no_collision(self, bt_client):
412+
"""After set_max_node_id, create_node_id should return IDs above the set max."""
413+
chunk_id = np.uint64(1 << 32)
414+
node_id = chunk_id | np.uint64(10)
415+
bt_client.set_max_node_id(chunk_id, node_id)
416+
new_id = bt_client.create_node_id(chunk_id)
417+
segment_id = int(np.uint64(new_id) ^ np.uint64(chunk_id))
418+
assert segment_id > 10
419+
420+
def test_set_max_node_id_is_additive(self, bt_client):
421+
"""Calling set_max_node_id twice increments cumulatively (not idempotent)."""
422+
chunk_id = np.uint64(1 << 32)
423+
node_id = chunk_id | np.uint64(5)
424+
bt_client.set_max_node_id(chunk_id, node_id)
425+
bt_client.set_max_node_id(chunk_id, node_id)
426+
max_id = bt_client.get_max_node_id(chunk_id)
427+
# Counter was incremented by 5 twice -> segment_id is 10
428+
assert int(np.uint64(max_id) ^ np.uint64(chunk_id)) == 10
429+
430+
def test_set_max_node_id_after_create(self, bt_client):
431+
"""set_max_node_id after create_node_ids advances counter further."""
432+
chunk_id = np.uint64(1 << 32)
433+
bt_client.create_node_ids(chunk_id, 3) # counter at 3
434+
node_id = chunk_id | np.uint64(7)
435+
bt_client.set_max_node_id(chunk_id, node_id) # increments by 7 -> counter at 10
436+
max_id = bt_client.get_max_node_id(chunk_id)
437+
assert int(np.uint64(max_id) ^ np.uint64(chunk_id)) == 10
438+
403439

404440
class TestOperationIds:
405441
def test_create_unique(self, bt_client):

tests/test_hbase_client.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,42 @@ def test_create_batch(self, hbase_client):
405405
assert len(ids) == 5
406406
assert len(np.unique(ids)) == 5
407407

408+
def test_set_max_node_id_fresh(self, hbase_client):
409+
"""On a fresh counter, set_max_node_id sets the counter to the segment ID."""
410+
chunk_id = np.uint64(1 << 32)
411+
node_id = chunk_id | np.uint64(10)
412+
hbase_client.set_max_node_id(chunk_id, node_id)
413+
max_id = hbase_client.get_max_node_id(chunk_id)
414+
assert max_id == node_id
415+
416+
def test_set_max_node_id_then_create_no_collision(self, hbase_client):
417+
"""After set_max_node_id, create_node_id should return IDs above the set max."""
418+
chunk_id = np.uint64(1 << 32)
419+
node_id = chunk_id | np.uint64(10)
420+
hbase_client.set_max_node_id(chunk_id, node_id)
421+
new_id = hbase_client.create_node_id(chunk_id)
422+
segment_id = int(np.uint64(new_id) ^ np.uint64(chunk_id))
423+
assert segment_id > 10
424+
425+
def test_set_max_node_id_is_additive(self, hbase_client):
426+
"""Calling set_max_node_id twice increments cumulatively (not idempotent)."""
427+
chunk_id = np.uint64(1 << 32)
428+
node_id = chunk_id | np.uint64(5)
429+
hbase_client.set_max_node_id(chunk_id, node_id)
430+
hbase_client.set_max_node_id(chunk_id, node_id)
431+
max_id = hbase_client.get_max_node_id(chunk_id)
432+
# Counter was incremented by 5 twice -> segment_id is 10
433+
assert int(np.uint64(max_id) ^ np.uint64(chunk_id)) == 10
434+
435+
def test_set_max_node_id_after_create(self, hbase_client):
436+
"""set_max_node_id after create_node_ids advances counter further."""
437+
chunk_id = np.uint64(1 << 32)
438+
hbase_client.create_node_ids(chunk_id, 3) # counter at 3
439+
node_id = chunk_id | np.uint64(7)
440+
hbase_client.set_max_node_id(chunk_id, node_id) # increments by 7 -> counter at 10
441+
max_id = hbase_client.get_max_node_id(chunk_id)
442+
assert int(np.uint64(max_id) ^ np.uint64(chunk_id)) == 10
443+
408444

409445
class TestHBaseOperationIds:
410446
def test_create_unique(self, hbase_client):

0 commit comments

Comments
 (0)