1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-28 17:57:36 +00:00

LibCore: Resume search in find_and_populate_until_any_of

The search used to go through the buffer from the start, even if we just
appended a small number of bytes at the end. It now remembers the last
stop and resume the search from it.
This commit is contained in:
Lucas CHOLLET 2023-01-08 15:34:37 -05:00 committed by Andrew Kaster
parent b21ea54af0
commit 8252436c18

View file

@ -743,15 +743,14 @@ public:
// remove from the buffer after copying up to the delimiter to the // remove from the buffer after copying up to the delimiter to the
// user buffer. // user buffer.
auto const find_candidates = [this, &candidates, &longest_candidate](Optional<size_t> max_offset = {}) -> Optional<Match> { auto const find_candidates = [this, &candidates, &longest_candidate](size_t min_offset, Optional<size_t> max_offset = {}) -> Optional<Match> {
auto const corrected_minimum_offset = *longest_candidate > min_offset ? 0 : min_offset - *longest_candidate;
max_offset = max_offset.value_or(m_buffer.used_space()); max_offset = max_offset.value_or(m_buffer.used_space());
Optional<size_t> longest_match; Optional<size_t> longest_match;
size_t match_size = 0; size_t match_size = 0;
for (auto& candidate : candidates) { for (auto& candidate : candidates) {
// FIXME: This currently searches through the buffer from the start, auto const result = m_buffer.offset_of(candidate, corrected_minimum_offset, *max_offset);
// even if we just appended a small number of bytes at the end.
auto const result = m_buffer.offset_of(candidate, {}, *max_offset);
if (result.has_value()) { if (result.has_value()) {
auto previous_match = longest_match.value_or(*result); auto previous_match = longest_match.value_or(*result);
@ -768,16 +767,19 @@ public:
return {}; return {};
}; };
if (auto first_find = find_candidates(max_offset); first_find.has_value()) if (auto first_find = find_candidates(0, max_offset); first_find.has_value())
return first_find; return first_find;
auto last_size = m_buffer.used_space();
while (m_buffer.used_space() < max_offset.value_or(m_buffer.capacity())) { while (m_buffer.used_space() < max_offset.value_or(m_buffer.capacity())) {
auto const read_bytes = TRY(populate_read_buffer()); auto const read_bytes = TRY(populate_read_buffer());
if (read_bytes == 0) if (read_bytes == 0)
break; break;
if (auto first_find = find_candidates(max_offset); first_find.has_value()) if (auto first_find = find_candidates(last_size, max_offset); first_find.has_value())
return first_find; return first_find;
last_size = m_buffer.used_space();
} }
return Optional<Match> {}; return Optional<Match> {};