Adopted ceiling division in mbits formula
So now:
(block_size)
mbits = nlog2(----------) = nlog2(block_size) - 3
( 8 )
Instead of:
( (block_size))
mbits = nlog2(floor(----------)) = nlog2(block_size & ~0x7) - 3
( ( 8 ))
This makes the post-log - 3 formula simpler, which we probably want to
prefer as it avoids a division. And ceiling is arguably more intuitive
corner case behavior.
This may seem like a minor detail, but because mbits is purely
block_size derived and not configurable, any quirks here will become
a permanent compatibility requirement.
And hey, it saves a couple bytes (I'm not really sure why, the division
should've been optimized to a shift):
code stack ctx
before: 35528 2440 636
after: 35520 (-0.0%) 2440 (+0.0%) 636 (+0.0%)
This commit is contained in:
@@ -13160,31 +13160,40 @@ static int lfs_init(lfs_t *lfs, uint32_t flags,
|
||||
// calculate the number of bits we need to reserve for mdir rids
|
||||
//
|
||||
// Worst case (or best case?) each metadata entry is a single tag. In
|
||||
// theory each entry also needs a name, but with power-of-two rounding,
|
||||
// this is negligible
|
||||
// theory each entry also needs a did+name, but with power-of-two
|
||||
// rounding, this is negligible
|
||||
//
|
||||
// Assuming a _perfect_ compaction algorithm (requires unbounded RAM),
|
||||
// each tag also needs ~1 alt, this gives us:
|
||||
//
|
||||
// block_size block_size
|
||||
// m = ---------- = ----------
|
||||
// a_inf 2t
|
||||
// block_size block_size
|
||||
// mrids = ---------- = ----------
|
||||
// a_inf 2t
|
||||
//
|
||||
// Assuming t=4 bytes, the minimum tag encoding:
|
||||
//
|
||||
// block_size block_size
|
||||
// m = ---------- = ----------
|
||||
// 2*4 8
|
||||
// block_size block_size
|
||||
// mrids = ---------- = ----------
|
||||
// 2*4 8
|
||||
//
|
||||
// Note we can't assume ~1/2 block utilization here, as an mdir may
|
||||
// temporarily fill with more mids before compaction occurs.
|
||||
//
|
||||
// Rounding up to the nearest power of two:
|
||||
//
|
||||
// (block_size)
|
||||
// mbits = nlog2(----------) = nlog2(block_size) - 3
|
||||
// ( 8 )
|
||||
//
|
||||
// Note if you divide before the nlog2, make sure to use ceiling
|
||||
// division for compatibility if block_size is not aligned to 8 bytes.
|
||||
//
|
||||
// Note note our actual compaction algorithm is not perfect, and
|
||||
// requires 3t+4 bytes per tag, or with t=4 bytes => ~block_size/12
|
||||
// metadata entries per block. But we intentionally don't leverage this
|
||||
// to maintain compatibility with a theoretical perfect implementation.
|
||||
//
|
||||
lfs->mdir_bits = lfs_nlog2(lfs->cfg->block_size/8);
|
||||
lfs->mdir_bits = lfs_nlog2(lfs->cfg->block_size) - 3;
|
||||
|
||||
// zero linked-list of opened mdirs
|
||||
lfs->omdirs = NULL;
|
||||
|
||||
+1
-1
@@ -1633,7 +1633,7 @@ class Mtree:
|
||||
def mbits_(block_size):
|
||||
if isinstance(block_size, Bd):
|
||||
block_size = block_size.block_size
|
||||
return mt.ceil(mt.log2(block_size // 8))
|
||||
return mt.ceil(mt.log2(block_size)) - 3
|
||||
|
||||
# convenience function for creating mbits-dependent mids
|
||||
def mid(self, mbid, mrid=None):
|
||||
|
||||
@@ -1663,7 +1663,7 @@ class Mtree:
|
||||
def mbits_(block_size):
|
||||
if isinstance(block_size, Bd):
|
||||
block_size = block_size.block_size
|
||||
return mt.ceil(mt.log2(block_size // 8))
|
||||
return mt.ceil(mt.log2(block_size)) - 3
|
||||
|
||||
# convenience function for creating mbits-dependent mids
|
||||
def mid(self, mbid, mrid=None):
|
||||
|
||||
+1
-1
@@ -1590,7 +1590,7 @@ class Mtree:
|
||||
def mbits_(block_size):
|
||||
if isinstance(block_size, Bd):
|
||||
block_size = block_size.block_size
|
||||
return mt.ceil(mt.log2(block_size // 8))
|
||||
return mt.ceil(mt.log2(block_size)) - 3
|
||||
|
||||
# convenience function for creating mbits-dependent mids
|
||||
def mid(self, mbid, mrid=None):
|
||||
|
||||
+1
-1
@@ -1556,7 +1556,7 @@ class Mtree:
|
||||
def mbits_(block_size):
|
||||
if isinstance(block_size, Bd):
|
||||
block_size = block_size.block_size
|
||||
return mt.ceil(mt.log2(block_size // 8))
|
||||
return mt.ceil(mt.log2(block_size)) - 3
|
||||
|
||||
# convenience function for creating mbits-dependent mids
|
||||
def mid(self, mbid, mrid=None):
|
||||
|
||||
Reference in New Issue
Block a user