Initial groundwork for rbyd trees
- primitive lfs_rbyd_fetch
- primitive lfs_rbyd_commit
- tag reading/progging and encoding machinery
The tag encoding scheme here uses pairs of leb128s, encoding either
a normal tag:
iiii iiiiiii iiiiiTT TTTTTTt ttttt0v
^--------^------^-^- 16-bit id
'------|-|- 8-bit type2
'-|- 6-bit type1
'- valid bit
llll lllllll lllllll lllllll lllllll
^- n-bit length
Or an alt pointer:
wwww wwwwwww wwwwwww wwwwwww wwwcd1v
^^^-^- 28-bit weight
'|-|- color bit
'-|- direction bit
'- valid bit
jjjj jjjjjjj jjjjjjj jjjjjjj jjjjjjj
^- n-bit jump
Note that two bits overlap the alt pointer dir/color encoding, this
is actually not a problem at all since some tags (crcs/fcrcs) don't
participate in the rbyd tree and can use these bits.
There's a number of benefits to using leb128s, which should probably
be written about, most notably is the abstraction of the device's
word-size. The "n-bits" above can be whatever word size works on the
device, trading off code-size for storage capabilities without breaking
compatibility with other devices. This will eventually be negotiated via
the superblock.
This commit is contained in:
+39
@@ -10,6 +10,45 @@
|
||||
// Only compile if user does not provide custom config
|
||||
#ifndef LFS_CONFIG
|
||||
|
||||
// Need lfs.h for error codes
|
||||
// TODO should we actually move the error codes to lfs_util.h?
|
||||
#include "lfs.h"
|
||||
|
||||
|
||||
// Convert to/from leb128 encoding
|
||||
ssize_t lfs_toleb128(uint32_t word, void *buffer, size_t size) {
|
||||
uint8_t *data = buffer;
|
||||
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
uint8_t dat = word & 0x7f;
|
||||
word >>= 7;
|
||||
if (word != 0) {
|
||||
data[i] = dat | 0x80;
|
||||
} else {
|
||||
data[i] = dat | 0x00;
|
||||
return i+1;
|
||||
}
|
||||
}
|
||||
|
||||
return LFS_ERR_OVERFLOW;
|
||||
}
|
||||
|
||||
ssize_t lfs_fromleb128(uint32_t *word, const void *buffer, size_t size) {
|
||||
const uint8_t *data = buffer;
|
||||
|
||||
uint32_t word_ = 0;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
uint8_t dat = data[i];
|
||||
word_ |= (dat & 0x7f) << 7*i;
|
||||
if (!(dat & 0x80)) {
|
||||
*word = word_;
|
||||
return i+1;
|
||||
}
|
||||
}
|
||||
|
||||
return LFS_ERR_OVERFLOW;
|
||||
}
|
||||
|
||||
|
||||
// Software CRC implementation with small lookup table
|
||||
uint32_t lfs_crc(uint32_t crc, const void *buffer, size_t size) {
|
||||
|
||||
Reference in New Issue
Block a user