From: Michael Schroeder Date: Thu, 30 Apr 2026 11:56:23 +0000 (+0200) Subject: Bring down languagecache size if more than one language is configured X-Git-Tag: 0.7.38~21 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=ef513a6f7c2b896356eaefffab2f37b35b8ca8a2;p=thirdparty%2Flibsolv.git Bring down languagecache size if more than one language is configured We do not care about most of the pre-defined ids, so using a cache with the size nlang*ID_NUM_INTERNAL uses way to much space. Rewrite the cache code to use a cache of the size ID_NUM_INTERNAL plus (nlang+1) times the used keynames. Optimize the nlang=1 case so that it also uses less memory. --- diff --git a/src/pool.c b/src/pool.c index a0de4d81..f6b0e6fe 100644 --- a/src/pool.c +++ b/src/pool.c @@ -433,7 +433,6 @@ pool_set_languages(Pool *pool, const char **languages, int nlanguages) int i; pool->languagecache = solv_free(pool->languagecache); - pool->languagecacheother = 0; for (i = 0; i < pool->nlanguages; i++) free((char *)pool->languages[i]); pool->languages = solv_free((void *)pool->languages); diff --git a/src/pool.h b/src/pool.h index e85e9640..d9942564 100644 --- a/src/pool.h +++ b/src/pool.h @@ -143,7 +143,6 @@ struct s_Pool { Hashval relhashmask; Id *languagecache; - int languagecacheother; /* our tmp space string space */ struct s_Pool_tmpspace tmpspace; diff --git a/src/solvable.c b/src/solvable.c index d4ddd61b..7c4177dd 100644 --- a/src/solvable.c +++ b/src/solvable.c @@ -200,41 +200,58 @@ solvable_lookup_str_base(Solvable *s, Id keyname, Id basekeyname, int usebase) return usebase ? basestr : 0; } +static Id * +pool_lookup_languagecache_row(Pool *pool, Id keyname) +{ + int cols = pool->nlanguages + 1; + Id *row; + if (!pool->languagecache) + { + pool->languagecache = solv_calloc(ID_NUM_INTERNAL + cols + 1, sizeof(Id)); + pool->languagecache[0] = ID_NUM_INTERNAL; /* current size */ + } + if (keyname > 0 && keyname < ID_NUM_INTERNAL) + { + if (cols == 2) + return pool->languagecache + keyname; /* special case for just one language */ + if (pool->languagecache[keyname]) + return pool->languagecache + pool->languagecache[keyname]; + } + else + { + /* find our row, terminate if we reach the trailing zero */ + for (row = pool->languagecache + ID_NUM_INTERNAL; *row; row += cols) + if (*row == keyname) + return row + 1; + } + /* we need to add a new row (plus the trailing zero) */ + if (pool->languagecache[0] + cols + 1 >= SOLV_MAX_INDEX) + solv_ovfl("languagecache size overflow"); + pool->languagecache = solv_realloc2(pool->languagecache, pool->languagecache[0] + cols + 1, sizeof(Id)); + if (keyname < ID_NUM_INTERNAL) + pool->languagecache[keyname] = pool->languagecache[0] + 1; + row = pool->languagecache + pool->languagecache[0]; + pool->languagecache[0] += cols; + memset(row, 0, (cols + 1) * sizeof(Id)); /* +1 for the trailing zero */ + *row = keyname; + return row + 1; +} + const char * solvable_lookup_str_poollang(Solvable *s, Id keyname) { Pool *pool; - int i, cols; + int i; const char *str; Id *row; if (!s->repo) return 0; pool = s->repo->pool; - if (!pool->nlanguages) + if (!pool->nlanguages || !keyname) return solvable_lookup_str(s, keyname); - cols = pool->nlanguages + 1; - if (!pool->languagecache) - { - pool->languagecache = solv_calloc(ID_NUM_INTERNAL, cols * sizeof(Id)); - pool->languagecacheother = 0; - } - if (keyname >= ID_NUM_INTERNAL) - { - row = pool->languagecache + ID_NUM_INTERNAL * cols; - for (i = 0; i < pool->languagecacheother; i++, row += cols) - if (*row == keyname) - break; - if (i >= pool->languagecacheother) - { - pool->languagecache = solv_realloc2(pool->languagecache, pool->languagecacheother + 1, cols * sizeof(Id)); - row = pool->languagecache + cols * (ID_NUM_INTERNAL + pool->languagecacheother++); - *row = keyname; - } - } - else - row = pool->languagecache + keyname * cols; - row++; /* skip keyname */ + /* the languagecache caches the pool_id2langid result for all configured languages */ + row = pool_lookup_languagecache_row(pool, keyname); for (i = 0; i < pool->nlanguages; i++, row++) { if (!*row)