Coverage Report

Created: 2025-07-11 06:11

/src/openvswitch/lib/hmapx.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2011, 2012 Nicira, Inc.
3
 *
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:
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
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.
15
 */
16
17
#include <config.h>
18
19
#include "hmapx.h"
20
21
#include "hash.h"
22
23
static struct hmapx_node *
24
hmapx_find__(const struct hmapx *map, const void *data, size_t hash)
25
0
{
26
0
    struct hmapx_node *node;
27
28
0
    HMAP_FOR_EACH_IN_BUCKET (node, hmap_node, hash, &map->map) {
29
0
        if (node->data == data) {
30
0
            return node;
31
0
        }
32
0
    }
33
0
    return NULL;
34
0
}
35
36
static struct hmapx_node *
37
hmapx_add__(struct hmapx *map, void *data, size_t hash)
38
0
{
39
0
    struct hmapx_node *node = xmalloc(sizeof *node);
40
0
    node->data = data;
41
0
    hmap_insert(&map->map, &node->hmap_node, hash);
42
0
    return node;
43
0
}
44
45
/* Initializes 'map' as an empty set of pointers. */
46
void
47
hmapx_init(struct hmapx *map)
48
0
{
49
0
    hmap_init(&map->map);
50
0
}
51
52
/* Destroys 'map'. */
53
void
54
hmapx_destroy(struct hmapx *map)
55
0
{
56
0
    if (map) {
57
0
        hmapx_clear(map);
58
0
        hmap_destroy(&map->map);
59
0
    }
60
0
}
61
62
/* Initializes 'map' to contain the same pointers as 'orig'. */
63
void
64
hmapx_clone(struct hmapx *map, const struct hmapx *orig)
65
0
{
66
0
    struct hmapx_node *node;
67
68
0
    hmapx_init(map);
69
0
    hmap_reserve(&map->map, hmapx_count(orig));
70
71
0
    HMAP_FOR_EACH (node, hmap_node, &orig->map) {
72
0
        hmapx_add__(map, node->data, node->hmap_node.hash);
73
0
    }
74
0
}
75
76
/* Exchanges the contents of 'a' and 'b'. */
77
void
78
hmapx_swap(struct hmapx *a, struct hmapx *b)
79
0
{
80
0
    hmap_swap(&a->map, &b->map);
81
0
}
82
83
/* Adjusts 'map' so that it is still valid after it has been moved around in
84
 * memory (e.g. due to realloc()). */
85
void
86
hmapx_moved(struct hmapx *map)
87
0
{
88
0
    hmap_moved(&map->map);
89
0
}
90
91
/* Returns true if 'map' contains no nodes, false if it contains at least one
92
 * node. */
93
bool
94
hmapx_is_empty(const struct hmapx *map)
95
0
{
96
0
    return hmap_is_empty(&map->map);
97
0
}
98
99
/* Returns the number of nodes in 'map'. */
100
size_t
101
hmapx_count(const struct hmapx *map)
102
0
{
103
0
    return hmap_count(&map->map);
104
0
}
105
106
/* Adds 'data' to 'map'.  If 'data' is new, returns the new hmapx_node;
107
 * otherwise (if a 'data' already existed in 'map'), returns NULL. */
108
struct hmapx_node *
109
hmapx_add(struct hmapx *map, void *data)
110
0
{
111
0
    uint32_t hash = hash_pointer(data, 0);
112
0
    return (hmapx_find__(map, data, hash)
113
0
            ? NULL
114
0
            : hmapx_add__(map, data, hash));
115
0
}
116
117
/* Adds 'data' to 'map'.  Assert-fails if 'data' was already in 'map'. */
118
void
119
hmapx_add_assert(struct hmapx *map, void *data)
120
0
{
121
0
    ovs_assert(hmapx_add(map, data));
122
0
}
123
124
/* Removes all of the nodes from 'map'. */
125
void
126
hmapx_clear(struct hmapx *map)
127
0
{
128
0
    struct hmapx_node *node;
129
130
0
    HMAPX_FOR_EACH_SAFE (node, map) {
131
0
        hmapx_delete(map, node);
132
0
    }
133
0
}
134
135
/* Deletes 'node' from 'map' and frees 'node'. */
136
void
137
hmapx_delete(struct hmapx *map, struct hmapx_node *node)
138
0
{
139
0
    hmap_remove(&map->map, &node->hmap_node);
140
0
    free(node);
141
0
}
142
143
/* Searches for 'data' in 'map'.  If found, deletes it and returns true.  If
144
 * not found, returns false without modifying 'map'. */
145
bool
146
hmapx_find_and_delete(struct hmapx *map, const void *data)
147
0
{
148
0
    struct hmapx_node *node = hmapx_find(map, data);
149
0
    if (node) {
150
0
        hmapx_delete(map, node);
151
0
    }
152
0
    return node != NULL;
153
0
}
154
155
/* Searches for 'data' in 'map' and deletes it.  Assert-fails if 'data' is not
156
 * in 'map'. */
157
void
158
hmapx_find_and_delete_assert(struct hmapx *map, const void *data)
159
0
{
160
0
    ovs_assert(hmapx_find_and_delete(map, data));
161
0
}
162
163
/* Searches for 'data' in 'map'.  Returns its node, if found, otherwise a null
164
 * pointer. */
165
struct hmapx_node *
166
hmapx_find(const struct hmapx *map, const void *data)
167
0
{
168
0
    return hmapx_find__(map, data, hash_pointer(data, 0));
169
0
}
170
171
/* Returns true if 'map' contains 'data', false otherwise. */
172
bool
173
hmapx_contains(const struct hmapx *map, const void *data)
174
0
{
175
0
    return hmapx_find(map, data) != NULL;
176
0
}
177
178
/* Returns true if 'a' and 'b' contain the same pointers, false otherwise. */
179
bool
180
hmapx_equals(const struct hmapx *a, const struct hmapx *b)
181
0
{
182
0
    struct hmapx_node *node;
183
184
0
    if (hmapx_count(a) != hmapx_count(b)) {
185
0
        return false;
186
0
    }
187
188
0
    HMAP_FOR_EACH (node, hmap_node, &a->map) {
189
0
        if (!hmapx_find__(b, node->data, node->hmap_node.hash)) {
190
0
            return false;
191
0
        }
192
0
    }
193
194
0
    return true;
195
0
}