]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
Bring down languagecache size if more than one language is configured
authorMichael Schroeder <mls@suse.de>
Thu, 30 Apr 2026 11:56:23 +0000 (13:56 +0200)
committerMichael Schroeder <mls@suse.de>
Thu, 30 Apr 2026 12:46:35 +0000 (14:46 +0200)
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.

src/pool.c
src/pool.h
src/solvable.c

index a0de4d81c5a3df50c22f109756cb4d9dc972813a..f6b0e6fe57660de2294e75f7f14c184d8ad5cb1a 100644 (file)
@@ -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);
index e85e96403ddd6a5a14ea361182698edbff8caa6c..d994256409964165e1fe9df9c02e960f8c49610d 100644 (file)
@@ -143,7 +143,6 @@ struct s_Pool {
   Hashval relhashmask;
 
   Id *languagecache;
-  int languagecacheother;
 
   /* our tmp space string space */
   struct s_Pool_tmpspace tmpspace;
index d4ddd61b6c9c6b48bf448c76dad442ffc8f9dd03..7c4177dd00a9022d6ee72f70ebaa329defdbc56c 100644 (file)
@@ -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)