Changed lfsr_data_t internals, added LFSR_DATA_CAT

The main purpose of this change is to introduce LFSR_DATA_CAT, a
generalized way to concatenated various data references internally.

As a side-effect lfsr_data_t has been completely restructured. Now,
lfsr_data_t can be in one of 4 modes:

If the size field's sign bit=0, the lfsr_data_t points in-device. A new,
count field, determines the encoding:

  sign(size)=0, count=0 => inlined:

    .---+---+---+---.
    |     size      |
    |---+---+---+---|
    |c=0| inlined d |  note inlined data is just enough to hold
    |---+           |  one encoded leb128
    | ata...        |
    '---------------'

  sign(size)=1, count=1 => direct:

    .---+---+---+---.   .---+---+---+---.
    |     size      | .>| data...       |
    |---+---+---+---| | |       .       |
    |c=1|           | | .       .       .
    |---+---+---+---| | .       .       .
    | direct ptr -----' .               .
    '---------------'

  sign(size)=1, count>=2 => indirect:

    .---+---+---+---.   .---+---+---+---.   .---+---+---+---.
    |     size      | .>|     size      | .>| data...       |
    |---+---+---+---| | |---+---+---+---| | |       .       |
    |c>1|           | | |c=1|           | | .       .       .
    |---+---+---+---| | |---+---+---+---| | .       .       .
    | indirect ptr ---' | direct ptr -----' .               .
    '---------------'   '---------------'   .---+---+---+---.
                        |     size      | .>| data...       |
                        |---+---+---+---| | |       .       |
                        |c=1|           | | .       .       .
                        |---+---+---+---| | .       .       .
                        | direct ptr -----' .               .
                        '---+---+---+---'
                        |       .       |
                        |       .       |
                        .       .       .
                        .               .
                        .               .

  note only one indirect layer is allowed due to no recursion

If the size field's sign bit=1, the lfsr_data_t points on-disk:

  sign(size)=0 => on-disk:

    .---+---+---+---.          .....
    |     size      |      ..''     ''..
    |---+---+---+---|     :    :        :
    |     block ------+->|            ..:|
    |---+---+---+---| |  |......( )::::::|
    |      off -------'  |:::'    :      |
    '---------------'     :'       :    :
                           ''..     :.''
                               '''''

My goal with this commit was to test the new implementation and see how
it would impact code/RAM size before adopting it in the actual file
handling code, and the results are... not great...

            code          stack
  before:  24668           1840
  after:   25552 (+3.5%)   1920 (+4.2%)

I think most of the new cost comes from the now correct handling of
read/cmp with concatentated datas, which previously would just assert.
This change gives us LFSR_DATA_CAT, so I will be working with it for
now, but this may be worth looking at again in the future. Maybe the
correct handling of read/cmp should just be reverted to an assert...
This commit is contained in:
Christopher Haster
2023-09-22 22:19:37 -05:00
parent da2a4b45f7
commit 02ae6050de
5 changed files with 510 additions and 276 deletions
+14 -14
View File
@@ -3465,7 +3465,7 @@ code = '''
}
if (tag_ == LFSR_TAG_BTREE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.buffer.buffer;
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x btree 0x%x.%x\n",
mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs),
@@ -3475,7 +3475,7 @@ code = '''
// keep track of seen blocks
seen[branch->block / 8] |= 1 << (branch->block % 8);
} else if (tag_ == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.buffer.buffer;
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n",
mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs),
@@ -3589,7 +3589,7 @@ code = '''
}
if (tag_ == LFSR_TAG_BTREE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.buffer.buffer;
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x btree 0x%x.%x\n",
mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs),
@@ -3599,7 +3599,7 @@ code = '''
// keep track of seen blocks
seen[branch->block / 8] |= 1 << (branch->block % 8);
} else if (tag_ == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.buffer.buffer;
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n",
mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs),
@@ -3724,7 +3724,7 @@ code = '''
}
if (tag_ == LFSR_TAG_BTREE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.buffer.buffer;
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x btree 0x%x.%x\n",
mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs),
@@ -3734,7 +3734,7 @@ code = '''
// keep track of seen blocks
seen[branch->block / 8] |= 1 << (branch->block % 8);
} else if (tag_ == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.buffer.buffer;
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n",
mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs),
@@ -3851,7 +3851,7 @@ code = '''
}
if (tag_ == LFSR_TAG_BTREE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.buffer.buffer;
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x btree 0x%x.%x\n",
mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs),
@@ -3861,7 +3861,7 @@ code = '''
// keep track of seen blocks
seen[branch->block / 8] |= 1 << (branch->block % 8);
} else if (tag_ == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.buffer.buffer;
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n",
mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs),
@@ -3989,7 +3989,7 @@ code = '''
}
if (tag_ == LFSR_TAG_BTREE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.buffer.buffer;
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x btree 0x%x.%x\n",
mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs),
@@ -3999,7 +3999,7 @@ code = '''
// keep track of seen blocks
seen[branch->block / 8] |= 1 << (branch->block % 8);
} else if (tag_ == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.buffer.buffer;
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n",
mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs),
@@ -4159,7 +4159,7 @@ code = '''
}
if (tag_ == LFSR_TAG_BTREE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.buffer.buffer;
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x btree 0x%x.%x\n",
mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs),
@@ -4169,7 +4169,7 @@ code = '''
// keep track of seen blocks
seen[branch->block / 8] |= 1 << (branch->block % 8);
} else if (tag_ == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.buffer.buffer;
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n",
mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs),
@@ -4267,14 +4267,14 @@ code = '''
}
if (tag_ == LFSR_TAG_BTREE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.buffer.buffer;
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x btree 0x%x.%x\n",
mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs),
tag_,
branch->block, branch->trunk);
} else if (tag_ == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.buffer.buffer;
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n",
mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs),