1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-12 13:18:14 +03:00

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
This commit is contained in:
Michal Schmidt 2014-12-03 18:25:44 +01:00
parent 634ed0ee34
commit 69adae5168
3 changed files with 17 additions and 20 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -25,6 +25,8 @@
#include <stdbool.h>
#include <sys/stat.h>
#define MMAP_CACHE_MAX_CONTEXTS 8
typedef struct MMapCache MMapCache;
MMapCache* mmap_cache_new(void);