]> git.proxmox.com Git - libgit2.git/blob - src/cache.c
Fix the build on Emscripten
[libgit2.git] / src / cache.c
1 /*
2 * Copyright (C) 2009-2011 the libgit2 contributors
3 *
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
6 */
7
8 #include "common.h"
9 #include "repository.h"
10 #include "commit.h"
11 #include "thread-utils.h"
12 #include "cache.h"
13
14 int git_cache_init(git_cache *cache, size_t size, git_cached_obj_freeptr free_ptr)
15 {
16 if (size < 8)
17 size = 8;
18
19 /* round up size to closest power of 2 */
20 size--;
21 size |= size >> 1;
22 size |= size >> 2;
23 size |= size >> 4;
24 size |= size >> 8;
25 size |= size >> 16;
26 size++;
27
28 cache->size_mask = size - 1;
29 cache->lru_count = 0;
30 cache->free_obj = free_ptr;
31
32 git_mutex_init(&cache->lock);
33
34 cache->nodes = git__malloc(size * sizeof(git_cached_obj *));
35 if (cache->nodes == NULL)
36 return GIT_ENOMEM;
37
38 memset(cache->nodes, 0x0, size * sizeof(git_cached_obj *));
39 return GIT_SUCCESS;
40 }
41
42 void git_cache_free(git_cache *cache)
43 {
44 size_t i;
45
46 for (i = 0; i < (cache->size_mask + 1); ++i) {
47 if (cache->nodes[i] != NULL)
48 git_cached_obj_decref(cache->nodes[i], cache->free_obj);
49 }
50
51 git__free(cache->nodes);
52 }
53
54 void *git_cache_get(git_cache *cache, const git_oid *oid)
55 {
56 uint32_t hash;
57 git_cached_obj *node = NULL, *result = NULL;
58
59 memcpy(&hash, oid->id, sizeof(hash));
60
61 git_mutex_lock(&cache->lock);
62 {
63 node = cache->nodes[hash & cache->size_mask];
64
65 if (node != NULL && git_oid_cmp(&node->oid, oid) == 0) {
66 git_cached_obj_incref(node);
67 result = node;
68 }
69 }
70 git_mutex_unlock(&cache->lock);
71
72 return result;
73 }
74
75 void *git_cache_try_store(git_cache *cache, void *_entry)
76 {
77 git_cached_obj *entry = _entry;
78 uint32_t hash;
79
80 memcpy(&hash, &entry->oid, sizeof(hash));
81
82 /* increase the refcount on this object, because
83 * the cache now owns it */
84 git_cached_obj_incref(entry);
85
86 git_mutex_lock(&cache->lock);
87 {
88 git_cached_obj *node = cache->nodes[hash & cache->size_mask];
89
90 if (node == NULL) {
91 cache->nodes[hash & cache->size_mask] = entry;
92 } else if (git_oid_cmp(&node->oid, &entry->oid) == 0) {
93 git_cached_obj_decref(entry, cache->free_obj);
94 entry = node;
95 } else {
96 git_cached_obj_decref(node, cache->free_obj);
97 cache->nodes[hash & cache->size_mask] = entry;
98 }
99 }
100 git_mutex_unlock(&cache->lock);
101
102 /* increase the refcount again, because we are
103 * returning it to the user */
104 git_cached_obj_incref(entry);
105
106 return entry;
107 }