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:
@@ -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_;
|
||||||
|
|||||||
Reference in New Issue
Block a user