]>
git.proxmox.com Git - mirror_ovs.git/blob - lib/shash.c
2 * Copyright (c) 2009, 2010 Nicira Networks.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 hash_name(const char *name
)
25 return hash_string(name
, 0);
29 shash_init(struct shash
*sh
)
35 shash_destroy(struct shash
*sh
)
39 hmap_destroy(&sh
->map
);
44 shash_swap(struct shash
*a
, struct shash
*b
)
46 hmap_swap(&a
->map
, &b
->map
);
50 shash_moved(struct shash
*sh
)
56 shash_clear(struct shash
*sh
)
58 struct shash_node
*node
, *next
;
60 SHASH_FOR_EACH_SAFE (node
, next
, sh
) {
61 hmap_remove(&sh
->map
, &node
->node
);
68 shash_is_empty(const struct shash
*shash
)
70 return hmap_is_empty(&shash
->map
);
74 shash_count(const struct shash
*shash
)
76 return hmap_count(&shash
->map
);
79 /* It is the caller's responsibility to avoid duplicate names, if that is
82 shash_add(struct shash
*sh
, const char *name
, const void *data
)
84 struct shash_node
*node
= xmalloc(sizeof *node
);
85 node
->name
= xstrdup(name
);
86 node
->data
= (void *) data
;
87 hmap_insert(&sh
->map
, &node
->node
, hash_name(name
));
92 shash_add_once(struct shash
*sh
, const char *name
, const void *data
)
94 if (!shash_find(sh
, name
)) {
95 shash_add(sh
, name
, data
);
103 shash_delete(struct shash
*sh
, struct shash_node
*node
)
105 hmap_remove(&sh
->map
, &node
->node
);
110 /* If there are duplicates, returns a random element. */
112 shash_find(const struct shash
*sh
, const char *name
)
114 struct shash_node
*node
;
116 HMAP_FOR_EACH_WITH_HASH (node
, struct shash_node
, node
,
117 hash_name(name
), &sh
->map
) {
118 if (!strcmp(node
->name
, name
)) {
126 shash_find_data(const struct shash
*sh
, const char *name
)
128 struct shash_node
*node
= shash_find(sh
, name
);
129 return node
? node
->data
: NULL
;
133 shash_find_and_delete(struct shash
*sh
, const char *name
)
135 struct shash_node
*node
= shash_find(sh
, name
);
137 void *data
= node
->data
;
138 shash_delete(sh
, node
);
146 shash_first(const struct shash
*shash
)
148 struct hmap_node
*node
= hmap_first(&shash
->map
);
149 return node
? CONTAINER_OF(node
, struct shash_node
, node
) : NULL
;
153 compare_nodes_by_name(const void *a_
, const void *b_
)
155 const struct shash_node
*const *a
= a_
;
156 const struct shash_node
*const *b
= b_
;
157 return strcmp((*a
)->name
, (*b
)->name
);
160 const struct shash_node
**
161 shash_sort(const struct shash
*sh
)
163 if (shash_is_empty(sh
)) {
166 const struct shash_node
**nodes
;
167 struct shash_node
*node
;
171 nodes
= xmalloc(n
* sizeof *nodes
);
173 SHASH_FOR_EACH (node
, sh
) {
178 qsort(nodes
, n
, sizeof *nodes
, compare_nodes_by_name
);
184 /* Returns true if 'a' and 'b' contain the same keys (regardless of their
185 * values), false otherwise. */
187 shash_equal_keys(const struct shash
*a
, const struct shash
*b
)
189 struct shash_node
*node
;
191 if (hmap_count(&a
->map
) != hmap_count(&b
->map
)) {
194 SHASH_FOR_EACH (node
, a
) {
195 if (!shash_find(b
, node
->name
)) {