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
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_;