From: Tobias Stoeckmann Date: Thu, 17 Oct 2024 07:48:06 +0000 (+0200) Subject: libkmod: Add better caching to FILE index X-Git-Tag: v34~161 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0f6d92ad78fd11daa3fbabe0d53c3ea92f4ba87c;p=thirdparty%2Fkmod.git libkmod: Add better caching to FILE index We can use getdelim and reuse buffers by referencing the index_file instead of just the FILE handle. Signed-off-by: Tobias Stoeckmann Link: https://github.com/kmod-project/kmod/pull/190 Signed-off-by: Lucas De Marchi --- diff --git a/libkmod/libkmod-index.c b/libkmod/libkmod-index.c index 49122bf4..64a38979 100644 --- a/libkmod/libkmod-index.c +++ b/libkmod/libkmod-index.c @@ -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;