[systemd-commits] 15 commits - src/journal

Michal Schmidt michich at kemper.freedesktop.org
Thu Dec 18 06:04:11 PST 2014


 src/journal/journal-file.c     |  147 +++++++++++++++---------------
 src/journal/journal-file.h     |   28 +++++
 src/journal/journal-internal.h |   14 --
 src/journal/sd-journal.c       |  197 ++++++-----------------------------------
 src/journal/test-journal.c     |   19 +--
 5 files changed, 138 insertions(+), 267 deletions(-)

New commits:
commit c2551e7105051f40b2bf77a5c1ecb2e720d78d77
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Wed Dec 17 15:46:30 2014 +0100

    journal: next_with_matches() now does not need a mapped object as input
    
    Now that journal_file_next_entry() does not need a pointer to the
    current object, next_with_matches() does not need it either.

diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index bcd39be..285e5e3 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -748,10 +748,6 @@ static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direc
 
                 cp = f->current_offset;
 
-                r = journal_file_move_to_object(f, OBJECT_ENTRY, cp, &c);
-                if (r < 0)
-                        return r;
-
                 r = next_with_matches(j, f, direction, &c, &cp);
                 if (r <= 0)
                         return r;

commit f534928ad7aaeec0bec2d653b4a50e79b0fc8418
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Wed Dec 17 15:45:10 2014 +0100

    journal: journal_file_next_entry() does not need pointer to current Object
    
    The current offset is sufficient information.

diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 35f3ea9..fec54f3 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -2003,7 +2003,7 @@ int journal_file_compare_locations(JournalFile *af, JournalFile *bf) {
 
 int journal_file_next_entry(
                 JournalFile *f,
-                Object *o, uint64_t p,
+                uint64_t p,
                 direction_t direction,
                 Object **ret, uint64_t *offset) {
 
@@ -2011,18 +2011,14 @@ int journal_file_next_entry(
         int r;
 
         assert(f);
-        assert(p > 0 || !o);
 
         n = le64toh(f->header->n_entries);
         if (n <= 0)
                 return 0;
 
-        if (!o)
+        if (p == 0)
                 i = direction == DIRECTION_DOWN ? 0 : n - 1;
         else {
-                if (o->object.type != OBJECT_ENTRY)
-                        return -EINVAL;
-
                 r = generic_array_bisect(f,
                                          le64toh(f->header->entry_array_offset),
                                          le64toh(f->header->n_entries),
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index 561982f..01bb4e0 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -199,7 +199,7 @@ int journal_file_find_field_object_with_hash(JournalFile *f, const void *field,
 void journal_file_reset_location(JournalFile *f);
 void journal_file_save_location(JournalFile *f, direction_t direction, Object *o, uint64_t offset);
 int journal_file_compare_locations(JournalFile *af, JournalFile *bf);
-int journal_file_next_entry(JournalFile *f, Object *o, uint64_t p, direction_t direction, Object **ret, uint64_t *offset);
+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, Object *o, uint64_t p, uint64_t data_offset, direction_t direction, Object **ret, uint64_t *offset);
 
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 0fefe2b..bcd39be 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -681,9 +681,9 @@ static int find_location_with_matches(
                 /* No matches is simple */
 
                 if (j->current_location.type == LOCATION_HEAD)
-                        return journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, ret, offset);
+                        return journal_file_next_entry(f, 0, DIRECTION_DOWN, ret, offset);
                 if (j->current_location.type == LOCATION_TAIL)
-                        return journal_file_next_entry(f, NULL, 0, DIRECTION_UP, ret, offset);
+                        return journal_file_next_entry(f, 0, 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(f, j->current_location.seqnum, direction, ret, offset);
                 if (j->current_location.monotonic_set) {
@@ -694,7 +694,7 @@ static int find_location_with_matches(
                 if (j->current_location.realtime_set)
                         return journal_file_move_to_entry_by_realtime(f, j->current_location.realtime, direction, ret, offset);
 
-                return journal_file_next_entry(f, NULL, 0, direction, ret, offset);
+                return journal_file_next_entry(f, 0, direction, ret, offset);
         } else
                 return find_location_for_match(j, j->level0, f, direction, ret, offset);
 }
@@ -706,7 +706,6 @@ static int next_with_matches(
                 Object **ret,
                 uint64_t *offset) {
 
-        Object *c;
         uint64_t cp;
 
         assert(j);
@@ -714,13 +713,12 @@ static int next_with_matches(
         assert(ret);
         assert(offset);
 
-        c = *ret;
         cp = *offset;
 
         /* No matches is easy. We simple advance the file
          * pointer by one. */
         if (!j->level0)
-                return journal_file_next_entry(f, c, cp, direction, ret, offset);
+                return journal_file_next_entry(f, cp, direction, ret, offset);
 
         /* If we have a match then we look for the next matching entry
          * with an offset at least one step larger */
diff --git a/src/journal/test-journal.c b/src/journal/test-journal.c
index 29d5877..230d265 100644
--- a/src/journal/test-journal.c
+++ b/src/journal/test-journal.c
@@ -66,18 +66,18 @@ static void test_non_empty(void) {
 #endif
         journal_file_dump(f);
 
-        assert_se(journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, &o, &p) == 1);
+        assert_se(journal_file_next_entry(f, 0, DIRECTION_DOWN, &o, &p) == 1);
         assert_se(le64toh(o->entry.seqnum) == 1);
 
-        assert_se(journal_file_next_entry(f, o, p, DIRECTION_DOWN, &o, &p) == 1);
+        assert_se(journal_file_next_entry(f, p, DIRECTION_DOWN, &o, &p) == 1);
         assert_se(le64toh(o->entry.seqnum) == 2);
 
-        assert_se(journal_file_next_entry(f, o, p, DIRECTION_DOWN, &o, &p) == 1);
+        assert_se(journal_file_next_entry(f, p, DIRECTION_DOWN, &o, &p) == 1);
         assert_se(le64toh(o->entry.seqnum) == 3);
 
-        assert_se(journal_file_next_entry(f, o, p, DIRECTION_DOWN, &o, &p) == 0);
+        assert_se(journal_file_next_entry(f, p, DIRECTION_DOWN, &o, &p) == 0);
 
-        assert_se(journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, &o, &p) == 1);
+        assert_se(journal_file_next_entry(f, 0, DIRECTION_DOWN, &o, &p) == 1);
         assert_se(le64toh(o->entry.seqnum) == 1);
 
         assert_se(journal_file_find_data_object(f, test, strlen(test), NULL, &p) == 1);

commit 7943f42275025e1b6642b580b19b24dfab8dee61
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Wed Dec 17 15:07:25 2014 +0100

    journal: optimize iteration by returning previously found candidate entry
    
    In next_beyond_location() when the JournalFile's location type is
    LOCATION_SEEK, it means there's nothing to do, because we already have
    the location of the candidate entry. Do an early return. Note that now
    next_beyond_location() does not anymore guarantee on return that the
    entry is mapped, but previous patches made sure the caller does not
    care.
    
    This optimization is at least as good as "journal: optimize iteration:
    skip files that cannot improve current candidate entry" was.
    
    Timing results on my workstation, using:
    $ time ./journalctl -q --since=2014-06-01 --until=2014-07-01 > /dev/null
    
    Before "Revert "journal: optimize iteration: skip files that cannot
    improve current candidate entry":
    
    real    0m5.349s
    user    0m5.166s
    sys     0m0.181s
    
    Now:
    
    real    0m3.901s
    user    0m3.724s
    sys     0m0.176s

diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 0aaf225..0fefe2b 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -742,6 +742,12 @@ static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direc
         f->last_n_entries = n_entries;
 
         if (f->last_direction == direction && f->current_offset > 0) {
+                /* LOCATION_SEEK here means we did the work in a previous
+                 * iteration and the current location already points to a
+                 * candidate entry. */
+                if (f->location_type == LOCATION_SEEK)
+                        return 1;
+
                 cp = f->current_offset;
 
                 r = journal_file_move_to_object(f, OBJECT_ENTRY, cp, &c);

commit 6e693b42dcb0b332364b0414107826826925c49f
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Thu Dec 18 14:21:55 2014 +0100

    journal: optimize iteration by skipping exhausted files
    
    If from a previous iteration we know we are at the end of a journal
    file, don't bother looking into the file again. This is complicated by
    the fact that the EOF does not have to be permanent (think of
    "journalctl -f"). So we also check if the number of entries in the
    journal file changed.
    
    This optimization has a similar effect as "journal: optimize iteration:
    skip whole files behind current location" had.

diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index 8084176..561982f 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -78,6 +78,7 @@ typedef struct JournalFile {
 
         direction_t last_direction;
         LocationType location_type;
+        uint64_t last_n_entries;
 
         char *path;
         struct stat last_stat;
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index f3aae9b..0aaf225 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -729,12 +729,18 @@ static int next_with_matches(
 
 static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direction) {
         Object *c;
-        uint64_t cp;
+        uint64_t cp, n_entries;
         int r;
 
         assert(j);
         assert(f);
 
+        /* If we hit EOF before, recheck if any new entries arrived. */
+        n_entries = le64toh(f->header->n_entries);
+        if (f->location_type == LOCATION_TAIL && n_entries == f->last_n_entries)
+                return 0;
+        f->last_n_entries = n_entries;
+
         if (f->last_direction == direction && f->current_offset > 0) {
                 cp = f->current_offset;
 

commit 58439db4cc45a6f84a74ad73f873bd3c113eebf6
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Wed Dec 17 15:37:52 2014 +0100

    journal: drop unnecessary parameters of next_beyond_location()
    
    offset is redundant, because the caller can rely on f->current_offset.
    The object pointer the function saves in *ret is thrown away by the caller.

diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 8cf6de6..f3aae9b 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -727,7 +727,7 @@ static int next_with_matches(
         return next_for_match(j, j->level0, f, direction == DIRECTION_DOWN ? cp+1 : cp-1, direction, ret, offset);
 }
 
-static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direction, Object **ret, uint64_t *offset) {
+static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direction) {
         Object *c;
         uint64_t cp;
         int r;
@@ -771,11 +771,6 @@ static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direc
 
                 if (found) {
                         journal_file_save_location(f, direction, c, cp);
-
-                        if (ret)
-                                *ret = c;
-                        if (offset)
-                                *offset = cp;
                         return 1;
                 }
 
@@ -787,7 +782,6 @@ static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direc
 
 static int real_journal_next(sd_journal *j, direction_t direction) {
         JournalFile *f, *new_file = NULL;
-        uint64_t p = 0;
         Iterator i;
         Object *o;
         int r;
@@ -798,7 +792,7 @@ static int real_journal_next(sd_journal *j, direction_t direction) {
         ORDERED_HASHMAP_FOREACH(f, j->files, i) {
                 bool found;
 
-                r = next_beyond_location(j, f, direction, &o, &p);
+                r = next_beyond_location(j, f, direction);
                 if (r < 0) {
                         log_debug_errno(r, "Can't iterate through %s, ignoring: %m", f->path);
                         remove_file_real(j, f);

commit e499c9998bb42b792afb1acd3532fe975280c0fd
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Thu Dec 18 09:56:04 2014 +0100

    journal: remove redundant variable new_offset
    
    The file's current_offset is already updated at this point, so let's use
    it.

diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 7ca0f83..8cf6de6 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -787,7 +787,6 @@ static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direc
 
 static int real_journal_next(sd_journal *j, direction_t direction) {
         JournalFile *f, *new_file = NULL;
-        uint64_t new_offset = 0;
         uint64_t p = 0;
         Iterator i;
         Object *o;
@@ -819,16 +818,14 @@ static int real_journal_next(sd_journal *j, direction_t direction) {
                         found = direction == DIRECTION_DOWN ? k < 0 : k > 0;
                 }
 
-                if (found) {
+                if (found)
                         new_file = f;
-                        new_offset = p;
-                }
         }
 
         if (!new_file)
                 return 0;
 
-        r = journal_file_move_to_object(new_file, OBJECT_ENTRY, new_offset, &o);
+        r = journal_file_move_to_object(new_file, OBJECT_ENTRY, new_file->current_offset, &o);
         if (r < 0)
                 return r;
 

commit d8ae66d7faee23a74a69119270bf622100705f72
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Wed Dec 17 14:06:28 2014 +0100

    journal: compare candidate entries using JournalFiles' locations
    
    When comparing the locations of candidate entries, we can rely on the
    location information stored in struct JournalFile.

diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 7b9815c..35f3ea9 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -1949,6 +1949,58 @@ void journal_file_save_location(JournalFile *f, direction_t direction, Object *o
         f->current_xor_hash = le64toh(o->entry.xor_hash);
 }
 
+int journal_file_compare_locations(JournalFile *af, JournalFile *bf) {
+        assert(af);
+        assert(bf);
+        assert(af->location_type == LOCATION_SEEK);
+        assert(bf->location_type == LOCATION_SEEK);
+
+        /* If contents and timestamps match, these entries are
+         * identical, even if the seqnum does not match */
+        if (sd_id128_equal(af->current_boot_id, bf->current_boot_id) &&
+            af->current_monotonic == bf->current_monotonic &&
+            af->current_realtime == bf->current_realtime &&
+            af->current_xor_hash == bf->current_xor_hash)
+                return 0;
+
+        if (sd_id128_equal(af->header->seqnum_id, bf->header->seqnum_id)) {
+
+                /* If this is from the same seqnum source, compare
+                 * seqnums */
+                if (af->current_seqnum < bf->current_seqnum)
+                        return -1;
+                if (af->current_seqnum > bf->current_seqnum)
+                        return 1;
+
+                /* Wow! This is weird, different data but the same
+                 * seqnums? Something is borked, but let's make the
+                 * best of it and compare by time. */
+        }
+
+        if (sd_id128_equal(af->current_boot_id, bf->current_boot_id)) {
+
+                /* If the boot id matches, compare monotonic time */
+                if (af->current_monotonic < bf->current_monotonic)
+                        return -1;
+                if (af->current_monotonic > bf->current_monotonic)
+                        return 1;
+        }
+
+        /* Otherwise, compare UTC time */
+        if (af->current_realtime < bf->current_realtime)
+                return -1;
+        if (af->current_realtime > bf->current_realtime)
+                return 1;
+
+        /* Finally, compare by contents */
+        if (af->current_xor_hash < bf->current_xor_hash)
+                return -1;
+        if (af->current_xor_hash > bf->current_xor_hash)
+                return 1;
+
+        return 0;
+}
+
 int journal_file_next_entry(
                 JournalFile *f,
                 Object *o, uint64_t p,
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index 2bdfff7..8084176 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -197,6 +197,7 @@ int journal_file_find_field_object_with_hash(JournalFile *f, const void *field,
 
 void journal_file_reset_location(JournalFile *f);
 void journal_file_save_location(JournalFile *f, direction_t direction, Object *o, uint64_t offset);
+int journal_file_compare_locations(JournalFile *af, JournalFile *bf);
 int journal_file_next_entry(JournalFile *f, Object *o, uint64_t p, direction_t direction, Object **ret, uint64_t *offset);
 
 int journal_file_next_entry_for_data(JournalFile *f, Object *o, uint64_t p, uint64_t data_offset, direction_t direction, Object **ret, uint64_t *offset);
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 5a00cb0..7ca0f83 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -412,90 +412,6 @@ _public_ void sd_journal_flush_matches(sd_journal *j) {
         detach_location(j);
 }
 
-static int compare_entry_order(JournalFile *af, Object *_ao,
-                               JournalFile *bf, uint64_t bp) {
-
-        uint64_t a, b;
-        Object *ao, *bo;
-        int r;
-
-        assert(af);
-        assert(bf);
-        assert(_ao);
-
-        /* The mmap cache might invalidate the object from the first
-         * file if we look at the one from the second file. Hence
-         * temporarily copy the header of the first one, and look at
-         * that only. */
-        ao = alloca(offsetof(EntryObject, items));
-        memcpy(ao, _ao, offsetof(EntryObject, items));
-
-        r = journal_file_move_to_object(bf, OBJECT_ENTRY, bp, &bo);
-        if (r < 0)
-                return strcmp(af->path, bf->path);
-
-        /* We operate on two different files here, hence we can access
-         * two objects at the same time, which we normally can't.
-         *
-         * If contents and timestamps match, these entries are
-         * identical, even if the seqnum does not match */
-
-        if (sd_id128_equal(ao->entry.boot_id, bo->entry.boot_id) &&
-            ao->entry.monotonic == bo->entry.monotonic &&
-            ao->entry.realtime == bo->entry.realtime &&
-            ao->entry.xor_hash == bo->entry.xor_hash)
-                return 0;
-
-        if (sd_id128_equal(af->header->seqnum_id, bf->header->seqnum_id)) {
-
-                /* If this is from the same seqnum source, compare
-                 * seqnums */
-                a = le64toh(ao->entry.seqnum);
-                b = le64toh(bo->entry.seqnum);
-
-                if (a < b)
-                        return -1;
-                if (a > b)
-                        return 1;
-
-                /* Wow! This is weird, different data but the same
-                 * seqnums? Something is borked, but let's make the
-                 * best of it and compare by time. */
-        }
-
-        if (sd_id128_equal(ao->entry.boot_id, bo->entry.boot_id)) {
-
-                /* If the boot id matches, compare monotonic time */
-                a = le64toh(ao->entry.monotonic);
-                b = le64toh(bo->entry.monotonic);
-
-                if (a < b)
-                        return -1;
-                if (a > b)
-                        return 1;
-        }
-
-        /* Otherwise, compare UTC time */
-        a = le64toh(ao->entry.realtime);
-        b = le64toh(bo->entry.realtime);
-
-        if (a < b)
-                return -1;
-        if (a > b)
-                return 1;
-
-        /* Finally, compare by contents */
-        a = le64toh(ao->entry.xor_hash);
-        b = le64toh(bo->entry.xor_hash);
-
-        if (a < b)
-                return -1;
-        if (a > b)
-                return 1;
-
-        return 0;
-}
-
 _pure_ static int compare_with_location(JournalFile *af, Object *ao, Location *l) {
         uint64_t a;
 
@@ -898,7 +814,7 @@ static int real_journal_next(sd_journal *j, direction_t direction) {
                 else {
                         int k;
 
-                        k = compare_entry_order(f, o, new_file, new_offset);
+                        k = journal_file_compare_locations(f, new_file);
 
                         found = direction == DIRECTION_DOWN ? k < 0 : k > 0;
                 }

commit 1eb6332d557e6e510a9ce723296cb3b658d7e9a4
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Tue Dec 16 22:38:09 2014 +0100

    journal: simplify set_location()
    
    set_location() is called from real_journal_next() when a winning entry
    has been picked from among the candidates in journal files.
    
    The location type is always set to LOCATION_DISCRETE. No need to pass
    it as a parameter.
    The per-JournalFile location information is already updated at this
    point. No need for having the direction and offset here.

diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 71b056c..5a00cb0 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -114,21 +114,16 @@ static void init_location(Location *l, LocationType type, JournalFile *f, Object
         l->seqnum_set = l->realtime_set = l->monotonic_set = l->xor_hash_set = true;
 }
 
-static void set_location(sd_journal *j, LocationType type, JournalFile *f, Object *o,
-                         direction_t direction, uint64_t offset) {
+static void set_location(sd_journal *j, JournalFile *f, Object *o) {
         assert(j);
-        assert(type == LOCATION_DISCRETE || type == LOCATION_SEEK);
         assert(f);
         assert(o);
 
-        init_location(&j->current_location, type, f, o);
+        init_location(&j->current_location, LOCATION_DISCRETE, f, o);
 
         j->current_file = f;
         j->current_field = 0;
 
-        f->last_direction = direction;
-        f->current_offset = offset;
-
         /* Let f know its candidate entry was picked. */
         assert(f->location_type == LOCATION_SEEK);
         f->location_type = LOCATION_DISCRETE;
@@ -921,7 +916,7 @@ static int real_journal_next(sd_journal *j, direction_t direction) {
         if (r < 0)
                 return r;
 
-        set_location(j, LOCATION_DISCRETE, new_file, o, direction, new_offset);
+        set_location(j, new_file, o);
 
         return 1;
 }

commit 6573ef05a3cbe15949acfbbf1ad03726068907bd
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Tue Dec 16 21:03:36 2014 +0100

    journal: keep per-JournalFile location info during iteration
    
    In next_beyond_location() when we find a candidate entry in a journal
    file, save its location information in struct JournalFile.
    
    The purpose of remembering the locations of candidate entries is to be
    able to save work in the next iteration. This patch does only the
    remembering part.
    
    LOCATION_SEEK means the location identifies a candidate entry.
    When a winner is picked from among candidates, it becomes
    LOCATION_DISCRETE.
    LOCATION_TAIL here signifies we've iterated the file to the end (or the
    beginning in the case of reversed direction).

diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 8cbdbb9..7b9815c 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -1929,7 +1929,24 @@ int journal_file_move_to_entry_by_monotonic(
 }
 
 void journal_file_reset_location(JournalFile *f) {
+        f->location_type = LOCATION_HEAD;
         f->current_offset = 0;
+        f->current_seqnum = 0;
+        f->current_realtime = 0;
+        f->current_monotonic = 0;
+        zero(f->current_boot_id);
+        f->current_xor_hash = 0;
+}
+
+void journal_file_save_location(JournalFile *f, direction_t direction, Object *o, uint64_t offset) {
+        f->last_direction = direction;
+        f->location_type = LOCATION_SEEK;
+        f->current_offset = offset;
+        f->current_seqnum = le64toh(o->entry.seqnum);
+        f->current_realtime = le64toh(o->entry.realtime);
+        f->current_monotonic = le64toh(o->entry.monotonic);
+        f->current_boot_id = o->entry.boot_id;
+        f->current_xor_hash = le64toh(o->entry.xor_hash);
 }
 
 int journal_file_next_entry(
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index 3a19827..2bdfff7 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -77,6 +77,7 @@ typedef struct JournalFile {
         bool tail_entry_monotonic_valid:1;
 
         direction_t last_direction;
+        LocationType location_type;
 
         char *path;
         struct stat last_stat;
@@ -86,6 +87,11 @@ typedef struct JournalFile {
         HashItem *field_hash_table;
 
         uint64_t current_offset;
+        uint64_t current_seqnum;
+        uint64_t current_realtime;
+        uint64_t current_monotonic;
+        sd_id128_t current_boot_id;
+        uint64_t current_xor_hash;
 
         JournalMetrics metrics;
         MMapCache *mmap;
@@ -190,6 +196,7 @@ int journal_file_find_field_object(JournalFile *f, const void *field, uint64_t s
 int journal_file_find_field_object_with_hash(JournalFile *f, const void *field, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset);
 
 void journal_file_reset_location(JournalFile *f);
+void journal_file_save_location(JournalFile *f, direction_t direction, Object *o, uint64_t offset);
 int journal_file_next_entry(JournalFile *f, Object *o, uint64_t p, direction_t direction, Object **ret, uint64_t *offset);
 
 int journal_file_next_entry_for_data(JournalFile *f, Object *o, uint64_t p, uint64_t data_offset, direction_t direction, Object **ret, uint64_t *offset);
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index adaf402..71b056c 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -128,6 +128,10 @@ static void set_location(sd_journal *j, LocationType type, JournalFile *f, Objec
 
         f->last_direction = direction;
         f->current_offset = offset;
+
+        /* Let f know its candidate entry was picked. */
+        assert(f->location_type == LOCATION_SEEK);
+        f->location_type = LOCATION_DISCRETE;
 }
 
 static int match_is_valid(const void *data, size_t size) {
@@ -855,6 +859,8 @@ static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direc
                         found = true;
 
                 if (found) {
+                        journal_file_save_location(f, direction, c, cp);
+
                         if (ret)
                                 *ret = c;
                         if (offset)
@@ -887,8 +893,10 @@ static int real_journal_next(sd_journal *j, direction_t direction) {
                         log_debug_errno(r, "Can't iterate through %s, ignoring: %m", f->path);
                         remove_file_real(j, f);
                         continue;
-                } else if (r == 0)
+                } else if (r == 0) {
+                        f->location_type = LOCATION_TAIL;
                         continue;
+                }
 
                 if (!new_file)
                         found = true;

commit 1fc605b0e130149a44abfa38c33f4535cfe548ea
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Tue Dec 16 20:54:56 2014 +0100

    journal: abstract the resetting of JournalFile's location

diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index efe14b0..8cbdbb9 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -1928,6 +1928,10 @@ int journal_file_move_to_entry_by_monotonic(
                                              ret, offset, NULL);
 }
 
+void journal_file_reset_location(JournalFile *f) {
+        f->current_offset = 0;
+}
+
 int journal_file_next_entry(
                 JournalFile *f,
                 Object *o, uint64_t p,
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index b14d0fc..3a19827 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -189,6 +189,7 @@ int journal_file_find_data_object_with_hash(JournalFile *f, const void *data, ui
 int journal_file_find_field_object(JournalFile *f, const void *field, uint64_t size, Object **ret, uint64_t *offset);
 int journal_file_find_field_object_with_hash(JournalFile *f, const void *field, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset);
 
+void journal_file_reset_location(JournalFile *f);
 int journal_file_next_entry(JournalFile *f, Object *o, uint64_t p, direction_t direction, Object **ret, uint64_t *offset);
 
 int journal_file_next_entry_for_data(JournalFile *f, Object *o, uint64_t p, uint64_t data_offset, direction_t direction, Object **ret, uint64_t *offset);
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 72c9770..adaf402 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -87,7 +87,7 @@ static void detach_location(sd_journal *j) {
         j->current_field = 0;
 
         ORDERED_HASHMAP_FOREACH(f, j->files, i)
-                f->current_offset = 0;
+                journal_file_reset_location(f);
 }
 
 static void reset_location(sd_journal *j) {

commit 99cc7653a83af6647f28ac0cbedf6f6062e92b72
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Tue Dec 16 20:51:58 2014 +0100

    journal: move definition of LocationType to journal-file.h
    
    In preparation for individual JournalFiles maintaining a location
    of their own.

diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index 3514bef..b14d0fc 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -48,6 +48,20 @@ typedef enum direction {
         DIRECTION_DOWN
 } direction_t;
 
+typedef enum LocationType {
+        /* The first and last entries, resp. */
+        LOCATION_HEAD,
+        LOCATION_TAIL,
+
+        /* We already read the entry we currently point to, and the
+         * next one to read should probably not be this one again. */
+        LOCATION_DISCRETE,
+
+        /* We should seek to the precise location specified, and
+         * return it, as we haven't read it yet. */
+        LOCATION_SEEK
+} LocationType;
+
 typedef struct JournalFile {
         int fd;
 
diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h
index 70847db..e99050c 100644
--- a/src/journal/journal-internal.h
+++ b/src/journal/journal-internal.h
@@ -57,20 +57,6 @@ struct Match {
         LIST_HEAD(Match, matches);
 };
 
-typedef enum LocationType {
-        /* The first and last entries, resp. */
-        LOCATION_HEAD,
-        LOCATION_TAIL,
-
-        /* We already read the entry we currently point to, and the
-         * next one to read should probably not be this one again. */
-        LOCATION_DISCRETE,
-
-        /* We should seek to the precise location specified, and
-         * return it, as we haven't read it yet. */
-        LOCATION_SEEK
-} LocationType;
-
 struct Location {
         LocationType type;
 

commit 8a2bd0a365b203a3c42de75d5c907a5c540fbb13
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Tue Dec 16 20:32:41 2014 +0100

    Revert "journal: optimize iteration: skip whole files behind current location"
    
    This reverts commit b7c88ab8cc7d55a43450bf3dea750f95f2e910d6.
    
    This optimization will be made redundant by the following patches.

diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 15cc1fc..72c9770 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -497,26 +497,6 @@ static int compare_entry_order(JournalFile *af, Object *_ao,
         return 0;
 }
 
-static bool whole_file_precedes_location(JournalFile *f, Location *l, direction_t direction) {
-        assert(f);
-        assert(l);
-
-        if (l->type != LOCATION_DISCRETE && l->type != LOCATION_SEEK)
-                return false;
-
-        if (l->seqnum_set && sd_id128_equal(l->seqnum_id, f->header->seqnum_id))
-                return direction == DIRECTION_DOWN ?
-                        l->seqnum > le64toh(f->header->tail_entry_seqnum) :
-                        l->seqnum < le64toh(f->header->head_entry_seqnum);
-
-        if (l->realtime_set)
-                return direction == DIRECTION_DOWN ?
-                        l->realtime > le64toh(f->header->tail_entry_realtime) :
-                        l->realtime < le64toh(f->header->head_entry_realtime);
-
-        return false;
-}
-
 _pure_ static int compare_with_location(JournalFile *af, Object *ao, Location *l) {
         uint64_t a;
 
@@ -902,9 +882,6 @@ static int real_journal_next(sd_journal *j, direction_t direction) {
         ORDERED_HASHMAP_FOREACH(f, j->files, i) {
                 bool found;
 
-                if (whole_file_precedes_location(f, &j->current_location, direction))
-                        continue;
-
                 r = next_beyond_location(j, f, direction, &o, &p);
                 if (r < 0) {
                         log_debug_errno(r, "Can't iterate through %s, ignoring: %m", f->path);

commit 0633cb5206924bb6fe183804eda2b696ae352cca
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Tue Dec 16 20:32:34 2014 +0100

    Revert "journal: optimize iteration: skip files that cannot improve current candidate entry"
    
    This reverts commit f8b5a3b75fb55f0acb85c21424b3893c822742e9.
    
    This optimization will be made redundant by the following patches.

diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index be08a92..15cc1fc 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -517,27 +517,6 @@ static bool whole_file_precedes_location(JournalFile *f, Location *l, direction_
         return false;
 }
 
-static bool file_may_have_preceding_entry(JournalFile *f, JournalFile *of, uint64_t op, direction_t direction) {
-        Object *o;
-        int r;
-
-        assert(f);
-        assert(of);
-
-        r = journal_file_move_to_object(of, OBJECT_ENTRY, op, &o);
-        if (r < 0)
-                return true;
-
-        if (sd_id128_equal(f->header->seqnum_id, of->header->seqnum_id))
-                return direction == DIRECTION_DOWN ?
-                        le64toh(o->entry.seqnum) >= le64toh(f->header->head_entry_seqnum) :
-                        le64toh(o->entry.seqnum) <= le64toh(f->header->tail_entry_seqnum);
-
-        return direction == DIRECTION_DOWN ?
-                le64toh(o->entry.realtime) >= le64toh(f->header->head_entry_realtime) :
-                le64toh(o->entry.realtime) <= le64toh(f->header->tail_entry_realtime);
-}
-
 _pure_ static int compare_with_location(JournalFile *af, Object *ao, Location *l) {
         uint64_t a;
 
@@ -926,9 +905,6 @@ static int real_journal_next(sd_journal *j, direction_t direction) {
                 if (whole_file_precedes_location(f, &j->current_location, direction))
                         continue;
 
-                if (new_file && !file_may_have_preceding_entry(f, new_file, new_offset, direction))
-                        continue;
-
                 r = next_beyond_location(j, f, direction, &o, &p);
                 if (r < 0) {
                         log_debug_errno(r, "Can't iterate through %s, ignoring: %m", f->path);

commit 14499361a537f769fadfb2e9323c8a65d31e6862
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Tue Dec 16 15:47:01 2014 +0100

    journal: delete unused function journal_file_skip_entry()
    
    Its only caller is a test.

diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 75a7c11..efe14b0 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -1995,55 +1995,6 @@ int journal_file_next_entry(
         return 1;
 }
 
-int journal_file_skip_entry(
-                JournalFile *f,
-                Object *o, uint64_t p,
-                int64_t skip,
-                Object **ret, uint64_t *offset) {
-
-        uint64_t i, n;
-        int r;
-
-        assert(f);
-        assert(o);
-        assert(p > 0);
-
-        if (o->object.type != OBJECT_ENTRY)
-                return -EINVAL;
-
-        r = generic_array_bisect(f,
-                                 le64toh(f->header->entry_array_offset),
-                                 le64toh(f->header->n_entries),
-                                 p,
-                                 test_object_offset,
-                                 DIRECTION_DOWN,
-                                 NULL, NULL,
-                                 &i);
-        if (r <= 0)
-                return r;
-
-        /* Calculate new index */
-        if (skip < 0) {
-                if ((uint64_t) -skip >= i)
-                        i = 0;
-                else
-                        i = i - (uint64_t) -skip;
-        } else
-                i  += (uint64_t) skip;
-
-        n = le64toh(f->header->n_entries);
-        if (n <= 0)
-                return -EBADMSG;
-
-        if (i >= n)
-                i = n-1;
-
-        return generic_array_get(f,
-                                 le64toh(f->header->entry_array_offset),
-                                 i,
-                                 ret, offset);
-}
-
 int journal_file_next_entry_for_data(
                 JournalFile *f,
                 Object *o, uint64_t p,
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index 8c3f308..3514bef 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -176,7 +176,6 @@ int journal_file_find_field_object(JournalFile *f, const void *field, uint64_t s
 int journal_file_find_field_object_with_hash(JournalFile *f, const void *field, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset);
 
 int journal_file_next_entry(JournalFile *f, Object *o, uint64_t p, direction_t direction, Object **ret, uint64_t *offset);
-int journal_file_skip_entry(JournalFile *f, Object *o, uint64_t p, int64_t skip, Object **ret, uint64_t *offset);
 
 int journal_file_next_entry_for_data(JournalFile *f, Object *o, uint64_t p, uint64_t data_offset, direction_t direction, Object **ret, uint64_t *offset);
 
diff --git a/src/journal/test-journal.c b/src/journal/test-journal.c
index ff9dc9e..29d5877 100644
--- a/src/journal/test-journal.c
+++ b/src/journal/test-journal.c
@@ -80,15 +80,6 @@ static void test_non_empty(void) {
         assert_se(journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, &o, &p) == 1);
         assert_se(le64toh(o->entry.seqnum) == 1);
 
-        assert_se(journal_file_skip_entry(f, o, p, 2, &o, &p) == 1);
-        assert_se(le64toh(o->entry.seqnum) == 3);
-
-        assert_se(journal_file_skip_entry(f, o, p, -2, &o, &p) == 1);
-        assert_se(le64toh(o->entry.seqnum) == 1);
-
-        assert_se(journal_file_skip_entry(f, o, p, -2, &o, &p) == 1);
-        assert_se(le64toh(o->entry.seqnum) == 1);
-
         assert_se(journal_file_find_data_object(f, test, strlen(test), NULL, &p) == 1);
         assert_se(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_DOWN, &o, NULL) == 1);
         assert_se(le64toh(o->entry.seqnum) == 1);

commit ae2adbcd09bd383b5a18728dfd32cf604c2c910e
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Tue Dec 16 19:06:30 2014 +0100

    journal: delete unused function journal_file_move_to_entry_by_offset()

diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 7cdaf29..75a7c11 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -1799,23 +1799,6 @@ _pure_ static int test_object_offset(JournalFile *f, uint64_t p, uint64_t needle
                 return TEST_RIGHT;
 }
 
-int journal_file_move_to_entry_by_offset(
-                JournalFile *f,
-                uint64_t p,
-                direction_t direction,
-                Object **ret,
-                uint64_t *offset) {
-
-        return generic_array_bisect(f,
-                                    le64toh(f->header->entry_array_offset),
-                                    le64toh(f->header->n_entries),
-                                    p,
-                                    test_object_offset,
-                                    direction,
-                                    ret, offset, NULL);
-}
-
-
 static int test_object_seqnum(JournalFile *f, uint64_t p, uint64_t needle) {
         Object *o;
         int r;
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index a4a172b..8c3f308 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -180,7 +180,6 @@ int journal_file_skip_entry(JournalFile *f, Object *o, uint64_t p, int64_t skip,
 
 int journal_file_next_entry_for_data(JournalFile *f, Object *o, uint64_t p, uint64_t data_offset, direction_t direction, Object **ret, uint64_t *offset);
 
-int journal_file_move_to_entry_by_offset(JournalFile *f, uint64_t seqnum, 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);



More information about the systemd-commits mailing list