]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
libkmod: Add better caching to FILE index
authorTobias Stoeckmann <tobias@stoeckmann.org>
Thu, 17 Oct 2024 07:48:06 +0000 (09:48 +0200)
committerLucas De Marchi <lucas.de.marchi@gmail.com>
Tue, 29 Oct 2024 02:50:14 +0000 (21:50 -0500)
We can use getdelim and reuse buffers by referencing the index_file
instead of just the FILE handle.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Link: https://github.com/kmod-project/kmod/pull/190
Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
libkmod/libkmod-index.c

index 49122bf4234c9d6171d364d5e09d777ff37f7833..64a38979eee9b89a7e443c63ae1b3f6eb0f4cb0f 100644 (file)
@@ -197,25 +197,18 @@ static inline bool read_u32(FILE *in, uint32_t *l)
        return read_u32s(in, l, 1);
 }
 
-static ssize_t buf_freadchars(struct strbuf *buf, FILE *in)
-{
-       ssize_t i = 0;
-       int ch;
-
-       while ((ch = read_char(in))) {
-               if (ch == EOF || !strbuf_pushchar(buf, ch))
-                       return -1;
-               i++;
-       }
-
-       return i;
-}
-
 /*
  * Index file searching
  */
-struct index_node_f {
+struct index_file {
        FILE *file;
+       uint32_t root_offset;
+       char *tmp;
+       size_t tmp_size;
+};
+
+struct index_node_f {
+       struct index_file *idx;
        char *prefix; /* path compression */
        struct index_value *values;
        unsigned char first; /* range of child nodes */
@@ -223,26 +216,23 @@ struct index_node_f {
        uint32_t children[0];
 };
 
-static struct index_node_f *index_read(FILE *in, uint32_t offset)
+static struct index_node_f *index_read(struct index_file *idx, uint32_t offset)
 {
        struct index_node_f *node = NULL;
        char *prefix = NULL;
        size_t child_count = 0;
+       FILE *fp = idx->file;
 
        if ((offset & INDEX_NODE_MASK) == 0)
                return NULL;
 
-       if (fseek(in, offset & INDEX_NODE_MASK, SEEK_SET) < 0)
+       if (fseek(fp, offset & INDEX_NODE_MASK, SEEK_SET) < 0)
                return NULL;
 
        if (offset & INDEX_NODE_PREFIX) {
-               struct strbuf buf;
-               strbuf_init(&buf);
-               if (buf_freadchars(&buf, in) < 0) {
-                       strbuf_release(&buf);
+               if (getdelim(&idx->tmp, &idx->tmp_size, '\0', fp) < 0)
                        return NULL;
-               }
-               prefix = strbuf_steal(&buf);
+               prefix = strdup(idx->tmp);
        } else
                prefix = strdup("");
 
@@ -250,8 +240,8 @@ static struct index_node_f *index_read(FILE *in, uint32_t offset)
                goto err;
 
        if (offset & INDEX_NODE_CHILDS) {
-               int first = read_char(in);
-               int last = read_char(in);
+               int first = read_char(fp);
+               int last = read_char(fp);
 
                if (first == EOF || last == EOF || first > last)
                        goto err;
@@ -266,7 +256,7 @@ static struct index_node_f *index_read(FILE *in, uint32_t offset)
                node->first = (unsigned char)first;
                node->last = (unsigned char)last;
 
-               if (!read_u32s(in, node->children, child_count))
+               if (!read_u32s(fp, node->children, child_count))
                        goto err;
        } else {
                node = malloc(sizeof(struct index_node_f));
@@ -280,32 +270,25 @@ static struct index_node_f *index_read(FILE *in, uint32_t offset)
        node->values = NULL;
        if (offset & INDEX_NODE_VALUES) {
                uint32_t value_count;
-               struct strbuf buf;
-               const char *value;
                unsigned int priority;
 
-               if (!read_u32(in, &value_count))
+               if (!read_u32(fp, &value_count))
                        goto err;
 
-               strbuf_init(&buf);
                while (value_count--) {
-                       if (!read_u32(in, &priority) || buf_freadchars(&buf, in) < 0) {
-                               strbuf_release(&buf);
+                       ssize_t n;
+
+                       if (!read_u32(fp, &priority))
                                goto err;
-                       }
-                       value = strbuf_str(&buf);
-                       if (value == NULL) {
-                               strbuf_release(&buf);
+                       n = getdelim(&idx->tmp, &idx->tmp_size, '\0', fp);
+                       if (n < 0)
                                goto err;
-                       }
-                       add_value(&node->values, value, buf.used, priority);
-                       strbuf_clear(&buf);
+                       add_value(&node->values, idx->tmp, n, priority);
                }
-               strbuf_release(&buf);
        }
 
        node->prefix = prefix;
-       node->file = in;
+       node->idx = idx;
        return node;
 err:
        free(prefix);
@@ -320,11 +303,6 @@ static void index_close(struct index_node_f *node)
        free(node);
 }
 
-struct index_file {
-       FILE *file;
-       uint32_t root_offset;
-};
-
 struct index_file *index_file_open(const char *filename)
 {
        FILE *file;
@@ -351,6 +329,8 @@ struct index_file *index_file_open(const char *filename)
                free(new);
                goto err;
        }
+       new->tmp = NULL;
+       new->tmp_size = 0;
 
        errno = 0;
        return new;
@@ -362,18 +342,19 @@ err:
 void index_file_close(struct index_file *idx)
 {
        fclose(idx->file);
+       free(idx->tmp);
        free(idx);
 }
 
 static struct index_node_f *index_readroot(struct index_file *in)
 {
-       return index_read(in->file, in->root_offset);
+       return index_read(in, in->root_offset);
 }
 
 static struct index_node_f *index_readchild(const struct index_node_f *parent, int ch)
 {
        if (parent->first <= ch && ch <= parent->last) {
-               return index_read(parent->file, parent->children[ch - parent->first]);
+               return index_read(parent->idx, parent->children[ch - parent->first]);
        }
 
        return NULL;