make id cache eviction more efficient
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
diff --git a/lib/got_lib_object_idcache.h b/lib/got_lib_object_idcache.h
index 7920666..20d9f5c 100644
--- a/lib/got_lib_object_idcache.h
+++ b/lib/got_lib_object_idcache.h
@@ -22,8 +22,8 @@ void got_object_idcache_free(struct got_object_idcache *);
const struct got_error *got_object_idcache_add(struct got_object_idcache *,
struct got_object_id *, void *);
void *got_object_idcache_get(struct got_object_idcache *, struct got_object_id *);
-const struct got_error *got_object_idcache_remove_least_used(void **,
- struct got_object_idcache *);
+const struct got_error *got_object_idcache_remove_one(void **,
+ struct got_object_idcache *, struct got_object_id *);
int got_object_idcache_contains(struct got_object_idcache *,
struct got_object_id *);
void got_object_idcache_for_each(struct got_object_idcache *,
diff --git a/lib/object_cache.c b/lib/object_cache.c
index 7957b39..f4766bb 100644
--- a/lib/object_cache.c
+++ b/lib/object_cache.c
@@ -73,8 +73,8 @@ got_object_cache_add(struct got_object_cache *cache, struct got_object_id *id, v
nelem = got_object_idcache_num_elements(cache->idcache);
if (nelem >= cache->size) {
- err = got_object_idcache_remove_least_used((void **)&ce,
- cache->idcache);
+ err = got_object_idcache_remove_one((void **)&ce,
+ cache->idcache, id);
if (err)
return err;
switch (cache->type) {
diff --git a/lib/object_idcache.c b/lib/object_idcache.c
index 7632943..3206b9e 100644
--- a/lib/object_idcache.c
+++ b/lib/object_idcache.c
@@ -132,10 +132,11 @@ got_object_idcache_get(struct got_object_idcache *cache, struct got_object_id *i
}
const struct got_error *
-got_object_idcache_remove_least_used(void **data, struct got_object_idcache *cache)
+got_object_idcache_remove_one(void **data, struct got_object_idcache *cache,
+ struct got_object_id *id)
{
struct got_object_idcache_element *entry;
- int i, idx = 0, maxelem = cache->nelem[0];
+ uint8_t idx = id->sha1[0];
if (data)
*data = NULL;
@@ -143,13 +144,18 @@ got_object_idcache_remove_least_used(void **data, struct got_object_idcache *cac
if (cache->totelem == 0)
return got_error(GOT_ERR_NO_OBJ);
- /* Remove least used element from longest list. */
- for (i = 0; i < nitems(cache->entries); i++) {
- if (maxelem < cache->nelem[i]) {
- idx = i;
- maxelem = cache->nelem[i];
+ if (cache->nelem[idx] == 0) {
+ /* Remove an element from the longest list. */
+ int i, maxelem = cache->nelem[0];
+ idx = 0;
+ for (i = 0; i < nitems(cache->entries); i++) {
+ if (maxelem < cache->nelem[i]) {
+ idx = i;
+ maxelem = cache->nelem[i];
+ }
}
}
+
entry = TAILQ_LAST(&cache->entries[idx], got_object_idcache_head);
TAILQ_REMOVE(&cache->entries[idx], entry, entry);
if (data)