summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2018-12-01 10:18:42 +0100
committerPatrick Steinhardt <ps@pks.im>2019-02-15 13:16:49 +0100
commit6a9117f557fed0afe4007c5de5158e0ebd3a187f (patch)
tree5775649b8d18f8f0b218a0125fcb8dfee6376560
parentc976b4f9b3065db1d8ae048a90fa6a8825458d7d (diff)
downloadlibgit2-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.c20
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;