packaging: Add contrib installation
[platform/upstream/git.git] / oidset.c
index ac169f0..5aac633 100644 (file)
--- a/oidset.c
+++ b/oidset.c
@@ -1,49 +1,85 @@
 #include "cache.h"
 #include "oidset.h"
 
-struct oidset_entry {
-       struct hashmap_entry hash;
-       struct object_id oid;
-};
-
-static int oidset_hashcmp(const void *va, const void *vb,
-                         const void *vkey)
+void oidset_init(struct oidset *set, size_t initial_size)
 {
-       const struct oidset_entry *a = va, *b = vb;
-       const struct object_id *key = vkey;
-       return oidcmp(&a->oid, key ? key : &b->oid);
+       memset(&set->set, 0, sizeof(set->set));
+       if (initial_size)
+               kh_resize_oid_set(&set->set, initial_size);
 }
 
 int oidset_contains(const struct oidset *set, const struct object_id *oid)
 {
-       struct hashmap_entry key;
-
-       if (!set->map.cmpfn)
-               return 0;
-
-       hashmap_entry_init(&key, sha1hash(oid->hash));
-       return !!hashmap_get(&set->map, &key, oid);
+       khiter_t pos = kh_get_oid_set(&set->set, *oid);
+       return pos != kh_end(&set->set);
 }
 
 int oidset_insert(struct oidset *set, const struct object_id *oid)
 {
-       struct oidset_entry *entry;
+       int added;
+       kh_put_oid_set(&set->set, *oid, &added);
+       return !added;
+}
 
-       if (!set->map.cmpfn)
-               hashmap_init(&set->map, oidset_hashcmp, 0);
+int oidset_remove(struct oidset *set, const struct object_id *oid)
+{
+       khiter_t pos = kh_get_oid_set(&set->set, *oid);
+       if (pos == kh_end(&set->set))
+               return 0;
+       kh_del_oid_set(&set->set, pos);
+       return 1;
+}
 
-       if (oidset_contains(set, oid))
-               return 1;
+void oidset_clear(struct oidset *set)
+{
+       kh_release_oid_set(&set->set);
+       oidset_init(set, 0);
+}
 
-       entry = xmalloc(sizeof(*entry));
-       hashmap_entry_init(&entry->hash, sha1hash(oid->hash));
-       oidcpy(&entry->oid, oid);
+int oidset_size(struct oidset *set)
+{
+       return kh_size(&set->set);
+}
 
-       hashmap_add(&set->map, entry);
-       return 0;
+void oidset_parse_file(struct oidset *set, const char *path)
+{
+       oidset_parse_file_carefully(set, path, NULL, NULL);
 }
 
-void oidset_clear(struct oidset *set)
+void oidset_parse_file_carefully(struct oidset *set, const char *path,
+                                oidset_parse_tweak_fn fn, void *cbdata)
 {
-       hashmap_free(&set->map, 1);
+       FILE *fp;
+       struct strbuf sb = STRBUF_INIT;
+       struct object_id oid;
+
+       fp = fopen(path, "r");
+       if (!fp)
+               die("could not open object name list: %s", path);
+       while (!strbuf_getline(&sb, fp)) {
+               const char *p;
+               const char *name;
+
+               /*
+                * Allow trailing comments, leading whitespace
+                * (including before commits), and empty or whitespace
+                * only lines.
+                */
+               name = strchr(sb.buf, '#');
+               if (name)
+                       strbuf_setlen(&sb, name - sb.buf);
+               strbuf_trim(&sb);
+               if (!sb.len)
+                       continue;
+
+               if (parse_oid_hex(sb.buf, &oid, &p) || *p != '\0')
+                       die("invalid object name: %s", sb.buf);
+               if (fn && fn(&oid, cbdata))
+                       continue;
+               oidset_insert(set, &oid);
+       }
+       if (ferror(fp))
+               die_errno("Could not read '%s'", path);
+       fclose(fp);
+       strbuf_release(&sb);
 }