2 * Copyright (C) the libgit2 contributors. All rights reserved.
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.
7 #ifndef INCLUDE_sorted_cache_h__
8 #define INCLUDE_sorted_cache_h__
10 #include "git2_util.h"
22 * The purpose of this data structure is to cache the parsed contents of a
23 * file (a.k.a. the backing file) where each item in the file can be
24 * identified by a key string and you want to both look them up by name
25 * and traverse them in sorted order. Each item is assumed to itself end
26 * in a GIT_FLEX_ARRAY.
29 typedef void (*git_sortedcache_free_item_fn
)(void *payload
, void *item
);
34 size_t item_path_offset
;
35 git_sortedcache_free_item_fn free_item
;
36 void *free_item_payload
;
40 git_futils_filestamp stamp
;
41 char path
[GIT_FLEX_ARRAY
];
44 /* Create a new sortedcache
46 * Even though every sortedcache stores items with a GIT_FLEX_ARRAY at
47 * the end containing their key string, you have to provide the item_cmp
48 * sorting function because the sorting function doesn't get a payload
49 * and therefore can't know the offset to the item key string. :-(
51 * @param out The allocated git_sortedcache
52 * @param item_path_offset Offset to the GIT_FLEX_ARRAY item key in the
53 * struct - use offsetof(struct mine, key-field) to get this
54 * @param free_item Optional callback to free each item
55 * @param free_item_payload Optional payload passed to free_item callback
56 * @param item_cmp Compare the keys of two items
57 * @param path The path to the backing store file for this cache; this
58 * may be NULL. The cache makes it easy to load this and check
59 * if it has been modified since the last load and/or write.
61 GIT_WARN_UNUSED_RESULT
int git_sortedcache_new(
62 git_sortedcache
**out
,
63 size_t item_path_offset
, /* use offsetof(struct, path-field) macro */
64 git_sortedcache_free_item_fn free_item
,
65 void *free_item_payload
,
66 git_vector_cmp item_cmp
,
69 /* Copy a sorted cache
71 * - `copy_item` can be NULL to just use memcpy
72 * - if `lock`, grabs read lock on `src` during copy and releases after
74 GIT_WARN_UNUSED_RESULT
int git_sortedcache_copy(
75 git_sortedcache
**out
,
78 int (*copy_item
)(void *payload
, void *tgt_item
, void *src_item
),
81 /* Free sorted cache (first calling `free_item` callbacks)
83 * Don't call on a locked collection - it may acquire a write lock
85 void git_sortedcache_free(git_sortedcache
*sc
);
87 /* Increment reference count - balance with call to free */
88 void git_sortedcache_incref(git_sortedcache
*sc
);
90 /* Get the pathname associated with this cache at creation time */
91 const char *git_sortedcache_path(git_sortedcache
*sc
);
94 * CACHE WRITE FUNCTIONS
96 * The following functions require you to have a writer lock to make the
97 * modification. Some of the functions take a `wlock` parameter and
98 * will optionally lock and unlock for you if that is passed as true.
102 /* Lock sortedcache for write */
103 GIT_WARN_UNUSED_RESULT
int git_sortedcache_wlock(git_sortedcache
*sc
);
105 /* Unlock sorted cache when done with write */
106 void git_sortedcache_wunlock(git_sortedcache
*sc
);
108 /* Lock cache and load backing file into a buffer.
110 * This grabs a write lock on the cache then looks at the modification
111 * time and size of the file on disk.
113 * If the file appears to have changed, this loads the file contents into
114 * the buffer and returns a positive value leaving the cache locked - the
115 * caller should parse the file content, update the cache as needed, then
116 * release the lock. NOTE: In this case, the caller MUST unlock the cache.
118 * If the file appears to be unchanged, then this automatically releases
119 * the lock on the cache, clears the buffer, and returns 0.
121 * @return 0 if up-to-date, 1 if out-of-date, <0 on error
123 GIT_WARN_UNUSED_RESULT
int git_sortedcache_lockandload(
124 git_sortedcache
*sc
, git_str
*buf
);
126 /* Refresh file timestamp after write completes
127 * You should already be holding the write lock when you call this.
129 void git_sortedcache_updated(git_sortedcache
*sc
);
131 /* Release all items in sorted cache
133 * If `wlock` is true, grabs write lock and releases when done, otherwise
134 * you should already be holding a write lock when you call this.
136 GIT_WARN_UNUSED_RESULT
int git_sortedcache_clear(
137 git_sortedcache
*sc
, bool wlock
);
139 /* Find and/or insert item, returning pointer to item data.
140 * You should already be holding the write lock when you call this.
142 GIT_WARN_UNUSED_RESULT
int git_sortedcache_upsert(
143 void **out
, git_sortedcache
*sc
, const char *key
);
145 /* Removes entry at pos from cache
146 * You should already be holding the write lock when you call this.
148 int git_sortedcache_remove(git_sortedcache
*sc
, size_t pos
);
151 * CACHE READ FUNCTIONS
153 * The following functions access items in the cache. To prevent the
154 * results from being invalidated before they can be used, you should be
155 * holding either a read lock or a write lock when using these functions.
159 /* Lock sortedcache for read */
160 GIT_WARN_UNUSED_RESULT
int git_sortedcache_rlock(git_sortedcache
*sc
);
162 /* Unlock sorted cache when done with read */
163 void git_sortedcache_runlock(git_sortedcache
*sc
);
165 /* Lookup item by key - returns NULL if not found */
166 void *git_sortedcache_lookup(const git_sortedcache
*sc
, const char *key
);
168 /* Get how many items are in the cache
170 * You can call this function without holding a lock, but be aware
171 * that it may change before you use it.
173 size_t git_sortedcache_entrycount(const git_sortedcache
*sc
);
175 /* Lookup item by index - returns NULL if out of range */
176 void *git_sortedcache_entry(git_sortedcache
*sc
, size_t pos
);
178 /* Lookup index of item by key - returns GIT_ENOTFOUND if not found */
179 int git_sortedcache_lookup_index(
180 size_t *out
, git_sortedcache
*sc
, const char *key
);