Commit 6a9117f5 by Patrick Steinhardt

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.
parent c976b4f9
...@@ -115,8 +115,7 @@ void git_cache_free(git_cache *cache) ...@@ -115,8 +115,7 @@ void git_cache_free(git_cache *cache)
/* Called with lock */ /* Called with lock */
static void cache_evict_entries(git_cache *cache) static void cache_evict_entries(git_cache *cache)
{ {
uint32_t seed = rand(); size_t evict_count = 8, i;
size_t evict_count = 8;
ssize_t evicted_memory = 0; ssize_t evicted_memory = 0;
/* do not infinite loop if there's not enough entries to evict */ /* do not infinite loop if there's not enough entries to evict */
...@@ -125,18 +124,19 @@ static void cache_evict_entries(git_cache *cache) ...@@ -125,18 +124,19 @@ static void cache_evict_entries(git_cache *cache)
return; return;
} }
i = 0;
while (evict_count > 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)) { if (git_oidmap_iterate((void **) &evict, cache->map, &i, &key) == GIT_ITEROVER)
git_cached_obj *evict = git_oidmap_value_at(cache->map, pos); break;
evict_count--; evict_count--;
evicted_memory += evict->size; evicted_memory += evict->size;
git_cached_obj_decref(evict); git_cached_obj_decref(evict);
git_oidmap_delete_at(cache->map, pos); git_oidmap_delete(cache->map, key);
}
} }
cache->used_memory -= evicted_memory; cache->used_memory -= evicted_memory;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment