chiark / gitweb /
journal: estimate data hash table size a bit larger by default
[elogind.git] / src / journal / journal-file.c
index 9d8c9e686d3ec186e29d859a5a435afb85725d16..b9ab009b3f732ce3cf1f9e74b8920053590eb1d1 100644 (file)
@@ -32,8 +32,8 @@
 #include "lookup3.h"
 #include "compress.h"
 
-#define DEFAULT_DATA_HASH_TABLE_SIZE (2047ULL*16ULL)
-#define DEFAULT_FIELD_HASH_TABLE_SIZE (2047ULL*16ULL)
+#define DEFAULT_DATA_HASH_TABLE_SIZE (2047ULL*sizeof(HashItem))
+#define DEFAULT_FIELD_HASH_TABLE_SIZE (333ULL*sizeof(HashItem))
 
 #define DEFAULT_WINDOW_SIZE (8ULL*1024ULL*1024ULL)
 
@@ -74,7 +74,8 @@ void journal_file_close(JournalFile *f) {
         assert(f);
 
         if (f->header) {
-                if (f->writable)
+                /* Mark the file offline. Don't override the archived state if it already is set */
+                if (f->writable && f->header->state == STATE_ONLINE)
                         f->header->state = STATE_OFFLINE;
 
                 munmap(f->header, PAGE_ALIGN(sizeof(Header)));
@@ -509,7 +510,17 @@ static int journal_file_setup_data_hash_table(JournalFile *f) {
 
         assert(f);
 
-        s = DEFAULT_DATA_HASH_TABLE_SIZE;
+        /* We estimate that we need 1 hash table entry per 768 of
+           journal file and we want to make sure we never get beyond
+           75% fill level. Calculate the hash table size for the
+           maximum file size based on these metrics. */
+
+        s = (f->metrics.max_size * 4 / 768 / 3) * sizeof(HashItem);
+        if (s < DEFAULT_DATA_HASH_TABLE_SIZE)
+                s = DEFAULT_DATA_HASH_TABLE_SIZE;
+
+        log_info("Reserving %llu entries in hash table.", (unsigned long long) (s / sizeof(HashItem)));
+
         r = journal_file_append_object(f,
                                        OBJECT_DATA_HASH_TABLE,
                                        offsetof(Object, hash_table.items) + s,
@@ -1894,6 +1905,9 @@ void journal_file_print_header(JournalFile *f) {
                "Machine ID: %s\n"
                "Boot ID: %s\n"
                "Sequential Number ID: %s\n"
+               "State: %s\n"
+               "Compatible Flags:%s%s\n"
+               "Incompatible Flags:%s%s\n"
                "Header size: %llu\n"
                "Arena size: %llu\n"
                "Data Hash Table Size: %llu\n"
@@ -1910,6 +1924,13 @@ void journal_file_print_header(JournalFile *f) {
                sd_id128_to_string(f->header->machine_id, b),
                sd_id128_to_string(f->header->boot_id, c),
                sd_id128_to_string(f->header->seqnum_id, c),
+               f->header->state == STATE_OFFLINE ? "offline" :
+               f->header->state == STATE_ONLINE ? "online" :
+               f->header->state == STATE_ARCHIVED ? "archived" : "unknown",
+               (f->header->compatible_flags & HEADER_COMPATIBLE_SIGNED) ? " SIGNED" : "",
+               (f->header->compatible_flags & ~HEADER_COMPATIBLE_SIGNED) ? " ???" : "",
+               (f->header->incompatible_flags & HEADER_INCOMPATIBLE_COMPRESSED) ? " COMPRESSED" : "",
+               (f->header->incompatible_flags & ~HEADER_INCOMPATIBLE_COMPRESSED) ? " ???" : "",
                (unsigned long long) le64toh(f->header->header_size),
                (unsigned long long) le64toh(f->header->arena_size),
                (unsigned long long) le64toh(f->header->data_hash_table_size) / sizeof(HashItem),
@@ -1939,6 +1960,7 @@ int journal_file_open(
                 const char *fname,
                 int flags,
                 mode_t mode,
+                JournalMetrics *metrics,
                 JournalFile *template,
                 JournalFile **ret) {
 
@@ -1965,10 +1987,8 @@ int journal_file_open(
         f->writable = (flags & O_ACCMODE) != O_RDONLY;
         f->prot = prot_from_flags(flags);
 
-        if (template) {
-                f->metrics = template->metrics;
+        if (template)
                 f->compress = template->compress;
-        }
 
         f->path = strdup(fname);
         if (!f->path) {
@@ -2019,6 +2039,12 @@ int journal_file_open(
         }
 
         if (f->writable) {
+                if (metrics) {
+                        journal_default_metrics(metrics, f->fd);
+                        f->metrics = *metrics;
+                } else if (template)
+                        f->metrics = template->metrics;
+
                 r = journal_file_refresh_header(f);
                 if (r < 0)
                         goto fail;
@@ -2093,7 +2119,7 @@ int journal_file_rotate(JournalFile **f) {
 
         old_file->header->state = STATE_ARCHIVED;
 
-        r = journal_file_open(old_file->path, old_file->flags, old_file->mode, old_file, &new_file);
+        r = journal_file_open(old_file->path, old_file->flags, old_file->mode, NULL, old_file, &new_file);
         journal_file_close(old_file);
 
         *f = new_file;
@@ -2104,6 +2130,7 @@ int journal_file_open_reliably(
                 const char *fname,
                 int flags,
                 mode_t mode,
+                JournalMetrics *metrics,
                 JournalFile *template,
                 JournalFile **ret) {
 
@@ -2111,7 +2138,7 @@ int journal_file_open_reliably(
         size_t l;
         char *p;
 
-        r = journal_file_open(fname, flags, mode, template, ret);
+        r = journal_file_open(fname, flags, mode, metrics, template, ret);
         if (r != -EBADMSG && /* corrupted */
             r != -ENODATA && /* truncated */
             r != -EHOSTDOWN && /* other machine */
@@ -2140,7 +2167,7 @@ int journal_file_open_reliably(
 
         log_warning("File %s corrupted, renaming and replacing.", fname);
 
-        return journal_file_open(fname, flags, mode, template, ret);
+        return journal_file_open(fname, flags, mode, metrics, template, ret);
 }
 
 struct vacuum_info {