diff options
author | Vicent Martà <tanoku@gmail.com> | 2012-01-27 18:28:02 -0800 |
---|---|---|
committer | Vicent Martà <tanoku@gmail.com> | 2012-01-27 18:28:02 -0800 |
commit | e4b4da140648d83f953837d4233dd87cb31f3ca4 (patch) | |
tree | e41553a06881bc2a5b9ab9b02c84db343c34f6ec /src/cache.c | |
parent | 7a6f51de6d4f5543634889e58c30a0a6ceb75a09 (diff) | |
download | libgit2-e4b4da140648d83f953837d4233dd87cb31f3ca4.tar.gz |
cache: Simplify locking mechanics
The object cache is mostly IO-bound, so it makes no sense to have a lock
per node.
Diffstat (limited to 'src/cache.c')
-rw-r--r-- | src/cache.c | 72 |
1 files changed, 34 insertions, 38 deletions
diff --git a/src/cache.c b/src/cache.c index 6ba4d212c..8150ec35a 100644 --- a/src/cache.c +++ b/src/cache.c @@ -13,8 +13,6 @@ int git_cache_init(git_cache *cache, size_t size, git_cached_obj_freeptr free_ptr) { - size_t i; - if (size < 8) size = 8; @@ -25,20 +23,19 @@ int git_cache_init(git_cache *cache, size_t size, git_cached_obj_freeptr free_pt size |= size >> 4; size |= size >> 8; size |= size >> 16; + size++; - cache->size_mask = size; + cache->size_mask = size - 1; cache->lru_count = 0; cache->free_obj = free_ptr; - cache->nodes = git__malloc((size + 1) * sizeof(cache_node)); + git_mutex_init(&cache->lock); + + cache->nodes = git__malloc(size * sizeof(git_cached_obj *)); if (cache->nodes == NULL) return GIT_ENOMEM; - for (i = 0; i < (size + 1); ++i) { - git_mutex_init(&cache->nodes[i].lock); - cache->nodes[i].ptr = NULL; - } - + memset(cache->nodes, 0x0, size * sizeof(git_cached_obj *)); return GIT_SUCCESS; } @@ -47,10 +44,8 @@ void git_cache_free(git_cache *cache) size_t i; for (i = 0; i < (cache->size_mask + 1); ++i) { - if (cache->nodes[i].ptr) - git_cached_obj_decref(cache->nodes[i].ptr, cache->free_obj); - - git_mutex_free(&cache->nodes[i].lock); + if (cache->nodes[i] != NULL) + git_cached_obj_decref(cache->nodes[i], cache->free_obj); } git__free(cache->nodes); @@ -59,53 +54,54 @@ void git_cache_free(git_cache *cache) void *git_cache_get(git_cache *cache, const git_oid *oid) { uint32_t hash; - cache_node *node = NULL; - void *result = NULL; + git_cached_obj *node = NULL, *result = NULL; memcpy(&hash, oid->id, sizeof(hash)); - node = &cache->nodes[hash & cache->size_mask]; - git_mutex_lock(&node->lock); + git_mutex_lock(&cache->lock); { - if (node->ptr && git_cached_obj_compare(node->ptr, oid) == 0) { - git_cached_obj_incref(node->ptr); - result = node->ptr; + node = cache->nodes[hash & cache->size_mask]; + + if (node != NULL && git_oid_cmp(&node->oid, oid) == 0) { + git_cached_obj_incref(node); + result = node; } } - git_mutex_unlock(&node->lock); + git_mutex_unlock(&cache->lock); return result; } -void *git_cache_try_store(git_cache *cache, void *entry) +void *git_cache_try_store(git_cache *cache, void *_entry) { + git_cached_obj *entry = _entry; uint32_t hash; - const git_oid *oid; - cache_node *node = NULL; - oid = &((git_cached_obj*)entry)->oid; - memcpy(&hash, oid->id, sizeof(hash)); - node = &cache->nodes[hash & cache->size_mask]; + memcpy(&hash, &entry->oid, sizeof(hash)); /* increase the refcount on this object, because * the cache now owns it */ git_cached_obj_incref(entry); - git_mutex_lock(&node->lock); - - if (node->ptr == NULL) { - node->ptr = entry; - } else if (git_cached_obj_compare(node->ptr, oid) == 0) { - git_cached_obj_decref(entry, cache->free_obj); - entry = node->ptr; - } else { - git_cached_obj_decref(node->ptr, cache->free_obj); - node->ptr = entry; + + git_mutex_lock(&cache->lock); + { + git_cached_obj *node = cache->nodes[hash & cache->size_mask]; + + if (node == NULL) { + cache->nodes[hash & cache->size_mask] = entry; + } else if (git_oid_cmp(&node->oid, &entry->oid) == 0) { + git_cached_obj_decref(entry, cache->free_obj); + entry = node; + } else { + git_cached_obj_decref(node, cache->free_obj); + cache->nodes[hash & cache->size_mask] = entry; + } } + git_mutex_unlock(&cache->lock); /* increase the refcount again, because we are * returning it to the user */ git_cached_obj_incref(entry); - git_mutex_unlock(&node->lock); return entry; } |