diff options
author | Patrick Steinhardt <ps@pks.im> | 2018-12-01 10:18:42 +0100 |
---|---|---|
committer | Patrick Steinhardt <ps@pks.im> | 2019-02-15 13:16:49 +0100 |
commit | 6a9117f557fed0afe4007c5de5158e0ebd3a187f (patch) | |
tree | 5775649b8d18f8f0b218a0125fcb8dfee6376560 | |
parent | c976b4f9b3065db1d8ae048a90fa6a8825458d7d (diff) | |
download | libgit2-6a9117f557fed0afe4007c5de5158e0ebd3a187f.tar.gz |
cache: use iteration interface for cache eviction
To relieve us from memory pressure, we may regularly call `cache_evict_entries`
to remove some entries from it. Unfortunately, our cache does not support a
least-recently-used mode or something similar, which is why we evict entries
completeley at random right now. Thing is, this is only possible due to the map
interfaces exposing the entry indices, and we intend to completely remove those
to decouple map users from map implementations. As soon as that is done, we are
unable to do this random eviction anymore.
Convert this to make use of an iterator for now. Obviously, there is no random
eviction possible like that anymore, but we'll always start by evicting from the
beginning of the map. Due to hashing, one may hope that the selected buckets
will be evicted at least in some way unpredictably. But more likely than not,
this will not be the case. But let's see what happens and if any users complain
about degraded performance. If so, we might come up with a different scheme than
random removal, e.g. by using an LRU cache.
-rw-r--r-- | src/cache.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/src/cache.c b/src/cache.c index a7907836c..b0b56ba4c 100644 --- a/src/cache.c +++ b/src/cache.c @@ -115,8 +115,7 @@ void git_cache_free(git_cache *cache) /* Called with lock */ static void cache_evict_entries(git_cache *cache) { - uint32_t seed = rand(); - size_t evict_count = 8; + size_t evict_count = 8, i; ssize_t evicted_memory = 0; /* do not infinite loop if there's not enough entries to evict */ @@ -125,18 +124,19 @@ static void cache_evict_entries(git_cache *cache) return; } + i = 0; while (evict_count > 0) { - size_t pos = seed++ % git_oidmap_end(cache->map); + git_cached_obj *evict; + const git_oid *key; - if (git_oidmap_has_data(cache->map, pos)) { - git_cached_obj *evict = git_oidmap_value_at(cache->map, pos); + if (git_oidmap_iterate((void **) &evict, cache->map, &i, &key) == GIT_ITEROVER) + break; - evict_count--; - evicted_memory += evict->size; - git_cached_obj_decref(evict); + evict_count--; + evicted_memory += evict->size; + git_cached_obj_decref(evict); - git_oidmap_delete_at(cache->map, pos); - } + git_oidmap_delete(cache->map, key); } cache->used_memory -= evicted_memory; |