diff options
Diffstat (limited to 'src/libsystemd/sd-journal/journal-file.c')
-rw-r--r-- | src/libsystemd/sd-journal/journal-file.c | 154 |
1 files changed, 72 insertions, 82 deletions
diff --git a/src/libsystemd/sd-journal/journal-file.c b/src/libsystemd/sd-journal/journal-file.c index f594b3eecb..78dc935161 100644 --- a/src/libsystemd/sd-journal/journal-file.c +++ b/src/libsystemd/sd-journal/journal-file.c @@ -2775,6 +2775,59 @@ enum { TEST_RIGHT }; +static int generic_array_bisect_one( + JournalFile *f, + uint64_t a, /* offset of entry array object. */ + uint64_t i, /* index of the entry item we will test. */ + uint64_t needle, + int (*test_object)(JournalFile *f, uint64_t p, uint64_t needle), + direction_t direction, + uint64_t *left, + uint64_t *right, + uint64_t *ret_offset) { + + Object *array; + uint64_t p; + int r; + + assert(f); + assert(test_object); + assert(left); + assert(right); + assert(*left <= i); + assert(i <= *right); + + r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &array); + if (r < 0) + return r; + + p = journal_file_entry_array_item(f, array, i); + if (p <= 0) + r = -EBADMSG; + else + r = test_object(f, p, needle); + if (IN_SET(r, -EBADMSG, -EADDRNOTAVAIL)) { + log_debug_errno(r, "Encountered invalid entry while bisecting, cutting algorithm short."); + *right = i; + return -ENOANO; /* recognizable error */ + } + if (r < 0) + return r; + + if (r == TEST_FOUND) + r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT; + + if (r == TEST_RIGHT) + *right = i; + else + *left = i + 1; + + if (ret_offset) + *ret_offset = p; + + return r; +} + static int generic_array_bisect( JournalFile *f, uint64_t first, @@ -2833,7 +2886,7 @@ static int generic_array_bisect( } while (a > 0) { - uint64_t left, right, k, lp; + uint64_t left = 0, right, k, lp; r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &array); if (r < 0) @@ -2844,76 +2897,30 @@ static int generic_array_bisect( if (right <= 0) return 0; - i = right - 1; - lp = p = journal_file_entry_array_item(f, array, i); - if (p <= 0) - r = -EBADMSG; - else - r = test_object(f, p, needle); - if (IN_SET(r, -EBADMSG, -EADDRNOTAVAIL)) { - log_debug_errno(r, "Encountered invalid entry while bisecting, cutting algorithm short. (1)"); - n = i; + right--; + r = generic_array_bisect_one(f, a, right, needle, test_object, direction, &left, &right, &lp); + if (r == -ENOANO) { + n = right; continue; } if (r < 0) return r; - if (r == TEST_FOUND) - r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT; - if (r == TEST_RIGHT) { - left = 0; - right -= 1; - - if (last_index != UINT64_MAX) { - assert(last_index <= right); - - /* If we cached the last index we - * looked at, let's try to not to jump - * too wildly around and see if we can - * limit the range to look at early to - * the immediate neighbors of the last - * index we looked at. */ - - if (last_index > 0) { - uint64_t x = last_index - 1; - - p = journal_file_entry_array_item(f, array, x); - if (p <= 0) - return -EBADMSG; - - r = test_object(f, p, needle); - if (r < 0) - return r; - - if (r == TEST_FOUND) - r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT; + /* If we cached the last index we looked at, let's try to not to jump too wildly + * around and see if we can limit the range to look at early to the immediate + * neighbors of the last index we looked at. */ - if (r == TEST_RIGHT) - right = x; - else - left = x + 1; - } - - if (last_index < right) { - uint64_t y = last_index + 1; - - p = journal_file_entry_array_item(f, array, y); - if (p <= 0) - return -EBADMSG; - - r = test_object(f, p, needle); - if (r < 0) - return r; - - if (r == TEST_FOUND) - r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT; + if (last_index > 0 && last_index - 1 < right) { + r = generic_array_bisect_one(f, a, last_index - 1, needle, test_object, direction, &left, &right, NULL); + if (r < 0 && r != -ENOANO) + return r; + } - if (r == TEST_RIGHT) - right = y; - else - left = y + 1; - } + if (last_index < right) { + r = generic_array_bisect_one(f, a, last_index + 1, needle, test_object, direction, &left, &right, NULL); + if (r < 0 && r != -ENOANO) + return r; } for (;;) { @@ -2928,26 +2935,9 @@ static int generic_array_bisect( assert(left < right); i = (left + right) / 2; - p = journal_file_entry_array_item(f, array, i); - if (p <= 0) - r = -EBADMSG; - else - r = test_object(f, p, needle); - if (IN_SET(r, -EBADMSG, -EADDRNOTAVAIL)) { - log_debug_errno(r, "Encountered invalid entry while bisecting, cutting algorithm short. (2)"); - right = n = i; - continue; - } - if (r < 0) + r = generic_array_bisect_one(f, a, i, needle, test_object, direction, &left, &right, NULL); + if (r < 0 && r != -ENOANO) return r; - - if (r == TEST_FOUND) - r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT; - - if (r == TEST_RIGHT) - right = i; - else - left = i + 1; } } |