From 11510decd020c3cb8936432d4d4bfb214492fcc4 Mon Sep 17 00:00:00 2001 From: Christian Couder Date: Sat, 15 Jun 2019 12:06:59 +0200 Subject: [PATCH 1/4] t/helper: add test-oidmap.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This new helper is very similar to "test-hashmap.c" and will help test how `struct oidmap` from oidmap.{c,h} can be used. Helped-by: SZEDER Gábor Helped-by: Jeff King Signed-off-by: Christian Couder Signed-off-by: Junio C Hamano --- Makefile | 1 + t/helper/test-oidmap.c | 126 +++++++++++++++++++++++++++++++++++++++++ t/helper/test-tool.c | 1 + t/helper/test-tool.h | 1 + 4 files changed, 129 insertions(+) create mode 100644 t/helper/test-oidmap.c diff --git a/Makefile b/Makefile index 8a7e2353520ddd..5efc7700edbb69 100644 --- a/Makefile +++ b/Makefile @@ -727,6 +727,7 @@ TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o TEST_BUILTINS_OBJS += test-match-trees.o TEST_BUILTINS_OBJS += test-mergesort.o TEST_BUILTINS_OBJS += test-mktemp.o +TEST_BUILTINS_OBJS += test-oidmap.o TEST_BUILTINS_OBJS += test-online-cpus.o TEST_BUILTINS_OBJS += test-parse-options.o TEST_BUILTINS_OBJS += test-path-utils.o diff --git a/t/helper/test-oidmap.c b/t/helper/test-oidmap.c new file mode 100644 index 00000000000000..7036588175f40f --- /dev/null +++ b/t/helper/test-oidmap.c @@ -0,0 +1,126 @@ +#include "test-tool.h" +#include "cache.h" +#include "oidmap.h" +#include "strbuf.h" + +/* key is an oid and value is a name (could be a refname for example) */ +struct test_entry { + struct oidmap_entry entry; + char name[FLEX_ARRAY]; +}; + +#define DELIM " \t\r\n" + +/* + * Read stdin line by line and print result of commands to stdout: + * + * hash oidkey -> sha1hash(oidkey) + * put oidkey namevalue -> NULL / old namevalue + * get oidkey -> NULL / namevalue + * remove oidkey -> NULL / old namevalue + * iterate -> oidkey1 namevalue1\noidkey2 namevalue2\n... + * + */ +int cmd__oidmap(int argc, const char **argv) +{ + struct strbuf line = STRBUF_INIT; + struct oidmap map = OIDMAP_INIT; + + setup_git_directory(); + + /* init oidmap */ + oidmap_init(&map, 0); + + /* process commands from stdin */ + while (strbuf_getline(&line, stdin) != EOF) { + char *cmd, *p1 = NULL, *p2 = NULL; + struct test_entry *entry; + struct object_id oid; + + /* break line into command and up to two parameters */ + cmd = strtok(line.buf, DELIM); + /* ignore empty lines */ + if (!cmd || *cmd == '#') + continue; + + p1 = strtok(NULL, DELIM); + if (p1) + p2 = strtok(NULL, DELIM); + + if (!strcmp("add", cmd) && p1 && p2) { + + if (get_oid(p1, &oid)) { + printf("Unknown oid: %s\n", p1); + continue; + } + + /* create entry with oidkey from p1, value = p2 */ + FLEX_ALLOC_STR(entry, name, p2); + oidcpy(&entry->entry.oid, &oid); + + /* add to oidmap */ + oidmap_put(&map, entry); + + } else if (!strcmp("put", cmd) && p1 && p2) { + + if (get_oid(p1, &oid)) { + printf("Unknown oid: %s\n", p1); + continue; + } + + /* create entry with oid_key = p1, name_value = p2 */ + FLEX_ALLOC_STR(entry, name, p2); + oidcpy(&entry->entry.oid, &oid); + + /* add / replace entry */ + entry = oidmap_put(&map, entry); + + /* print and free replaced entry, if any */ + puts(entry ? entry->name : "NULL"); + free(entry); + + } else if (!strcmp("get", cmd) && p1) { + + if (get_oid(p1, &oid)) { + printf("Unknown oid: %s\n", p1); + continue; + } + + /* lookup entry in oidmap */ + entry = oidmap_get(&map, &oid); + + /* print result */ + puts(entry ? entry->name : "NULL"); + + } else if (!strcmp("remove", cmd) && p1) { + + if (get_oid(p1, &oid)) { + printf("Unknown oid: %s\n", p1); + continue; + } + + /* remove entry from oidmap */ + entry = oidmap_remove(&map, &oid); + + /* print result and free entry*/ + puts(entry ? entry->name : "NULL"); + free(entry); + + } else if (!strcmp("iterate", cmd)) { + + struct oidmap_iter iter; + oidmap_iter_init(&map, &iter); + while ((entry = oidmap_iter_next(&iter))) + printf("%s %s\n", oid_to_hex(&entry->entry.oid), entry->name); + + } else { + + printf("Unknown command %s\n", cmd); + + } + } + + strbuf_release(&line); + oidmap_free(&map, 1); + return 0; +} diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index 087a8c0cc9da64..1eac25233f7ce6 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -35,6 +35,7 @@ static struct test_cmd cmds[] = { { "match-trees", cmd__match_trees }, { "mergesort", cmd__mergesort }, { "mktemp", cmd__mktemp }, + { "oidmap", cmd__oidmap }, { "online-cpus", cmd__online_cpus }, { "parse-options", cmd__parse_options }, { "path-utils", cmd__path_utils }, diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index 7e703f3038ae43..c7a46dc320e93b 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -25,6 +25,7 @@ int cmd__lazy_init_name_hash(int argc, const char **argv); int cmd__match_trees(int argc, const char **argv); int cmd__mergesort(int argc, const char **argv); int cmd__mktemp(int argc, const char **argv); +int cmd__oidmap(int argc, const char **argv); int cmd__online_cpus(int argc, const char **argv); int cmd__parse_options(int argc, const char **argv); int cmd__path_utils(int argc, const char **argv); From c1f7f53834636081af83743737a45e3c7fee7ee0 Mon Sep 17 00:00:00 2001 From: Christian Couder Date: Sat, 15 Jun 2019 12:07:00 +0200 Subject: [PATCH 2/4] t: add t0016-oidmap.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add actual tests for operations using `struct oidmap` from oidmap.{c,h}. Helped-by: SZEDER Gábor Helped-by: Jeff King Signed-off-by: Christian Couder Signed-off-by: Junio C Hamano --- t/t0016-oidmap.sh | 84 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100755 t/t0016-oidmap.sh diff --git a/t/t0016-oidmap.sh b/t/t0016-oidmap.sh new file mode 100755 index 00000000000000..af17264ce334cb --- /dev/null +++ b/t/t0016-oidmap.sh @@ -0,0 +1,84 @@ +#!/bin/sh + +test_description='test oidmap' +. ./test-lib.sh + +# This purposefully is very similar to t0011-hashmap.sh + +test_oidmap () { + echo "$1" | test-tool oidmap $3 >actual && + echo "$2" >expect && + test_cmp expect actual +} + + +test_expect_success 'setup' ' + + test_commit one && + test_commit two && + test_commit three && + test_commit four + +' + +test_expect_success 'put' ' + +test_oidmap "put one 1 +put two 2 +put invalidOid 4 +put three 3" "NULL +NULL +Unknown oid: invalidOid +NULL" + +' + +test_expect_success 'replace' ' + +test_oidmap "put one 1 +put two 2 +put three 3 +put invalidOid 4 +put two deux +put one un" "NULL +NULL +NULL +Unknown oid: invalidOid +2 +1" + +' + +test_expect_success 'get' ' + +test_oidmap "put one 1 +put two 2 +put three 3 +get two +get four +get invalidOid +get one" "NULL +NULL +NULL +2 +NULL +Unknown oid: invalidOid +1" + +' + +test_expect_success 'iterate' ' + +test_oidmap "put one 1 +put two 2 +put three 3 +iterate" "NULL +NULL +NULL +$(git rev-parse two) 2 +$(git rev-parse one) 1 +$(git rev-parse three) 3" + +' + +test_done From 19cfa0e03316df26045c2f6d11ef860c2ca79a92 Mon Sep 17 00:00:00 2001 From: Christian Couder Date: Sat, 15 Jun 2019 12:07:01 +0200 Subject: [PATCH 3/4] oidmap: use sha1hash() instead of static hash() function Get rid of the static hash() function in oidmap.c which is redundant with sha1hash(). Use sha1hash() directly instead. Let's be more consistent and not use several hash functions doing nearly exactly the same thing. Signed-off-by: Christian Couder Signed-off-by: Junio C Hamano --- oidmap.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/oidmap.c b/oidmap.c index b0841a0f5870ba..01c206aaefe1da 100644 --- a/oidmap.c +++ b/oidmap.c @@ -12,13 +12,6 @@ static int oidmap_neq(const void *hashmap_cmp_fn_data, &((const struct oidmap_entry *) entry_or_key)->oid); } -static int hash(const struct object_id *oid) -{ - int hash; - memcpy(&hash, oid->hash, sizeof(hash)); - return hash; -} - void oidmap_init(struct oidmap *map, size_t initial_size) { hashmap_init(&map->map, oidmap_neq, NULL, initial_size); @@ -36,7 +29,7 @@ void *oidmap_get(const struct oidmap *map, const struct object_id *key) if (!map->map.cmpfn) return NULL; - return hashmap_get_from_hash(&map->map, hash(key), key); + return hashmap_get_from_hash(&map->map, sha1hash(key->hash), key); } void *oidmap_remove(struct oidmap *map, const struct object_id *key) @@ -46,7 +39,7 @@ void *oidmap_remove(struct oidmap *map, const struct object_id *key) if (!map->map.cmpfn) oidmap_init(map, 0); - hashmap_entry_init(&entry, hash(key)); + hashmap_entry_init(&entry, sha1hash(key->hash)); return hashmap_remove(&map->map, &entry, key); } @@ -57,6 +50,6 @@ void *oidmap_put(struct oidmap *map, void *entry) if (!map->map.cmpfn) oidmap_init(map, 0); - hashmap_entry_init(&to_put->internal_entry, hash(&to_put->oid)); + hashmap_entry_init(&to_put->internal_entry, sha1hash(to_put->oid.hash)); return hashmap_put(&map->map, to_put); } From a1100d2ceed75a9523981bfab607dedd2564ef8c Mon Sep 17 00:00:00 2001 From: Christian Couder Date: Sat, 15 Jun 2019 12:07:02 +0200 Subject: [PATCH 4/4] test-hashmap: remove 'hash' command If hashes like strhash() are updated, for example to use a different hash algorithm, we should not have to be updating t0011 to change out the hashes. As long as hashmap can store and retrieve values, and that it performs well, we should not care what are the values of the hashes. Let's just focus on the externally visible behavior instead. Suggested-by: Jeff King Signed-off-by: Christian Couder Signed-off-by: Junio C Hamano --- t/helper/test-hashmap.c | 9 +-------- t/t0011-hashmap.sh | 9 --------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/t/helper/test-hashmap.c b/t/helper/test-hashmap.c index 23d2b172fe708f..aaf17b0ddf9e8d 100644 --- a/t/helper/test-hashmap.c +++ b/t/helper/test-hashmap.c @@ -173,14 +173,7 @@ int cmd__hashmap(int argc, const char **argv) p2 = strtok(NULL, DELIM); } - if (!strcmp("hash", cmd) && p1) { - - /* print results of different hash functions */ - printf("%u %u %u %u\n", - strhash(p1), memhash(p1, strlen(p1)), - strihash(p1), memihash(p1, strlen(p1))); - - } else if (!strcmp("add", cmd) && p1 && p2) { + if (!strcmp("add", cmd) && p1 && p2) { /* create entry with key = p1, value = p2 */ entry = alloc_test_entry(hash, p1, p2); diff --git a/t/t0011-hashmap.sh b/t/t0011-hashmap.sh index 3f1f505e8937f3..9c96b3e3b10a99 100755 --- a/t/t0011-hashmap.sh +++ b/t/t0011-hashmap.sh @@ -9,15 +9,6 @@ test_hashmap() { test_cmp expect actual } -test_expect_success 'hash functions' ' - -test_hashmap "hash key1" "2215982743 2215982743 116372151 116372151" && -test_hashmap "hash key2" "2215982740 2215982740 116372148 116372148" && -test_hashmap "hash fooBarFrotz" "1383912807 1383912807 3189766727 3189766727" && -test_hashmap "hash foobarfrotz" "2862305959 2862305959 3189766727 3189766727" - -' - test_expect_success 'put' ' test_hashmap "put key1 value1