From 4534d095e9c5a0a691ea1fe50cf1ab717292126e Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Mon, 11 Dec 2023 10:51:58 -0600 Subject: [PATCH] Reframed data slice operations in terms of lfsr_data_slice This combines the previous lfsr_data_truncate/lfsr_data_fruncate behavior into a single flexible function, and makes truncate/fruncate small aliases (drop in the future?). The combined behavior lets us adopt lfsr_data_slice in more places. --- lfs.c | 100 ++++++++++++++++++++++++---------------------------------- 1 file changed, 42 insertions(+), 58 deletions(-) diff --git a/lfs.c b/lfs.c index 2a08fb55..be3d4fa3 100644 --- a/lfs.c +++ b/lfs.c @@ -1122,30 +1122,37 @@ static inline lfsr_data_t lfsr_data_fromcat( } // note these operations only work on "simple" (not concatenated) datas -static lfsr_data_t lfsr_data_add(lfsr_data_t data, lfs_size_t off) { - // limit our off to data range - lfs_size_t off_ = lfs_min32(off, lfsr_data_size(&data)); +static lfsr_data_t lfsr_data_slice(lfsr_data_t data, + lfs_ssize_t off, lfs_ssize_t size) { + // limit our off/size to data range, note the use of unsigned casts + // here to treat -1 as unbounded + lfs_size_t off_ = lfs_min32( + lfs_smax32(off, 0), + lfsr_data_size(&data)); + lfs_size_t size_ = lfs_min32( + (lfs_size_t)size, + lfsr_data_size(&data) - off_); // on-disk? increment if (lfsr_data_ondisk(&data)) { data.u.disk.off += off_; - data.u.disk.size -= off_; + data.u.disk.size = LFSR_DATA_ONDISK | size_; // buffer? increment } else if (lfsr_data_isbuf(&data)) { data.u.buf.buffer += off_; - data.u.buf.size -= off_; + data.u.buf.size = size_; // hole? decrement } else if (lfsr_data_ishole(&data)) { - data.u.hole.size -= off_; + data.u.hole.size = size_; // inlined? internal memmove } else if (lfsr_data_isimm(&data)) { memmove(data.u.imm.buf, data.u.imm.buf + off_, - data.u.imm.size - off_); - data.u.imm.size -= off_; + size_); + data.u.imm.size = size_; // concatenated? not supported } else { @@ -1156,39 +1163,15 @@ static lfsr_data_t lfsr_data_add(lfsr_data_t data, lfs_size_t off) { } static lfsr_data_t lfsr_data_truncate(lfsr_data_t data, lfs_size_t size) { - // limit size to our data range - size = lfs_min32(size, lfsr_data_size(&data)); - - // on-disk? update size - if (lfsr_data_ondisk(&data)) { - data.u.disk.size = LFSR_DATA_ONDISK | size; - - // buffer? update size - } else if (lfsr_data_isbuf(&data)) { - data.u.buf.size = size; - - // hole? update size - } else if (lfsr_data_ishole(&data)) { - data.u.hole.size = size; - - // inlined? update size - } else if (lfsr_data_isimm(&data)) { - data.u.imm.size = size; - - // concatenated? not supported - } else { - LFS_UNREACHABLE(); - } - - return data; + return lfsr_data_slice(data, -1, size); } static lfsr_data_t lfsr_data_fruncate(lfsr_data_t data, lfs_size_t size) { - // limit size to our data range - size = lfs_min32(size, lfsr_data_size(&data)); - - // lfsr_data_fruncate and lfsr_data_add are basically the same operation - return lfsr_data_add(data, lfsr_data_size(&data) - size); + return lfsr_data_slice(data, + lfsr_data_size(&data) - lfs_min32( + size, + lfsr_data_size(&data)), + -1); } @@ -1229,7 +1212,7 @@ static lfs_ssize_t lfsr_data_read(lfs_t *lfs, lfsr_data_t *data, LFS_UNREACHABLE(); } - *data = lfsr_data_add(*data, d); + *data = lfsr_data_slice(*data, d, -1); return d; } @@ -1268,7 +1251,7 @@ static int lfsr_data_readleb128(lfs_t *lfs, lfsr_data_t *data, return d; } - *data = lfsr_data_add(*data, d); + *data = lfsr_data_slice(*data, d, -1); return 0; } @@ -9462,17 +9445,21 @@ static int lfsr_ftree_carve(lfs_t *lfs, } // note, an entry can be both a left and right sibling - lfsr_data_t left_slice_ = lfsr_data_truncate(bptr_.data, + lfsr_data_t left_slice_ = lfsr_data_slice(bptr_.data, + -1, pos - (bid_-(weight_-1))); - lfsr_data_t right_slice_ = lfsr_data_add(bptr_.data, - pos+weight - (bid_-(weight_-1))); + lfsr_data_t right_slice_ = lfsr_data_slice(bptr_.data, + pos+weight - (bid_-(weight_-1)), + -1); // left sibling needs carving but falls underneath our // crystallization threshold? break into fragments while (tag_ == LFSR_TAG_BLOCK && lfsr_data_size(&left_slice_) > lfs->cfg->fragment_size && lfsr_data_size(&left_slice_) <= lfs->cfg->crystal_size) { - bptr_.data = lfsr_data_add(bptr_.data, lfs->cfg->fragment_size); + bptr_.data = lfsr_data_slice(bptr_.data, + lfs->cfg->fragment_size, + -1); err = lfsr_bshrub_commit(lfs, mdir, &ftree->u.bshrub, LFSR_ATTRS( LFSR_ATTR(bid_, @@ -9488,7 +9475,8 @@ static int lfsr_ftree_carve(lfs_t *lfs, } weight_ -= lfs->cfg->fragment_size; - left_slice_ = lfsr_data_truncate(bptr_.data, + left_slice_ = lfsr_data_slice(bptr_.data, + -1, pos - (bid_-(weight_-1))); } @@ -9515,8 +9503,9 @@ static int lfsr_ftree_carve(lfs_t *lfs, bid_ -= (weight_-lfsr_data_size(&bptr_.data)); weight_ -= (weight_-lfsr_data_size(&bptr_.data)); - right_slice_ = lfsr_data_add(bptr_.data, - pos+weight - (bid_-(weight_-1))); + right_slice_ = lfsr_data_slice(bptr_.data, + pos+weight - (bid_-(weight_-1)), + -1); } // found left sibling? @@ -9954,7 +9943,6 @@ static int lfsr_ftree_flush(lfs_t *lfs, } if (pos < bid-(weight-1) + lfsr_data_size(&bptr.data)) { - // TODO should truncate just imply a strict data hint? // note one important side-effect here is a strict // data hint lfs_ssize_t d_ = lfs_min32( @@ -9962,10 +9950,8 @@ static int lfsr_ftree_flush(lfs_t *lfs, lfsr_data_size(&bptr.data) - (pos - (bid-(weight-1)))); err = lfsr_bd_progdata(lfs, block, pos - block_start, - LFSR_DATA_DISK( - bptr.data.u.disk.block, - bptr.data.u.disk.off - + (pos - (bid-(weight-1))), + lfsr_data_slice(bptr.data, + pos - (bid-(weight-1)), d_), &cksum); if (err) { @@ -10079,18 +10065,16 @@ lfs_ssize_t lfsr_file_read(lfs_t *lfs, lfsr_file_t *file, } if (pos < bid-(weight-1) + lfsr_data_size(&bptr.data)) { - // TODO should truncate just imply a strict data hint? // note one important side-effect here is a strict // data hint lfs_ssize_t d_ = lfs_min32( d, lfsr_data_size(&bptr.data) - (pos - (bid-(weight-1)))); - d_ = lfsr_data_read(lfs, - &LFSR_DATA_DISK( - bptr.data.u.disk.block, - bptr.data.u.disk.off + (pos - (bid-(weight-1))), - d_), + lfsr_data_t slice = lfsr_data_slice(bptr.data, + pos - (bid-(weight-1)), + d_); + d_ = lfsr_data_read(lfs, &slice, buffer_, d_); if (d_ < 0) { return d_;