forked from Imagelibrary/littlefs
Added LFSR_TAG_BNAME/MNAME, stop btree lookups at first tag
Now that we don't have to worry about name tag conflicts as much, we
can add name tags for things that aren't files.
This adds LFSR_TAG_BNAME for branch names, and LFSR_TAG_MNAME for mtree
names. Note that the upper 4 bits of the subtype match LFSR_TAG_BRANCH
and LFSR_TAG_MDIR respectively:
LFSR_TAG_BNAME 0x0200 v--- --1- ---- ----
LFSR_TAG_MNAME 0x0220 v--- --1- --1- ----
LFSR_TAG_BRANCH 0x030r v--- --11 ---- --rr
LFSR_TAG_MDIR 0x0324 v--- --11 --1- -1rr
The encoding is somewhat arbitrary, but I figured reserving ~31 types
for files is probably going to be plenty for littlefs. POSIX seems to
do just fine with only ~7 all these years, and I think custom attributes
will be more enticing for "niche" file types (symlinks, compressed
files, etc), given the easy backwards compatibility.
---
In addition to the debugging benefits, the new name tags let us stop
btree lookups on the first non-bname/branch tag. Previously we always
had to fetch the first struct tag as well to check if it was a branch.
In theory this saves one rbyd lookup, but in practice it's a bit muddy.
The problem is that there's two ways to use named btrees:
1. As buckets: mtree -> mdir -> mid
2. As a table: ddtree -> ddid
The only named btree we _currently_ have is the mtree. And the mtree
operates in bucket mode, with each mdir acting more-or-less as an
extension to the btree. So we end up needing to do the second tag lookup
anyways, and all we've done is complicated up the code.
But we will _eventually_ need the table mode for the ddtree, where we
care if the ddname is an exact match.
And returning the first tag is arguably the more "correct" internal API,
vs arbitrarily the first struct tag.
But then again this change is pretty pricey...
code stack ctx
before: 35732 2440 640
after: 35888 (+0.4%) 2480 (+1.6%) 640 (+0.0%)
---
It's worth noting the new BNAME/MNAME tags don't _require_ the btree
lookup changes (which is why we can get away with not touching the dbg
scripts). The previous algorithm of always checking for branch tags
still works.
Maybe there's an argument for conditionally using the previous API when
compiling without the ddtree, but that sounds horrendously messy...
This commit is contained in:
@@ -42,10 +42,12 @@ TAG_NAMELIMIT = 0x003a # 0x003a v--- ---- --11 1-1-
|
||||
TAG_GDELTA = 0x0100 ## 0x01tt v--- ---1 -ttt ttrr
|
||||
TAG_GRMDELTA = 0x0100 # 0x0100 v--- ---1 ---- ----
|
||||
TAG_NAME = 0x0200 ## 0x02tt v--- --1- -ttt tttt
|
||||
TAG_BNAME = 0x0200 # 0x0200 v--- --1- ---- ----
|
||||
TAG_REG = 0x0201 # 0x0201 v--- --1- ---- ---1
|
||||
TAG_DIR = 0x0202 # 0x0202 v--- --1- ---- --1-
|
||||
TAG_STICKYNOTE = 0x0203 # 0x0203 v--- --1- ---- --11
|
||||
TAG_BOOKMARK = 0x0204 # 0x0204 v--- --1- ---- -1--
|
||||
TAG_MNAME = 0x0220 # 0x0220 v--- --1- --1- ----
|
||||
TAG_STRUCT = 0x0300 ## 0x03tt v--- --11 -ttt ttrr
|
||||
TAG_BRANCH = 0x0300 # 0x030r v--- --11 ---- --rr
|
||||
TAG_DATA = 0x0304 # 0x0304 v--- --11 ---- -1--
|
||||
@@ -314,11 +316,12 @@ def tagrepr(tag, weight=None, size=None, *,
|
||||
elif (tag & 0x6f00) == TAG_NAME:
|
||||
return '%s%s%s%s' % (
|
||||
'shrub' if tag & TAG_SHRUB else '',
|
||||
'name' if (tag & 0xfff) == TAG_NAME
|
||||
'bname' if (tag & 0xfff) == TAG_BNAME
|
||||
else 'reg' if (tag & 0xfff) == TAG_REG
|
||||
else 'dir' if (tag & 0xfff) == TAG_DIR
|
||||
else 'stickynote' if (tag & 0xfff) == TAG_STICKYNOTE
|
||||
else 'bookmark' if (tag & 0xfff) == TAG_BOOKMARK
|
||||
else 'mname' if (tag & 0xfff) == TAG_MNAME
|
||||
else 'name 0x%02x' % (tag & 0xff),
|
||||
' w%d' % weight if weight else '',
|
||||
' %s' % size if size is not None else '')
|
||||
|
||||
Reference in New Issue
Block a user