From 69adae5168da231c6cf319f708860954701b25ed Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Wed, 3 Dec 2014 18:25:44 +0100 Subject: [PATCH 1/1] journal: replace contexts hashmap with a plain array try_context() is such a hot path that the hashmap lookup is expensive. The number of contexts is small - it is the number of object types. Using a hashmap is overkill. A plain array will do. Before: $ time ./journalctl --since=2014-06-01 --until=2014-07-01 > /dev/null real 0m9.445s user 0m9.228s sys 0m0.213s After: $ time ./journalctl --since=2014-06-01 --until=2014-07-01 > /dev/null real 0m5.438s user 0m5.266s sys 0m0.170s --- src/journal/journal-file.c | 1 + src/journal/mmap-cache.c | 34 ++++++++++++++-------------------- src/journal/mmap-cache.h | 2 ++ 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index 82e50fcca..7cdaf2920 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -376,6 +376,7 @@ static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size) static unsigned type_to_context(ObjectType type) { /* One context for each type, plus one catch-all for the rest */ + assert_cc(_OBJECT_TYPE_MAX <= MMAP_CACHE_MAX_CONTEXTS); return type > OBJECT_UNUSED && type < _OBJECT_TYPE_MAX ? type : 0; } diff --git a/src/journal/mmap-cache.c b/src/journal/mmap-cache.c index 949f97819..4c940aaa2 100644 --- a/src/journal/mmap-cache.c +++ b/src/journal/mmap-cache.c @@ -76,7 +76,7 @@ struct MMapCache { Hashmap *fds; - Hashmap *contexts; + Context *contexts[MMAP_CACHE_MAX_CONTEXTS]; LIST_HEAD(Window, unused); Window *last_unused; @@ -231,18 +231,13 @@ static void context_attach_window(Context *c, Window *w) { static Context *context_add(MMapCache *m, unsigned id) { Context *c; - int r; assert(m); - c = hashmap_get(m->contexts, UINT_TO_PTR(id + 1)); + c = m->contexts[id]; if (c) return c; - r = hashmap_ensure_allocated(&m->contexts, NULL); - if (r < 0) - return NULL; - c = new0(Context, 1); if (!c) return NULL; @@ -250,11 +245,8 @@ static Context *context_add(MMapCache *m, unsigned id) { c->cache = m; c->id = id; - r = hashmap_put(m->contexts, UINT_TO_PTR(id + 1), c); - if (r < 0) { - free(c); - return NULL; - } + assert(!m->contexts[id]); + m->contexts[id] = c; return c; } @@ -264,8 +256,10 @@ static void context_free(Context *c) { context_detach_window(c); - if (c->cache) - assert_se(hashmap_remove(c->cache->contexts, UINT_TO_PTR(c->id + 1))); + if (c->cache) { + assert(c->cache->contexts[c->id] == c); + c->cache->contexts[c->id] = NULL; + } free(c); } @@ -314,15 +308,14 @@ static FileDescriptor* fd_add(MMapCache *m, int fd) { } static void mmap_cache_free(MMapCache *m) { - Context *c; FileDescriptor *f; + int i; assert(m); - while ((c = hashmap_first(m->contexts))) - context_free(c); - - hashmap_free(m->contexts); + for (i = 0; i < MMAP_CACHE_MAX_CONTEXTS; i++) + if (m->contexts[i]) + context_free(m->contexts[i]); while ((f = hashmap_first(m->fds))) fd_free(f); @@ -374,7 +367,7 @@ static int try_context( assert(size > 0); assert(ret); - c = hashmap_get(m->contexts, UINT_TO_PTR(context+1)); + c = m->contexts[context]; if (!c) return 0; @@ -557,6 +550,7 @@ int mmap_cache_get( assert(fd >= 0); assert(size > 0); assert(ret); + assert(context < MMAP_CACHE_MAX_CONTEXTS); /* Check whether the current context is the right one already */ r = try_context(m, fd, prot, context, keep_always, offset, size, ret); diff --git a/src/journal/mmap-cache.h b/src/journal/mmap-cache.h index 543a2bf2d..fe2c83d75 100644 --- a/src/journal/mmap-cache.h +++ b/src/journal/mmap-cache.h @@ -25,6 +25,8 @@ #include #include +#define MMAP_CACHE_MAX_CONTEXTS 8 + typedef struct MMapCache MMapCache; MMapCache* mmap_cache_new(void); -- 2.30.2