]>
Commit | Line | Data |
---|---|---|
0b7cdc02 RB |
1 | /* |
2 | * Copyright (C) the libgit2 contributors. All rights reserved. | |
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 | #ifndef INCLUDE_sorted_cache_h__ | |
8 | #define INCLUDE_sorted_cache_h__ | |
9 | ||
eae0bfdc PP |
10 | #include "common.h" |
11 | ||
0b7cdc02 | 12 | #include "util.h" |
22a2d3d5 | 13 | #include "futils.h" |
0b7cdc02 RB |
14 | #include "vector.h" |
15 | #include "thread-utils.h" | |
16 | #include "pool.h" | |
17 | #include "strmap.h" | |
18 | ||
19b9a092 RB |
19 | #include <stddef.h> |
20 | ||
0b7cdc02 RB |
21 | /* |
22 | * The purpose of this data structure is to cache the parsed contents of a | |
805755f4 RB |
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. | |
0b7cdc02 RB |
27 | */ |
28 | ||
29 | typedef void (*git_sortedcache_free_item_fn)(void *payload, void *item); | |
30 | ||
31 | typedef struct { | |
32 | git_refcount rc; | |
8d9a85d4 | 33 | git_rwlock lock; |
0b7cdc02 RB |
34 | size_t item_path_offset; |
35 | git_sortedcache_free_item_fn free_item; | |
36 | void *free_item_payload; | |
37 | git_pool pool; | |
38 | git_vector items; | |
39 | git_strmap *map; | |
40 | git_futils_filestamp stamp; | |
41 | char path[GIT_FLEX_ARRAY]; | |
42 | } git_sortedcache; | |
43 | ||
8d9a85d4 | 44 | /* Create a new sortedcache |
0b7cdc02 | 45 | * |
8d9a85d4 | 46 | * Even though every sortedcache stores items with a GIT_FLEX_ARRAY at |
0b7cdc02 RB |
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. :-( | |
805755f4 RB |
50 | * |
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. | |
0b7cdc02 RB |
60 | */ |
61 | int git_sortedcache_new( | |
62 | git_sortedcache **out, | |
8d9a85d4 | 63 | size_t item_path_offset, /* use offsetof(struct, path-field) macro */ |
0b7cdc02 RB |
64 | git_sortedcache_free_item_fn free_item, |
65 | void *free_item_payload, | |
66 | git_vector_cmp item_cmp, | |
67 | const char *path); | |
68 | ||
8d9a85d4 | 69 | /* Copy a sorted cache |
0b7cdc02 | 70 | * |
8d9a85d4 | 71 | * - `copy_item` can be NULL to just use memcpy |
805755f4 | 72 | * - if `lock`, grabs read lock on `src` during copy and releases after |
0b7cdc02 RB |
73 | */ |
74 | int git_sortedcache_copy( | |
75 | git_sortedcache **out, | |
76 | git_sortedcache *src, | |
805755f4 | 77 | bool lock, |
0b7cdc02 RB |
78 | int (*copy_item)(void *payload, void *tgt_item, void *src_item), |
79 | void *payload); | |
80 | ||
8d9a85d4 RB |
81 | /* Free sorted cache (first calling `free_item` callbacks) |
82 | * | |
83 | * Don't call on a locked collection - it may acquire a write lock | |
3eecadcc | 84 | */ |
0b7cdc02 RB |
85 | void git_sortedcache_free(git_sortedcache *sc); |
86 | ||
8d9a85d4 | 87 | /* Increment reference count - balance with call to free */ |
0b7cdc02 RB |
88 | void git_sortedcache_incref(git_sortedcache *sc); |
89 | ||
8d9a85d4 RB |
90 | /* Get the pathname associated with this cache at creation time */ |
91 | const char *git_sortedcache_path(git_sortedcache *sc); | |
0b7cdc02 | 92 | |
8d9a85d4 RB |
93 | /* |
94 | * CACHE WRITE FUNCTIONS | |
95 | * | |
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. | |
99 | * | |
100 | */ | |
0b7cdc02 | 101 | |
8d9a85d4 RB |
102 | /* Lock sortedcache for write */ |
103 | int git_sortedcache_wlock(git_sortedcache *sc); | |
0b7cdc02 | 104 | |
8d9a85d4 RB |
105 | /* Unlock sorted cache when done with write */ |
106 | void git_sortedcache_wunlock(git_sortedcache *sc); | |
0b7cdc02 | 107 | |
805755f4 RB |
108 | /* Lock cache and load backing file into a buffer. |
109 | * | |
110 | * This grabs a write lock on the cache then looks at the modification | |
111 | * time and size of the file on disk. | |
112 | * | |
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. | |
117 | * | |
118 | * If the file appears to be unchanged, then this automatically releases | |
119 | * the lock on the cache, clears the buffer, and returns 0. | |
8d9a85d4 | 120 | * |
0b7cdc02 RB |
121 | * @return 0 if up-to-date, 1 if out-of-date, <0 on error |
122 | */ | |
123 | int git_sortedcache_lockandload(git_sortedcache *sc, git_buf *buf); | |
124 | ||
8d9a85d4 RB |
125 | /* Refresh file timestamp after write completes |
126 | * You should already be holding the write lock when you call this. | |
127 | */ | |
128 | void git_sortedcache_updated(git_sortedcache *sc); | |
129 | ||
130 | /* Release all items in sorted cache | |
131 | * | |
132 | * If `wlock` is true, grabs write lock and releases when done, otherwise | |
133 | * you should already be holding a write lock when you call this. | |
134 | */ | |
135 | int git_sortedcache_clear(git_sortedcache *sc, bool wlock); | |
136 | ||
137 | /* Find and/or insert item, returning pointer to item data. | |
138 | * You should already be holding the write lock when you call this. | |
3eecadcc | 139 | */ |
0b7cdc02 RB |
140 | int git_sortedcache_upsert( |
141 | void **out, git_sortedcache *sc, const char *key); | |
142 | ||
8d9a85d4 RB |
143 | /* Removes entry at pos from cache |
144 | * You should already be holding the write lock when you call this. | |
145 | */ | |
146 | int git_sortedcache_remove(git_sortedcache *sc, size_t pos); | |
147 | ||
148 | /* | |
149 | * CACHE READ FUNCTIONS | |
150 | * | |
151 | * The following functions access items in the cache. To prevent the | |
152 | * results from being invalidated before they can be used, you should be | |
153 | * holding either a read lock or a write lock when using these functions. | |
154 | * | |
3eecadcc | 155 | */ |
8d9a85d4 RB |
156 | |
157 | /* Lock sortedcache for read */ | |
158 | int git_sortedcache_rlock(git_sortedcache *sc); | |
159 | ||
160 | /* Unlock sorted cache when done with read */ | |
161 | void git_sortedcache_runlock(git_sortedcache *sc); | |
162 | ||
163 | /* Lookup item by key - returns NULL if not found */ | |
0b7cdc02 RB |
164 | void *git_sortedcache_lookup(const git_sortedcache *sc, const char *key); |
165 | ||
8d9a85d4 RB |
166 | /* Get how many items are in the cache |
167 | * | |
168 | * You can call this function without holding a lock, but be aware | |
169 | * that it may change before you use it. | |
170 | */ | |
0b7cdc02 RB |
171 | size_t git_sortedcache_entrycount(const git_sortedcache *sc); |
172 | ||
8d9a85d4 RB |
173 | /* Lookup item by index - returns NULL if out of range */ |
174 | void *git_sortedcache_entry(git_sortedcache *sc, size_t pos); | |
0b7cdc02 | 175 | |
8d9a85d4 | 176 | /* Lookup index of item by key - returns GIT_ENOTFOUND if not found */ |
a4977169 RB |
177 | int git_sortedcache_lookup_index( |
178 | size_t *out, git_sortedcache *sc, const char *key); | |
179 | ||
0b7cdc02 | 180 | #endif |