commit d2f4ff23fb8e50208ab396f6e87e09a7a4fa17a6
parent 03d4bc2044fdd032cb68702d94d0dde66fd5c4c9
Author: Christian Grothoff <christian@grothoff.org>
Date: Sat, 10 Oct 2026 00:23:22 +0200
use static array for used_histories, instead of O(n^2) complexity
Diffstat:
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c
@@ -171,12 +171,17 @@ static struct CoinHistory coin_histories[MAX_COIN_HISTORIES];
/**
* Indices of the entries of #coin_histories that are in use. Used to
* flush the cache at the end of a pass without touching the entire
- * (huge) #coin_histories array.
+ * (huge) #coin_histories array. An index is recorded only when its
+ * entry goes from empty to used, so there are never more than
+ * #MAX_COIN_HISTORIES of them. Static rather than grown with
+ * GNUNET_array_append(): that copies the whole array on every call
+ * (quadratic in the number of coins of a pass) and aborts once the
+ * array exceeds GNUNET_MAX_MALLOC_CHECKED (about 10.5M entries).
*/
-static unsigned int *used_histories;
+static unsigned int used_histories[MAX_COIN_HISTORIES];
/**
- * Length of the #used_histories array.
+ * Number of entries of #used_histories that are in use.
*/
static unsigned int num_used_histories;
@@ -223,12 +228,17 @@ cache_history (const struct TALER_CoinSpendPublicKeyP *coin_pub,
{
unsigned int i = coin_history_index (coin_pub);
+ if (NULL == tl)
+ return; /* nothing to cache; get_cached_history() would miss anyway */
if (NULL != coin_histories[i].tl)
+ {
TALER_EXCHANGEDB_free_coin_transaction_list (coin_histories[i].tl);
+ }
else
- GNUNET_array_append (used_histories,
- num_used_histories,
- i);
+ {
+ GNUNET_assert (num_used_histories < MAX_COIN_HISTORIES);
+ used_histories[num_used_histories++] = i;
+ }
coin_histories[i].coin_pub = *coin_pub;
coin_histories[i].tl = tl;
}
@@ -255,9 +265,7 @@ flush_coin_histories (void)
0,
sizeof (*ch));
}
- GNUNET_array_grow (used_histories,
- num_used_histories,
- 0);
+ num_used_histories = 0;
}