···127127 deleted.add(a.frame.node.cid)
128128129129 while True:
130130- while a.rkey != b.rkey: # we need a loop because they might "leapfrog" each other
130130+ while a.rpath != b.rpath: # we need a loop because they might "leapfrog" each other
131131 # "catch up" cursor a, if it's behind
132132- while a.rkey < b.rkey and not a.is_final:
132132+ while a.rpath < b.rpath and not a.is_final:
133133 if a.subtree: # recurse down every subtree
134134 a.down()
135135 deleted.add(a.frame.node.cid)
···137137 a.right()
138138139139 # catch up cursor b, likewise
140140- while b.rkey < a.rkey and not b.is_final:
140140+ while b.rpath < a.rpath and not b.is_final:
141141 if b.subtree: # recurse down every subtree
142142 b.down()
143143 created.add(b.frame.node.cid)
144144 else:
145145 b.right()
146146147147- # the rkeys now match, but the subrees below us might not
147147+ # the rpaths now match, but the subrees below us might not
148148149149 _mst_diff_recursive(created, deleted, a.subtree_walker(), b.subtree_walker())
150150151151 # check if we can still go right XXX: do we need to care about the case where one can, but the other can't?
152152 # To consider: maybe if I just step a, b will catch up automagically
153153- if a.rkey == a.stack[0].rkey and b.rkey == b.stack[0].rkey:
153153+ if a.rpath == a.stack[0].rpath and b.rpath == b.stack[0].rpath:
154154 break
155155156156 a.right()
+23-23
src/atmst/mst/node_walker.py
···18181919 Recall MSTNode layout: ::
20202121- keys: (lkey) (0, 1, 2, 3) (rkey)
2222- vals: (0, 1, 2, 3)
2323- subtrees: (0, 1, 2, 3, 4)
2121+ keys: (lpath) (0, 1, 2, 3) (rpath)
2222+ vals: (0, 1, 2, 3)
2323+ subtrees: (0, 1, 2, 3, 4)
24242525 """
2626- KEY_MIN = "" # string that compares less than all legal key strings
2727- KEY_MAX = "\xff" # string that compares greater than all legal key strings
2626+ PATH_MIN = "" # string that compares less than all legal path strings
2727+ PATH_MAX = "\xff" # string that compares greater than all legal path strings
28282929 @dataclass
3030 class StackFrame:
3131 node: MSTNode # could store CIDs only to save memory, in theory, but not much point
3232- lkey: str
3333- rkey: str
3232+ lpath: str
3333+ rpath: str
3434 idx: int
35353636 ns: NodeStore
3737 stack: List[StackFrame]
38383939- def __init__(self, ns: NodeStore, root_cid: Optional[CID], lkey: Optional[str]=KEY_MIN, rkey: Optional[str]=KEY_MAX) -> None:
3939+ def __init__(self, ns: NodeStore, root_cid: Optional[CID], lpath: Optional[str]=PATH_MIN, rpath: Optional[str]=PATH_MAX) -> None:
4040 self.ns = ns
4141 self.stack = [self.StackFrame(
4242 node=MSTNode.empty_root() if root_cid is None else self.ns.get_node(root_cid),
4343- lkey=lkey,
4444- rkey=rkey,
4343+ lpath=lpath,
4444+ rpath=rpath,
4545 idx=0
4646 )]
47474848 def subtree_walker(self) -> Self:
4949- return NodeWalker(self.ns, self.subtree, self.lkey, self.rkey)
4949+ return NodeWalker(self.ns, self.subtree, self.lpath, self.rpath)
50505151 @property
5252 def frame(self) -> StackFrame:
5353 return self.stack[-1]
54545555 @property
5656- def lkey(self) -> str:
5757- return self.frame.lkey if self.frame.idx == 0 else self.frame.node.keys[self.frame.idx - 1]
5656+ def lpath(self) -> str:
5757+ return self.frame.lpath if self.frame.idx == 0 else self.frame.node.keys[self.frame.idx - 1]
58585959 @property
6060 def lval(self) -> Optional[CID]:
···6464 def subtree(self) -> Optional[CID]:
6565 return self.frame.node.subtrees[self.frame.idx]
66666767- # hmmmm rkey is overloaded here... "right key" not "record key"...
6867 @property
6969- def rkey(self) -> str:
7070- return self.frame.rkey if self.frame.idx == len(self.frame.node.keys) else self.frame.node.keys[self.frame.idx]
6868+ def rpath(self) -> str:
6969+ return self.frame.rpath if self.frame.idx == len(self.frame.node.keys) else self.frame.node.keys[self.frame.idx]
71707271 @property
7372 def rval(self) -> Optional[CID]:
···75747675 @property
7776 def is_final(self) -> bool:
7878- return (not self.stack) or (self.subtree is None and self.rkey == self.stack[0].rkey)
7777+ return (not self.stack) or (self.subtree is None and self.rpath == self.stack[0].rpath)
79788079 def right(self) -> None:
8180 if (self.frame.idx + 1) >= len(self.frame.node.subtrees):
···93929493 self.stack.append(self.StackFrame(
9594 node=self.ns.get_node(subtree),
9696- lkey=self.lkey,
9797- rkey=self.rkey,
9595+ lpath=self.lpath,
9696+ rpath=self.rpath,
9897 idx=0
9998 ))
10099···105104 while self.subtree: # recurse down every subtree
106105 self.down()
107106 self.right()
108108- return self.lkey, self.lval # the kv pair we just jumped over
107107+ return self.lpath, self.lval # the kv pair we just jumped over
109108110109 # iterate over every k/v pair in key-sorted order
110110+ # NB: should really be p/v standing for path/value
111111 def iter_kv(self) -> Iterable[Tuple[str, CID]]:
112112 while not self.is_final:
113113 yield self.next_kv()
···128128 # start inclusive
129129 def iter_kv_range(self, start: str, end: str, end_inclusive: bool=False) -> Iterable[Tuple[str, CID]]:
130130 while True:
131131- while self.rkey < start:
131131+ while self.rpath < start:
132132 self.right()
133133 if not self.subtree:
134134 break
···141141142142 def find_value(self, key: str) -> Optional[CID]:
143143 while True:
144144- while self.rkey < key:
144144+ while self.rpath < key:
145145 self.right()
146146 if not self.subtree:
147147 break
148148 self.down()
149149- if self.rkey != key:
149149+ if self.rpath != key:
150150 return None
151151 return self.rval
+1-1
tests/test_varint.py
···2222 self.assertRaises(ValueError, decode_varint, io.BytesIO(b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f')) # too big
2323 self.assertRaises(ValueError, decode_varint, io.BytesIO(b"")) # too short
2424 self.assertRaises(ValueError, decode_varint, io.BytesIO(b'\xff')) # truncated
2525- self.assertRaises(ValueError, decode_varint, io.BytesIO(b"\x80\x00")) # too minimally encoded
2525+ self.assertRaises(ValueError, decode_varint, io.BytesIO(b"\x80\x00")) # not minimally encoded
26262727if __name__ == '__main__':
2828 unittest.main(module="tests.test_varint")