Partial implementation of a rudimentary mtree
This became surprisingly tricky. The main issue is knowing when to split mdirs, and how to determine this without wasting erase cycles. Unlike splitting btree nodes, we can't salvage failed compacts here. As soon as the salvage commit is written to disk, the commit becomes immediately visibile to the filesystem because it still exists in the mtree. This is a problem if we lose power. We're likely going to need to implement rbyd estimates. This is something I hoped to avoid because it brings in quite a bit of complexity and might lead to an annoying amount of storage waste since our estimates will need to be conservative to avoid unrecoverable situations. --- Also changed the on-disk btree/branch struct to store a copy of the weight. This was already required for the root of the btree, requiring the weight to be stored in every btree pointer allows better code deduplication at the cost of some redundancy on btree branches, where the weight is already implied by the rbyd structure. This weight is usually a single byte for most branches anyways. This may be worth revisiting at some point to see if there's any other unexpected tradeoffs.
This commit is contained in:
+4
-3
@@ -367,9 +367,10 @@ def main(disk, root=0, *,
|
||||
# is it another branch? continue down tree
|
||||
if struct_tag == TAG_BRANCH and (
|
||||
depth is None or depth_ < depth):
|
||||
trunk, d1 = fromleb128(struct_)
|
||||
block, d2 = fromleb128(struct_[d1:])
|
||||
crc = fromle32(struct_[d1+d2:])
|
||||
w, d1 = fromleb128(struct_)
|
||||
trunk, d2 = fromleb128(struct_[d1:])
|
||||
block, d3 = fromleb128(struct_[d1+d2:])
|
||||
crc = fromle32(struct_[d1+d2+d3:])
|
||||
rbyd = Rbyd.fetch(f, block_size, block, trunk)
|
||||
|
||||
# corrupted? bail here so we can keep traversing the tree
|
||||
|
||||
Reference in New Issue
Block a user