X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fshash.c;h=3269a4108c38474dd703f34580a7fd2ec749255a;hb=0ab14c8e284b7c5c68aff1ccc6795a1d4b58bd49;hp=8fd2eb18fcf83a10a244f61190c8ff908c1d6821;hpb=f2f7be8696e030dbe6f7c859c4e2bd76fd363036;p=openvswitch diff --git a/lib/shash.c b/lib/shash.c index 8fd2eb18..3269a410 100644 --- a/lib/shash.c +++ b/lib/shash.c @@ -167,12 +167,25 @@ shash_replace(struct shash *sh, const char *name, const void *data) } } +/* Deletes 'node' from 'sh' and frees the node's name. The caller is still + * responsible for freeing the node's data, if necessary. */ void shash_delete(struct shash *sh, struct shash_node *node) { + free(shash_steal(sh, node)); +} + +/* Deletes 'node' from 'sh'. Neither the node's name nor its data is freed; + * instead, ownership is transferred to the caller. Returns the node's + * name. */ +char * +shash_steal(struct shash *sh, struct shash_node *node) +{ + char *name = node->name; + hmap_remove(&sh->map, &node->node); - free(node->name); free(node); + return name; } static struct shash_node * @@ -180,7 +193,7 @@ shash_find__(const struct shash *sh, const char *name, size_t hash) { struct shash_node *node; - HMAP_FOR_EACH_WITH_HASH (node, struct shash_node, node, hash, &sh->map) { + HMAP_FOR_EACH_WITH_HASH (node, node, hash, &sh->map) { if (!strcmp(node->name, name)) { return node; } @@ -290,3 +303,57 @@ shash_random_node(struct shash *sh) { return CONTAINER_OF(hmap_random_node(&sh->map), struct shash_node, node); } + +/* String-to-string maps (smaps). */ + +/* Frees 'smap', including its keys and string values. */ +void +smap_destroy(struct shash *smap) +{ + shash_destroy_free_data(smap); +} + +/* Returns true if string-to-string maps 'a' and 'b' contain the same keys and + * values, false otherwise. */ +bool +smap_equal(const struct shash *a, const struct shash *b) +{ + struct shash_node *a_node; + + if (shash_count(a) != shash_count(b)) { + return false; + } + + SHASH_FOR_EACH (a_node, a) { + uint32_t hash = a_node->node.hash; + struct shash_node *b_node = shash_find__(b, a_node->name, hash); + if (!b_node || strcmp(a_node->data, b_node->data)) { + return false; + } + } + + return true; +} + +/* Initializes 'dst' as a clone of 'src'. */ +void +smap_clone(struct shash *dst, const struct shash *src) +{ + struct shash_node *node; + + shash_init(dst); + SHASH_FOR_EACH (node, src) { + shash_add_nocopy__(dst, xstrdup(node->name), xstrdup(node->data), + node->node.hash); + } +} + +/* Adds 'key' with string 'value' to 'smap', making a copy of each. + * + * It is the caller's responsibility to avoid duplicate names, if that is + * desirable. */ +void +smap_add(struct shash *smap, const char *key, const char *value) +{ + shash_add(smap, key, xstrdup(value)); +}