This reduces the number of calls to journal_file_move_to_object() which are heavy.
All call sites have easy access to the data object so this change doesn't end up
complicating things.
JournaldFile *f;
struct iovec iovec;
static const char test[] = "TEST1=1", test2[] = "TEST2=2";
- Object *o;
+ Object *o, *d;
uint64_t p;
sd_id128_t fake_boot_id;
char t[] = "/var/tmp/journal-XXXXXX";
assert_se(journal_file_next_entry(f->file, 0, DIRECTION_DOWN, &o, &p) == 1);
assert_se(le64toh(o->entry.seqnum) == 1);
- assert_se(journal_file_find_data_object(f->file, test, strlen(test), NULL, &p) == 1);
- assert_se(journal_file_next_entry_for_data(f->file, p, DIRECTION_DOWN, &o, NULL) == 1);
+ assert_se(journal_file_find_data_object(f->file, test, strlen(test), &d, NULL) == 1);
+ assert_se(journal_file_next_entry_for_data(f->file, d, DIRECTION_DOWN, &o, NULL) == 1);
assert_se(le64toh(o->entry.seqnum) == 1);
- assert_se(journal_file_next_entry_for_data(f->file, p, DIRECTION_UP, &o, NULL) == 1);
+ assert_se(journal_file_next_entry_for_data(f->file, d, DIRECTION_UP, &o, NULL) == 1);
assert_se(le64toh(o->entry.seqnum) == 3);
- assert_se(journal_file_find_data_object(f->file, test2, strlen(test2), NULL, &p) == 1);
- assert_se(journal_file_next_entry_for_data(f->file, p, DIRECTION_UP, &o, NULL) == 1);
+ assert_se(journal_file_find_data_object(f->file, test2, strlen(test2), &d, NULL) == 1);
+ assert_se(journal_file_next_entry_for_data(f->file, d, DIRECTION_UP, &o, NULL) == 1);
assert_se(le64toh(o->entry.seqnum) == 2);
- assert_se(journal_file_next_entry_for_data(f->file, p, DIRECTION_DOWN, &o, NULL) == 1);
+ assert_se(journal_file_next_entry_for_data(f->file, d, DIRECTION_DOWN, &o, NULL) == 1);
assert_se(le64toh(o->entry.seqnum) == 2);
- assert_se(journal_file_find_data_object(f->file, "quux", 4, NULL, &p) == 0);
+ assert_se(journal_file_find_data_object(f->file, "quux", 4, &d, NULL) == 0);
assert_se(journal_file_move_to_entry_by_seqnum(f->file, 1, DIRECTION_DOWN, &o, NULL) == 1);
assert_se(le64toh(o->entry.seqnum) == 1);
int journal_file_next_entry_for_data(
JournalFile *f,
- uint64_t data_offset,
+ Object *d,
direction_t direction,
Object **ret, uint64_t *ret_offset) {
uint64_t i, n, ofs;
- Object *d;
int r;
assert(f);
-
- r = journal_file_move_to_object(f, OBJECT_DATA, data_offset, &d);
- if (r < 0)
- return r;
+ assert(d);
+ assert(d->object.type == OBJECT_DATA);
n = le64toh(READ_NOW(d->data.n_entries));
if (n <= 0)
int journal_file_move_to_entry_by_offset_for_data(
JournalFile *f,
- uint64_t data_offset,
+ Object *d,
uint64_t p,
direction_t direction,
Object **ret, uint64_t *ret_offset) {
- int r;
- Object *d;
-
assert(f);
-
- r = journal_file_move_to_object(f, OBJECT_DATA, data_offset, &d);
- if (r < 0)
- return r;
+ assert(d);
+ assert(d->object.type == OBJECT_DATA);
return generic_array_bisect_plus_one(
f,
int journal_file_move_to_entry_by_monotonic_for_data(
JournalFile *f,
- uint64_t data_offset,
+ Object *d,
sd_id128_t boot_id,
uint64_t monotonic,
direction_t direction,
Object **ret, uint64_t *ret_offset) {
- Object *o, *d;
+ Object *o;
int r;
- uint64_t b, z;
+ uint64_t b, z, entry_offset, entry_array_offset, n_entries;
assert(f);
+ assert(d);
+ assert(d->object.type == OBJECT_DATA);
+
+ /* Save all the required data before the data object gets invalidated. */
+ entry_offset = le64toh(READ_NOW(d->data.entry_offset));
+ entry_array_offset = le64toh(READ_NOW(d->data.entry_array_offset));
+ n_entries = le64toh(READ_NOW(d->data.n_entries));
/* First, seek by time */
r = find_data_object_by_boot_id(f, boot_id, &o, &b);
/* And now, continue seeking until we find an entry that
* exists in both bisection arrays */
+ r = journal_file_move_to_object(f, OBJECT_DATA, b, &o);
+ if (r < 0)
+ return r;
+
for (;;) {
Object *qo;
uint64_t p, q;
- r = journal_file_move_to_object(f, OBJECT_DATA, data_offset, &d);
- if (r < 0)
- return r;
-
r = generic_array_bisect_plus_one(f,
- le64toh(d->data.entry_offset),
- le64toh(d->data.entry_array_offset),
- le64toh(d->data.n_entries),
+ entry_offset,
+ entry_array_offset,
+ n_entries,
z,
test_object_offset,
direction,
if (r <= 0)
return r;
- r = journal_file_move_to_object(f, OBJECT_DATA, b, &o);
- if (r < 0)
- return r;
-
r = generic_array_bisect_plus_one(f,
le64toh(o->data.entry_offset),
le64toh(o->data.entry_array_offset),
int journal_file_move_to_entry_by_seqnum_for_data(
JournalFile *f,
- uint64_t data_offset,
+ Object *d,
uint64_t seqnum,
direction_t direction,
Object **ret, uint64_t *ret_offset) {
- Object *d;
- int r;
-
assert(f);
-
- r = journal_file_move_to_object(f, OBJECT_DATA, data_offset, &d);
- if (r < 0)
- return r;
+ assert(d);
+ assert(d->object.type == OBJECT_DATA);
return generic_array_bisect_plus_one(
f,
int journal_file_move_to_entry_by_realtime_for_data(
JournalFile *f,
- uint64_t data_offset,
+ Object *d,
uint64_t realtime,
direction_t direction,
Object **ret, uint64_t *ret_offset) {
- Object *d;
- int r;
-
assert(f);
-
- r = journal_file_move_to_object(f, OBJECT_DATA, data_offset, &d);
- if (r < 0)
- return r;
+ assert(d);
+ assert(d->object.type == OBJECT_DATA);
return generic_array_bisect_plus_one(
f,
int journal_file_compare_locations(JournalFile *af, JournalFile *bf);
int journal_file_next_entry(JournalFile *f, uint64_t p, direction_t direction, Object **ret, uint64_t *offset);
-int journal_file_next_entry_for_data(JournalFile *f, uint64_t data_offset, direction_t direction, Object **ret, uint64_t *offset);
+int journal_file_next_entry_for_data(JournalFile *f, Object *d, direction_t direction, Object **ret, uint64_t *offset);
int journal_file_move_to_entry_by_seqnum(JournalFile *f, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset);
int journal_file_move_to_entry_by_realtime(JournalFile *f, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset);
int journal_file_move_to_entry_by_monotonic(JournalFile *f, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret, uint64_t *offset);
-int journal_file_move_to_entry_by_offset_for_data(JournalFile *f, uint64_t data_offset, uint64_t p, direction_t direction, Object **ret, uint64_t *offset);
-int journal_file_move_to_entry_by_seqnum_for_data(JournalFile *f, uint64_t data_offset, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset);
-int journal_file_move_to_entry_by_realtime_for_data(JournalFile *f, uint64_t data_offset, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset);
-int journal_file_move_to_entry_by_monotonic_for_data(JournalFile *f, uint64_t data_offset, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret, uint64_t *offset);
+int journal_file_move_to_entry_by_offset_for_data(JournalFile *f, Object *d, uint64_t p, direction_t direction, Object **ret, uint64_t *offset);
+int journal_file_move_to_entry_by_seqnum_for_data(JournalFile *f, Object *d, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset);
+int journal_file_move_to_entry_by_realtime_for_data(JournalFile *f, Object *d, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset);
+int journal_file_move_to_entry_by_monotonic_for_data(JournalFile *f, Object *d, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret, uint64_t *offset);
int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p);
assert(f);
if (m->type == MATCH_DISCRETE) {
- uint64_t dp, hash;
+ Object *d;
+ uint64_t hash;
/* If the keyed hash logic is used, we need to calculate the hash fresh per file. Otherwise
* we can use what we pre-calculated. */
else
hash = m->hash;
- r = journal_file_find_data_object_with_hash(f, m->data, m->size, hash, NULL, &dp);
+ r = journal_file_find_data_object_with_hash(f, m->data, m->size, hash, &d, NULL);
if (r <= 0)
return r;
- return journal_file_move_to_entry_by_offset_for_data(f, dp, after_offset, direction, ret, offset);
+ return journal_file_move_to_entry_by_offset_for_data(f, d, after_offset, direction, ret, offset);
} else if (m->type == MATCH_OR_TERM) {
Match *i;
assert(f);
if (m->type == MATCH_DISCRETE) {
+ Object *d;
uint64_t dp, hash;
if (JOURNAL_HEADER_KEYED_HASH(f->header))
else
hash = m->hash;
- r = journal_file_find_data_object_with_hash(f, m->data, m->size, hash, NULL, &dp);
+ r = journal_file_find_data_object_with_hash(f, m->data, m->size, hash, &d, &dp);
if (r <= 0)
return r;
/* FIXME: missing: find by monotonic */
if (j->current_location.type == LOCATION_HEAD)
- return journal_file_next_entry_for_data(f, dp, DIRECTION_DOWN, ret, offset);
+ return journal_file_next_entry_for_data(f, d, DIRECTION_DOWN, ret, offset);
if (j->current_location.type == LOCATION_TAIL)
- return journal_file_next_entry_for_data(f, dp, DIRECTION_UP, ret, offset);
+ return journal_file_next_entry_for_data(f, d, DIRECTION_UP, ret, offset);
if (j->current_location.seqnum_set && sd_id128_equal(j->current_location.seqnum_id, f->header->seqnum_id))
- return journal_file_move_to_entry_by_seqnum_for_data(f, dp, j->current_location.seqnum, direction, ret, offset);
+ return journal_file_move_to_entry_by_seqnum_for_data(f, d, j->current_location.seqnum, direction, ret, offset);
if (j->current_location.monotonic_set) {
- r = journal_file_move_to_entry_by_monotonic_for_data(f, dp, j->current_location.boot_id, j->current_location.monotonic, direction, ret, offset);
+ r = journal_file_move_to_entry_by_monotonic_for_data(f, d, j->current_location.boot_id, j->current_location.monotonic, direction, ret, offset);
if (r != -ENOENT)
return r;
+
+ /* The data object might have been invalidated. */
+ r = journal_file_move_to_object(f, OBJECT_DATA, dp, &d);
+ if (r < 0)
+ return r;
}
if (j->current_location.realtime_set)
- return journal_file_move_to_entry_by_realtime_for_data(f, dp, j->current_location.realtime, direction, ret, offset);
+ return journal_file_move_to_entry_by_realtime_for_data(f, d, j->current_location.realtime, direction, ret, offset);
- return journal_file_next_entry_for_data(f, dp, direction, ret, offset);
+ return journal_file_next_entry_for_data(f, d, direction, ret, offset);
} else if (m->type == MATCH_OR_TERM) {
uint64_t np = 0;