journal: use IteratedCache in sd-journal

This changes real_journal_next() to leverage the IteratedCache for
accelerating iteration across the open journal files.

journalctl timing comparisons with 100 journal files of 8MiB size
party to this boot:

Pre (~v235):
  # time ./journalctl -b --no-pager > /dev/null
  real    0m9.613s
  user    0m9.560s
  sys     0m0.053s

  # time ./journalctl -b --no-pager > /dev/null
  real    0m9.548s
  user    0m9.525s
  sys     0m0.023s

  # time ./journalctl -b --no-pager > /dev/null
  real    0m9.612s
  user    0m9.582s
  sys     0m0.030s

Post-IteratedCache:

  # time ./journalctl -b --no-pager > /dev/null
  real    0m8.449s
  user    0m8.425s
  sys     0m0.024s

  # time ./journalctl -b --no-pager > /dev/null
  real    0m8.409s
  user    0m8.382s
  sys     0m0.027s

  # time ./journalctl -b --no-pager > /dev/null
  real    0m8.410s
  user    0m8.350s
  sys     0m0.061s

~12.5% improvement, the benefit increases the more log files there are.
This commit is contained in:
Vito Caputo 2017-10-08 16:52:56 -07:00
parent 45ea84d8ed
commit 5d4ba7f2b3
2 changed files with 16 additions and 4 deletions

View file

@ -89,6 +89,7 @@ struct sd_journal {
char *prefix;
OrderedHashmap *files;
IteratedCache *files_cache;
MMapCache *mmap;
Location current_location;

View file

@ -819,15 +819,21 @@ 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;
Iterator i;
JournalFile *new_file = NULL;
unsigned i, n_files;
const void **files;
Object *o;
int r;
assert_return(j, -EINVAL);
assert_return(!journal_pid_changed(j), -ECHILD);
ORDERED_HASHMAP_FOREACH(f, j->files, i) {
r = iterated_cache_get(j->files_cache, NULL, &files, &n_files);
if (r < 0)
return r;
for (i = 0; i < n_files; i++) {
JournalFile *f = (JournalFile *)files[i];
bool found;
r = next_beyond_location(j, f, direction);
@ -1736,9 +1742,13 @@ static sd_journal *journal_new(int flags, const char *path) {
}
j->files = ordered_hashmap_new(&string_hash_ops);
if (!j->files)
goto fail;
j->files_cache = ordered_hashmap_iterated_cache_new(j->files);
j->directories_by_path = hashmap_new(&string_hash_ops);
j->mmap = mmap_cache_new();
if (!j->files || !j->directories_by_path || !j->mmap)
if (!j->files_cache || !j->directories_by_path || !j->mmap)
goto fail;
return j;
@ -1984,6 +1994,7 @@ _public_ void sd_journal_close(sd_journal *j) {
sd_journal_flush_matches(j);
ordered_hashmap_free_with_destructor(j->files, journal_file_close);
iterated_cache_free(j->files_cache);
while ((d = hashmap_first(j->directories_by_path)))
remove_directory(j, d);