]> git.proxmox.com Git - libgit2.git/commitdiff
Add sortedcache APIs to lookup index and remove
authorRussell Belfer <rb@github.com>
Wed, 21 Aug 2013 21:09:38 +0000 (14:09 -0700)
committerRussell Belfer <rb@github.com>
Wed, 21 Aug 2013 21:09:38 +0000 (14:09 -0700)
This adds two other APIs that I need to the sortedcache type.

src/sortedcache.c
src/sortedcache.h
tests-clar/core/sortedcache.c

index 6015d616d6fad0da3c44da0d3ee07e9338ba03bd..2efa3c4e96f13dfd3eea27f580b1e5631326c6bf 100644 (file)
@@ -295,3 +295,62 @@ void *git_sortedcache_entry(const git_sortedcache *sc, size_t 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;
+}
+
index 5d0d8f5a75bc7e6f9018e788e83422d96054c1fd..f63ad645b08cc5ba14f8c0584432d771bdde5917 100644 (file)
@@ -98,4 +98,11 @@ size_t git_sortedcache_entrycount(const git_sortedcache *sc);
 /* lookup item by index */
 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
index f192af31df4ec47df4c4bd0a75718898454a31c3..91415943d7462ce92c200009a983065eff7f628e 100644 (file)
@@ -10,6 +10,7 @@ void test_core_sortedcache__name_only(void)
 {
        git_sortedcache *sc;
        void *item;
+       size_t pos;
 
        cl_git_pass(git_sortedcache_new(
                &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(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);
 
        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(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);
 
        cl_assert_equal_i(3, free_count);
@@ -223,6 +261,7 @@ void test_core_sortedcache__on_disk(void)
        git_sortedcache *sc;
        sortedcache_test_struct *item;
        int free_count = 0;
+       size_t pos;
 
        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_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);
 
        cl_assert_equal_i(7, free_count);