2 * Copyright (C) 2009-2011 the libgit2 contributors
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.
9 #include "repository.h"
11 #include "thread-utils.h"
14 int git_cache_init(git_cache
*cache
, size_t size
, git_cached_obj_freeptr free_ptr
)
21 /* round up size to closest power of 2 */
29 cache
->size_mask
= size
;
31 cache
->free_obj
= free_ptr
;
33 cache
->nodes
= git__malloc((size
+ 1) * sizeof(cache_node
));
34 if (cache
->nodes
== NULL
)
37 for (i
= 0; i
< (size
+ 1); ++i
) {
38 git_mutex_init(&cache
->nodes
[i
].lock
);
39 cache
->nodes
[i
].ptr
= NULL
;
45 void git_cache_free(git_cache
*cache
)
49 for (i
= 0; i
< (cache
->size_mask
+ 1); ++i
) {
50 if (cache
->nodes
[i
].ptr
)
51 git_cached_obj_decref(cache
->nodes
[i
].ptr
, cache
->free_obj
);
53 git_mutex_free(&cache
->nodes
[i
].lock
);
59 void *git_cache_get(git_cache
*cache
, const git_oid
*oid
)
62 cache_node
*node
= NULL
;
65 hash
= (const uint32_t *)oid
->id
;
66 node
= &cache
->nodes
[hash
[0] & cache
->size_mask
];
68 git_mutex_lock(&node
->lock
);
70 if (node
->ptr
&& git_cached_obj_compare(node
->ptr
, oid
) == 0) {
71 git_cached_obj_incref(node
->ptr
);
75 git_mutex_unlock(&node
->lock
);
80 void *git_cache_try_store(git_cache
*cache
, void *entry
)
84 cache_node
*node
= NULL
;
86 oid
= &((git_cached_obj
*)entry
)->oid
;
87 hash
= (const uint32_t *)oid
->id
;
88 node
= &cache
->nodes
[hash
[0] & cache
->size_mask
];
90 /* increase the refcount on this object, because
91 * the cache now owns it */
92 git_cached_obj_incref(entry
);
93 git_mutex_lock(&node
->lock
);
95 if (node
->ptr
== NULL
) {
97 } else if (git_cached_obj_compare(node
->ptr
, oid
) == 0) {
98 git_cached_obj_decref(entry
, cache
->free_obj
);
101 git_cached_obj_decref(node
->ptr
, cache
->free_obj
);
105 /* increase the refcount again, because we are
106 * returning it to the user */
107 git_cached_obj_incref(entry
);
108 git_mutex_unlock(&node
->lock
);