mirror of
https://git.proxmox.com/git/libgit2
synced 2025-06-28 08:04:35 +00:00
Add sortedcache APIs to lookup index and remove
This adds two other APIs that I need to the sortedcache type.
This commit is contained in:
parent
0b7cdc0263
commit
a4977169e1
@ -295,3 +295,62 @@ void *git_sortedcache_entry(const git_sortedcache *sc, size_t pos)
|
|||||||
{
|
{
|
||||||
return git_vector_get(&sc->items, pos);
|
return git_vector_get(&sc->items, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct sortedcache_magic_key {
|
||||||
|
size_t offset;
|
||||||
|
const char *key;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int sortedcache_magic_cmp(const void *key, const void *value)
|
||||||
|
{
|
||||||
|
const struct sortedcache_magic_key *magic = key;
|
||||||
|
const char *value_key = ((const char *)value) + magic->offset;
|
||||||
|
return strcmp(magic->key, value_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lookup index of item by key */
|
||||||
|
int git_sortedcache_lookup_index(
|
||||||
|
size_t *out, git_sortedcache *sc, const char *key)
|
||||||
|
{
|
||||||
|
struct sortedcache_magic_key magic;
|
||||||
|
|
||||||
|
magic.offset = sc->item_path_offset;
|
||||||
|
magic.key = key;
|
||||||
|
|
||||||
|
return git_vector_bsearch2(out, &sc->items, sortedcache_magic_cmp, &magic);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove entry from cache */
|
||||||
|
int git_sortedcache_remove(git_sortedcache *sc, size_t pos, bool lock)
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
|
char *item;
|
||||||
|
khiter_t mappos;
|
||||||
|
|
||||||
|
if (lock && git_sortedcache_lock(sc) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* because of pool allocation, this can't actually remove the item,
|
||||||
|
* but we can remove it from the items vector and the hash table.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((item = git_vector_get(&sc->items, pos)) == NULL) {
|
||||||
|
giterr_set(GITERR_INVALID, "Removing item out of range");
|
||||||
|
error = GIT_ENOTFOUND;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)git_vector_remove(&sc->items, pos);
|
||||||
|
|
||||||
|
mappos = git_strmap_lookup_index(sc->map, item + sc->item_path_offset);
|
||||||
|
git_strmap_delete_at(sc->map, mappos);
|
||||||
|
|
||||||
|
if (sc->free_item)
|
||||||
|
sc->free_item(sc->free_item_payload, item);
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (lock)
|
||||||
|
git_sortedcache_unlock(sc);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -98,4 +98,11 @@ size_t git_sortedcache_entrycount(const git_sortedcache *sc);
|
|||||||
/* lookup item by index */
|
/* lookup item by index */
|
||||||
void *git_sortedcache_entry(const git_sortedcache *sc, size_t pos);
|
void *git_sortedcache_entry(const git_sortedcache *sc, size_t pos);
|
||||||
|
|
||||||
|
/* lookup index of item by key */
|
||||||
|
int git_sortedcache_lookup_index(
|
||||||
|
size_t *out, git_sortedcache *sc, const char *key);
|
||||||
|
|
||||||
|
/* remove entry from cache */
|
||||||
|
int git_sortedcache_remove(git_sortedcache *sc, size_t pos, bool lock);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -10,6 +10,7 @@ void test_core_sortedcache__name_only(void)
|
|||||||
{
|
{
|
||||||
git_sortedcache *sc;
|
git_sortedcache *sc;
|
||||||
void *item;
|
void *item;
|
||||||
|
size_t pos;
|
||||||
|
|
||||||
cl_git_pass(git_sortedcache_new(
|
cl_git_pass(git_sortedcache_new(
|
||||||
&sc, 0, NULL, NULL, name_only_cmp, NULL));
|
&sc, 0, NULL, NULL, name_only_cmp, NULL));
|
||||||
@ -44,6 +45,15 @@ void test_core_sortedcache__name_only(void)
|
|||||||
cl_assert_equal_s("zzz", item);
|
cl_assert_equal_s("zzz", item);
|
||||||
cl_assert(git_sortedcache_entry(sc, 5) == NULL);
|
cl_assert(git_sortedcache_entry(sc, 5) == NULL);
|
||||||
|
|
||||||
|
cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "aaa"));
|
||||||
|
cl_assert_equal_sz(0, pos);
|
||||||
|
cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "iii"));
|
||||||
|
cl_assert_equal_sz(2, pos);
|
||||||
|
cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "zzz"));
|
||||||
|
cl_assert_equal_sz(4, pos);
|
||||||
|
cl_assert_equal_i(
|
||||||
|
GIT_ENOTFOUND, git_sortedcache_lookup_index(&pos, sc, "abc"));
|
||||||
|
|
||||||
git_sortedcache_clear(sc, true);
|
git_sortedcache_clear(sc, true);
|
||||||
|
|
||||||
cl_assert_equal_sz(0, git_sortedcache_entrycount(sc));
|
cl_assert_equal_sz(0, git_sortedcache_entrycount(sc));
|
||||||
@ -182,6 +192,34 @@ void test_core_sortedcache__in_memory(void)
|
|||||||
cl_assert_equal_i(10, item->value);
|
cl_assert_equal_i(10, item->value);
|
||||||
cl_assert(git_sortedcache_entry(sc, 3) == NULL);
|
cl_assert(git_sortedcache_entry(sc, 3) == NULL);
|
||||||
|
|
||||||
|
{
|
||||||
|
size_t pos;
|
||||||
|
|
||||||
|
cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "again"));
|
||||||
|
cl_assert_equal_sz(0, pos);
|
||||||
|
cl_git_pass(git_sortedcache_remove(sc, pos, true));
|
||||||
|
cl_assert_equal_i(
|
||||||
|
GIT_ENOTFOUND, git_sortedcache_lookup_index(&pos, sc, "again"));
|
||||||
|
|
||||||
|
cl_assert_equal_sz(2, git_sortedcache_entrycount(sc));
|
||||||
|
|
||||||
|
cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "testing"));
|
||||||
|
cl_assert_equal_sz(1, pos);
|
||||||
|
cl_git_pass(git_sortedcache_remove(sc, pos, true));
|
||||||
|
cl_assert_equal_i(
|
||||||
|
GIT_ENOTFOUND, git_sortedcache_lookup_index(&pos, sc, "testing"));
|
||||||
|
|
||||||
|
cl_assert_equal_sz(1, git_sortedcache_entrycount(sc));
|
||||||
|
|
||||||
|
cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "final"));
|
||||||
|
cl_assert_equal_sz(0, pos);
|
||||||
|
cl_git_pass(git_sortedcache_remove(sc, pos, true));
|
||||||
|
cl_assert_equal_i(
|
||||||
|
GIT_ENOTFOUND, git_sortedcache_lookup_index(&pos, sc, "final"));
|
||||||
|
|
||||||
|
cl_assert_equal_sz(0, git_sortedcache_entrycount(sc));
|
||||||
|
}
|
||||||
|
|
||||||
git_sortedcache_free(sc);
|
git_sortedcache_free(sc);
|
||||||
|
|
||||||
cl_assert_equal_i(3, free_count);
|
cl_assert_equal_i(3, free_count);
|
||||||
@ -223,6 +261,7 @@ void test_core_sortedcache__on_disk(void)
|
|||||||
git_sortedcache *sc;
|
git_sortedcache *sc;
|
||||||
sortedcache_test_struct *item;
|
sortedcache_test_struct *item;
|
||||||
int free_count = 0;
|
int free_count = 0;
|
||||||
|
size_t pos;
|
||||||
|
|
||||||
cl_git_mkfile("cacheitems.txt", "10 abc\n20 bcd\n30 cde\n");
|
cl_git_mkfile("cacheitems.txt", "10 abc\n20 bcd\n30 cde\n");
|
||||||
|
|
||||||
@ -291,6 +330,19 @@ void test_core_sortedcache__on_disk(void)
|
|||||||
cl_assert_equal_s("zzz", item->path);
|
cl_assert_equal_s("zzz", item->path);
|
||||||
cl_assert_equal_i(200, item->value);
|
cl_assert_equal_i(200, item->value);
|
||||||
|
|
||||||
|
cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "aaa"));
|
||||||
|
cl_assert_equal_sz(0, pos);
|
||||||
|
cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "abc"));
|
||||||
|
cl_assert_equal_sz(1, pos);
|
||||||
|
cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "final"));
|
||||||
|
cl_assert_equal_sz(2, pos);
|
||||||
|
cl_git_pass(git_sortedcache_lookup_index(&pos, sc, "zzz"));
|
||||||
|
cl_assert_equal_sz(3, pos);
|
||||||
|
cl_assert_equal_i(
|
||||||
|
GIT_ENOTFOUND, git_sortedcache_lookup_index(&pos, sc, "missing"));
|
||||||
|
cl_assert_equal_i(
|
||||||
|
GIT_ENOTFOUND, git_sortedcache_lookup_index(&pos, sc, "cde"));
|
||||||
|
|
||||||
git_sortedcache_free(sc);
|
git_sortedcache_free(sc);
|
||||||
|
|
||||||
cl_assert_equal_i(7, free_count);
|
cl_assert_equal_i(7, free_count);
|
||||||
|
Loading…
Reference in New Issue
Block a user