diff options
Diffstat (limited to 'src/cache.c')
-rw-r--r-- | src/cache.c | 46 |
1 files changed, 16 insertions, 30 deletions
diff --git a/src/cache.c b/src/cache.c index 5a9b8415c..fdf5c1b80 100644 --- a/src/cache.c +++ b/src/cache.c @@ -32,23 +32,6 @@ #define GIT_CACHE_OPENADR 3 -GIT_INLINE(int) cached_obj_compare(git_cached_obj *obj, const git_oid *oid) -{ - return git_oid_cmp(&obj->oid, oid); -} - -GIT_INLINE(void) cached_obj_incref(git_cached_obj *obj) -{ - git_atomic_inc(&obj->refcount); -} - -GIT_INLINE(void) cached_obj_decref(git_cached_obj *obj, git_cached_obj_freeptr free_obj) -{ - if (git_atomic_dec(&obj->refcount) == 0) - free_obj(obj); -} - - void git_cache_init(git_cache *cache, size_t size, git_cached_obj_freeptr free_ptr) { size_t i; @@ -82,7 +65,9 @@ void git_cache_free(git_cache *cache) size_t i; for (i = 0; i < (cache->size_mask + 1); ++i) { - cached_obj_decref(cache->nodes[i].ptr, cache->free_obj); + if (cache->nodes[i].ptr) + git_cached_obj_decref(cache->nodes[i].ptr, cache->free_obj); + git_mutex_free(&cache->nodes[i].lock); } @@ -103,8 +88,8 @@ void *git_cache_get(git_cache *cache, const git_oid *oid) git_mutex_lock(&node->lock); { - if (cached_obj_compare(node->ptr, oid) == 0) { - cached_obj_incref(node->ptr); + if (node->ptr && git_cached_obj_compare(node->ptr, oid) == 0) { + git_cached_obj_incref(node->ptr); node->lru = ++cache->lru_count; found = 1; } @@ -121,14 +106,14 @@ void *git_cache_try_store(git_cache *cache, void *entry) cache_node *nodes[GIT_CACHE_OPENADR], *lru_node; const uint32_t *hash; const git_oid *oid; - size_t i, stored = 0; + size_t i; oid = &((git_cached_obj*)entry)->oid; hash = (const uint32_t *)oid->id; /* increase the refcount on this object, because * the cache now owns it */ - cached_obj_incref(entry); + git_cached_obj_incref(entry); for (i = 0; i < GIT_CACHE_OPENADR; ++i) { size_t pos = hash[i] & cache->size_mask; @@ -139,34 +124,35 @@ void *git_cache_try_store(git_cache *cache, void *entry) lru_node = nodes[0]; - for (i = 0; !stored && entry && i < GIT_CACHE_OPENADR; ++i) { + for (i = 0; i < GIT_CACHE_OPENADR; ++i) { if (nodes[i]->ptr == NULL) { nodes[i]->ptr = entry; nodes[i]->lru = ++cache->lru_count; - stored = 1; - } else if (cached_obj_compare(nodes[i]->ptr, oid) == 0) { - cached_obj_decref(entry, cache->free_obj); + break; + } else if (git_cached_obj_compare(nodes[i]->ptr, oid) == 0) { + git_cached_obj_decref(entry, cache->free_obj); entry = nodes[i]->ptr; - stored = 1; + nodes[i]->lru = ++cache->lru_count; + break; } if (nodes[i]->lru < lru_node->lru) lru_node = nodes[i]; } - if (!stored) { + if (i == GIT_CACHE_OPENADR) { void *old_entry = lru_node->ptr; assert(old_entry); - cached_obj_decref(old_entry, cache->free_obj); + git_cached_obj_decref(old_entry, cache->free_obj); lru_node->ptr = entry; lru_node->lru = ++cache->lru_count; } /* increase the refcount again, because we are * returning it to the user */ - cached_obj_incref(entry); + git_cached_obj_incref(entry); for (i = 0; i < GIT_CACHE_OPENADR; ++i) git_mutex_unlock(&nodes[i]->lock); |