Progress on file btrees
Added lfsr_bptr_t to represent block pointers (maybe we should rename
mblocks back to mptr), added fetching of btrees/bptrs in
lfsr_file_opencfg, added estimate tracking to our shrubs so we actually
know when to create a btree, and implemented most of the high-level
btree logic.
It's not working yet, but the biggest idea introduced here is how we
handle block alignment.
See, we really don't want awkward btree topologies to form where small
amounts of data get stuck between blocks:
.-----.--.-----.
| | | |
| | | |
'-----'--'-----'
This is wasteful, as the middle bit of data either gets represented as a
full block with its data partially covered, or as data inlined in the
btree, which comes with ~2x overhead.
The solution here is to scan for a block on either the left or right to
derive our block alignment from.
Unfortunately, since our sibling blocks could have been carved, this
requires scanning all the way from pos-2*B+1 to pos+2*B-1, a total of
4*B-2, to make sure we find a sibling if there is one.
worst case left worst case right
.-----.-----. .-----.-----.
| xxxx| | |p |xxxxx|
|xxxxx| p| | |xxxx |
'-----'-----' '-----'-----'
'----+----' '----+----'
pos-2*bs+1 pos+2*bs-1
Fortunately, at this stage, data should have had many chances to
coalesce, so hopefully the actual scan overhead should be much smaller
in practice.
Writing data to a file linearly, for example, only needs a single lookup
to find the previous block.
This commit is contained in:
@@ -358,6 +358,14 @@ typedef struct lfsr_rbyd {
|
||||
lfs_block_t block;
|
||||
} lfsr_rbyd_t;
|
||||
|
||||
typedef struct lfsr_bptr {
|
||||
// note size lines up with weight in lfsr_btree_t
|
||||
lfs_soff_t size;
|
||||
lfs_block_t block;
|
||||
lfs_size_t off;
|
||||
// TODO how do we track ecksum?
|
||||
} lfsr_bptr_t;
|
||||
|
||||
// The maximum size of inlined pointers in a btree, this depends on littlefs's
|
||||
// on-disk pointer representations (there are several), but doesn't change at
|
||||
// runtime.
|
||||
@@ -464,6 +472,12 @@ typedef struct lfsr_data {
|
||||
lfs_block_t block;
|
||||
lfs_size_t off;
|
||||
} disk;
|
||||
// TODO doc
|
||||
struct {
|
||||
lfs_ssize_t size;
|
||||
lfs_block_t block;
|
||||
const struct lfsr_file *file;
|
||||
} file;
|
||||
} u;
|
||||
} lfsr_data_t;
|
||||
|
||||
@@ -517,7 +531,7 @@ typedef struct lfsr_inlined {
|
||||
struct {
|
||||
lfs_soff_t weight;
|
||||
lfs_size_t trunk;
|
||||
lfs_size_t overhead;
|
||||
lfs_off_t estimate;
|
||||
} shrub;
|
||||
} u;
|
||||
} lfsr_inlined_t;
|
||||
@@ -538,6 +552,12 @@ typedef struct lfsr_file {
|
||||
lfsr_inlined_t inlined;
|
||||
lfsr_inlined_t inlined_;
|
||||
|
||||
union {
|
||||
lfs_soff_t size;
|
||||
lfsr_bptr_t bptr;
|
||||
lfsr_btree_t btree;
|
||||
} u;
|
||||
|
||||
const struct lfs_file_config *cfg;
|
||||
} lfsr_file_t;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user