mirror of
https://github.com/Zygo/bees.git
synced 2025-05-17 21:35:45 +02:00
fs: add an item type parameter to next_min
When we are searching the btrfs metadata trees, we usually want only one type of item. If the last item in a search result is not of the desired type, we can restart the search at the next possible key with that item type, potentially skipping over some uninteresting items we would otherwise have to fetch, process, and discard. Also remove a bug in the previous next_min code that would skip over items if the offset overflowed and the next objectid in the tree had a lower item type number than the previous objectid. This doesn't seem to be a bug that has ever happened, as it would require a file to roll over in the offset field. Signed-off-by: Zygo Blaxell <bees@furryterror.org>
This commit is contained in:
parent
e861957632
commit
fcd847bbf9
@ -192,6 +192,9 @@ namespace crucible {
|
||||
// Copy objectid/type/offset so we move forward
|
||||
void next_min(const BtrfsIoctlSearchHeader& ref);
|
||||
|
||||
// move forward to next object of a single type
|
||||
void next_min(const BtrfsIoctlSearchHeader& ref, const uint8_t type);
|
||||
|
||||
size_t m_buf_size;
|
||||
set<BtrfsIoctlSearchHeader> m_result;
|
||||
};
|
||||
|
38
lib/fs.cc
38
lib/fs.cc
@ -823,8 +823,46 @@ namespace crucible {
|
||||
min_type = ref.type;
|
||||
min_offset = ref.offset + 1;
|
||||
if (min_offset < ref.offset) {
|
||||
// We wrapped, try the next type
|
||||
++min_type;
|
||||
assert(min_offset == 0);
|
||||
if (min_type < ref.type) {
|
||||
assert(min_type == 0);
|
||||
// We wrapped, try the next objectid
|
||||
++min_objectid;
|
||||
// no advancement possible at end
|
||||
THROW_CHECK1(runtime_error, min_type, min_type == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BtrfsIoctlSearchKey::next_min(const BtrfsIoctlSearchHeader &ref, const uint8_t type)
|
||||
{
|
||||
if (ref.type < type) {
|
||||
// forward to type in same object with zero offset
|
||||
min_objectid = ref.objectid;
|
||||
min_type = type;
|
||||
min_offset = 0;
|
||||
} else if (ref.type > type) {
|
||||
// skip directly to start of next objectid with target type
|
||||
min_objectid = ref.objectid + 1;
|
||||
// no advancement possible at end
|
||||
THROW_CHECK2(out_of_range, min_objectid, ref.objectid, min_objectid > ref.objectid);
|
||||
min_type = type;
|
||||
min_offset = 0;
|
||||
} else {
|
||||
// advance within this type
|
||||
min_objectid = ref.objectid;
|
||||
min_type = ref.type;
|
||||
min_offset = ref.offset + 1;
|
||||
if (min_offset < ref.offset) {
|
||||
// We wrapped, try the next objectid, same type
|
||||
++min_objectid;
|
||||
THROW_CHECK2(out_of_range, min_objectid, ref.objectid, min_objectid > ref.objectid);
|
||||
min_type = type;
|
||||
assert(min_offset == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user