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.
This commit is contained in:
Christopher Haster
2023-12-11 10:51:58 -06:00
parent c4d75efa40
commit 4534d095e9
+42 -58
View File
@@ -1122,30 +1122,37 @@ static inline lfsr_data_t lfsr_data_fromcat(
} }
// note these operations only work on "simple" (not concatenated) datas // 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) { static lfsr_data_t lfsr_data_slice(lfsr_data_t data,
// limit our off to data range lfs_ssize_t off, lfs_ssize_t size) {
lfs_size_t off_ = lfs_min32(off, lfsr_data_size(&data)); // 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 // on-disk? increment
if (lfsr_data_ondisk(&data)) { if (lfsr_data_ondisk(&data)) {
data.u.disk.off += off_; data.u.disk.off += off_;
data.u.disk.size -= off_; data.u.disk.size = LFSR_DATA_ONDISK | size_;
// buffer? increment // buffer? increment
} else if (lfsr_data_isbuf(&data)) { } else if (lfsr_data_isbuf(&data)) {
data.u.buf.buffer += off_; data.u.buf.buffer += off_;
data.u.buf.size -= off_; data.u.buf.size = size_;
// hole? decrement // hole? decrement
} else if (lfsr_data_ishole(&data)) { } else if (lfsr_data_ishole(&data)) {
data.u.hole.size -= off_; data.u.hole.size = size_;
// inlined? internal memmove // inlined? internal memmove
} else if (lfsr_data_isimm(&data)) { } else if (lfsr_data_isimm(&data)) {
memmove(data.u.imm.buf, memmove(data.u.imm.buf,
data.u.imm.buf + off_, data.u.imm.buf + off_,
data.u.imm.size - off_); size_);
data.u.imm.size -= off_; data.u.imm.size = size_;
// concatenated? not supported // concatenated? not supported
} else { } 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) { static lfsr_data_t lfsr_data_truncate(lfsr_data_t data, lfs_size_t size) {
// limit size to our data range return lfsr_data_slice(data, -1, size);
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;
} }
static lfsr_data_t lfsr_data_fruncate(lfsr_data_t data, lfs_size_t size) { static lfsr_data_t lfsr_data_fruncate(lfsr_data_t data, lfs_size_t size) {
// limit size to our data range return lfsr_data_slice(data,
size = lfs_min32(size, lfsr_data_size(&data)); lfsr_data_size(&data) - lfs_min32(
size,
// lfsr_data_fruncate and lfsr_data_add are basically the same operation lfsr_data_size(&data)),
return lfsr_data_add(data, lfsr_data_size(&data) - size); -1);
} }
@@ -1229,7 +1212,7 @@ static lfs_ssize_t lfsr_data_read(lfs_t *lfs, lfsr_data_t *data,
LFS_UNREACHABLE(); LFS_UNREACHABLE();
} }
*data = lfsr_data_add(*data, d); *data = lfsr_data_slice(*data, d, -1);
return d; return d;
} }
@@ -1268,7 +1251,7 @@ static int lfsr_data_readleb128(lfs_t *lfs, lfsr_data_t *data,
return d; return d;
} }
*data = lfsr_data_add(*data, d); *data = lfsr_data_slice(*data, d, -1);
return 0; 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 // 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))); pos - (bid_-(weight_-1)));
lfsr_data_t right_slice_ = lfsr_data_add(bptr_.data, lfsr_data_t right_slice_ = lfsr_data_slice(bptr_.data,
pos+weight - (bid_-(weight_-1))); pos+weight - (bid_-(weight_-1)),
-1);
// left sibling needs carving but falls underneath our // left sibling needs carving but falls underneath our
// crystallization threshold? break into fragments // crystallization threshold? break into fragments
while (tag_ == LFSR_TAG_BLOCK while (tag_ == LFSR_TAG_BLOCK
&& lfsr_data_size(&left_slice_) > lfs->cfg->fragment_size && lfsr_data_size(&left_slice_) > lfs->cfg->fragment_size
&& lfsr_data_size(&left_slice_) <= lfs->cfg->crystal_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( err = lfsr_bshrub_commit(lfs, mdir, &ftree->u.bshrub, LFSR_ATTRS(
LFSR_ATTR(bid_, LFSR_ATTR(bid_,
@@ -9488,7 +9475,8 @@ static int lfsr_ftree_carve(lfs_t *lfs,
} }
weight_ -= lfs->cfg->fragment_size; weight_ -= lfs->cfg->fragment_size;
left_slice_ = lfsr_data_truncate(bptr_.data, left_slice_ = lfsr_data_slice(bptr_.data,
-1,
pos - (bid_-(weight_-1))); pos - (bid_-(weight_-1)));
} }
@@ -9515,8 +9503,9 @@ static int lfsr_ftree_carve(lfs_t *lfs,
bid_ -= (weight_-lfsr_data_size(&bptr_.data)); bid_ -= (weight_-lfsr_data_size(&bptr_.data));
weight_ -= (weight_-lfsr_data_size(&bptr_.data)); weight_ -= (weight_-lfsr_data_size(&bptr_.data));
right_slice_ = lfsr_data_add(bptr_.data, right_slice_ = lfsr_data_slice(bptr_.data,
pos+weight - (bid_-(weight_-1))); pos+weight - (bid_-(weight_-1)),
-1);
} }
// found left sibling? // 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)) { 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 // note one important side-effect here is a strict
// data hint // data hint
lfs_ssize_t d_ = lfs_min32( lfs_ssize_t d_ = lfs_min32(
@@ -9962,10 +9950,8 @@ static int lfsr_ftree_flush(lfs_t *lfs,
lfsr_data_size(&bptr.data) lfsr_data_size(&bptr.data)
- (pos - (bid-(weight-1)))); - (pos - (bid-(weight-1))));
err = lfsr_bd_progdata(lfs, block, pos - block_start, err = lfsr_bd_progdata(lfs, block, pos - block_start,
LFSR_DATA_DISK( lfsr_data_slice(bptr.data,
bptr.data.u.disk.block, pos - (bid-(weight-1)),
bptr.data.u.disk.off
+ (pos - (bid-(weight-1))),
d_), d_),
&cksum); &cksum);
if (err) { 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)) { 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 // note one important side-effect here is a strict
// data hint // data hint
lfs_ssize_t d_ = lfs_min32( lfs_ssize_t d_ = lfs_min32(
d, d,
lfsr_data_size(&bptr.data) lfsr_data_size(&bptr.data)
- (pos - (bid-(weight-1)))); - (pos - (bid-(weight-1))));
d_ = lfsr_data_read(lfs, lfsr_data_t slice = lfsr_data_slice(bptr.data,
&LFSR_DATA_DISK( pos - (bid-(weight-1)),
bptr.data.u.disk.block, d_);
bptr.data.u.disk.off + (pos - (bid-(weight-1))), d_ = lfsr_data_read(lfs, &slice,
d_),
buffer_, d_); buffer_, d_);
if (d_ < 0) { if (d_ < 0) {
return d_; return d_;