/src/openvswitch/lib/ovsdb-data.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (c) 2009, 2010, 2011, 2012, 2015, 2016, 2017 Nicira, Inc. |
2 | | * |
3 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | * you may not use this file except in compliance with the License. |
5 | | * You may obtain a copy of the License at: |
6 | | * |
7 | | * http://www.apache.org/licenses/LICENSE-2.0 |
8 | | * |
9 | | * Unless required by applicable law or agreed to in writing, software |
10 | | * distributed under the License is distributed on an "AS IS" BASIS, |
11 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | * See the License for the specific language governing permissions and |
13 | | * limitations under the License. |
14 | | */ |
15 | | |
16 | | #ifndef OVSDB_DATA_H |
17 | | #define OVSDB_DATA_H 1 |
18 | | |
19 | | #include <stdlib.h> |
20 | | #include "compiler.h" |
21 | | #include "ovsdb-types.h" |
22 | | #include "openvswitch/json.h" |
23 | | #include "openvswitch/shash.h" |
24 | | #include "util.h" |
25 | | |
26 | | #ifdef __cplusplus |
27 | | extern "C" { |
28 | | #endif |
29 | | |
30 | 0 | #define MAX_OVSDB_ATOM_RANGE_SIZE 4096 |
31 | | |
32 | | struct ds; |
33 | | struct ovsdb_symbol_table; |
34 | | struct smap; |
35 | | |
36 | | static inline struct json * |
37 | | ovsdb_atom_string_create_nocopy(char *str) |
38 | 0 | { |
39 | 0 | return json_string_create_nocopy(str); |
40 | 0 | } Unexecuted instantiation: userspace-tso.c:ovsdb_atom_string_create_nocopy Unexecuted instantiation: dpdk-stub.c:ovsdb_atom_string_create_nocopy Unexecuted instantiation: vswitch-idl.c:ovsdb_atom_string_create_nocopy Unexecuted instantiation: ovsdb-data.c:ovsdb_atom_string_create_nocopy Unexecuted instantiation: ovsdb-idl.c:ovsdb_atom_string_create_nocopy Unexecuted instantiation: ovsdb-map-op.c:ovsdb_atom_string_create_nocopy Unexecuted instantiation: ovsdb-set-op.c:ovsdb_atom_string_create_nocopy Unexecuted instantiation: ovsdb-types.c:ovsdb_atom_string_create_nocopy Unexecuted instantiation: ovsdb-cs.c:ovsdb_atom_string_create_nocopy |
41 | | |
42 | | static inline struct json * |
43 | | ovsdb_atom_string_create(const char *str) |
44 | 0 | { |
45 | 0 | return json_string_create(str); |
46 | 0 | } Unexecuted instantiation: userspace-tso.c:ovsdb_atom_string_create Unexecuted instantiation: dpdk-stub.c:ovsdb_atom_string_create Unexecuted instantiation: vswitch-idl.c:ovsdb_atom_string_create Unexecuted instantiation: ovsdb-data.c:ovsdb_atom_string_create Unexecuted instantiation: ovsdb-idl.c:ovsdb_atom_string_create Unexecuted instantiation: ovsdb-map-op.c:ovsdb_atom_string_create Unexecuted instantiation: ovsdb-set-op.c:ovsdb_atom_string_create Unexecuted instantiation: ovsdb-types.c:ovsdb_atom_string_create Unexecuted instantiation: ovsdb-cs.c:ovsdb_atom_string_create |
47 | | |
48 | | /* One value of an atomic type (given by enum ovs_atomic_type). */ |
49 | | union ovsdb_atom { |
50 | | int64_t integer; |
51 | | double real; |
52 | | bool boolean; |
53 | | struct json *s; |
54 | | struct uuid uuid; |
55 | | }; |
56 | | |
57 | | void ovsdb_atom_init_default(union ovsdb_atom *, enum ovsdb_atomic_type); |
58 | | const union ovsdb_atom *ovsdb_atom_default(enum ovsdb_atomic_type); |
59 | | bool ovsdb_atom_is_default(const union ovsdb_atom *, enum ovsdb_atomic_type); |
60 | | void ovsdb_atom_clone(union ovsdb_atom *, const union ovsdb_atom *, |
61 | | enum ovsdb_atomic_type); |
62 | | void ovsdb_atom_swap(union ovsdb_atom *, union ovsdb_atom *); |
63 | | |
64 | | /* Returns false if ovsdb_atom_destroy() is a no-op when it is applied to an |
65 | | * initialized atom of the given 'type', true if ovsdb_atom_destroy() actually |
66 | | * does something. |
67 | | * |
68 | | * This can be used to avoid calling ovsdb_atom_destroy() for each element in |
69 | | * an array of homogeneous atoms. (It's not worthwhile for a single atom.) */ |
70 | | static inline bool |
71 | | ovsdb_atom_needs_destruction(enum ovsdb_atomic_type type) |
72 | 0 | { |
73 | 0 | return type == OVSDB_TYPE_STRING; |
74 | 0 | } Unexecuted instantiation: userspace-tso.c:ovsdb_atom_needs_destruction Unexecuted instantiation: dpdk-stub.c:ovsdb_atom_needs_destruction Unexecuted instantiation: vswitch-idl.c:ovsdb_atom_needs_destruction Unexecuted instantiation: ovsdb-data.c:ovsdb_atom_needs_destruction Unexecuted instantiation: ovsdb-idl.c:ovsdb_atom_needs_destruction Unexecuted instantiation: ovsdb-map-op.c:ovsdb_atom_needs_destruction Unexecuted instantiation: ovsdb-set-op.c:ovsdb_atom_needs_destruction Unexecuted instantiation: ovsdb-types.c:ovsdb_atom_needs_destruction Unexecuted instantiation: ovsdb-cs.c:ovsdb_atom_needs_destruction |
75 | | |
76 | | /* Frees the contents of 'atom', which must have the specified 'type'. |
77 | | * |
78 | | * This does not actually call free(atom). If necessary, the caller must be |
79 | | * responsible for that. */ |
80 | | static inline void |
81 | | ovsdb_atom_destroy(union ovsdb_atom *atom, enum ovsdb_atomic_type type) |
82 | 0 | { |
83 | 0 | if (type == OVSDB_TYPE_STRING) { |
84 | 0 | json_destroy(atom->s); |
85 | 0 | } |
86 | 0 | } Unexecuted instantiation: userspace-tso.c:ovsdb_atom_destroy Unexecuted instantiation: dpdk-stub.c:ovsdb_atom_destroy Unexecuted instantiation: vswitch-idl.c:ovsdb_atom_destroy Unexecuted instantiation: ovsdb-data.c:ovsdb_atom_destroy Unexecuted instantiation: ovsdb-idl.c:ovsdb_atom_destroy Unexecuted instantiation: ovsdb-map-op.c:ovsdb_atom_destroy Unexecuted instantiation: ovsdb-set-op.c:ovsdb_atom_destroy Unexecuted instantiation: ovsdb-types.c:ovsdb_atom_destroy Unexecuted instantiation: ovsdb-cs.c:ovsdb_atom_destroy |
87 | | |
88 | | uint32_t ovsdb_atom_hash(const union ovsdb_atom *, enum ovsdb_atomic_type, |
89 | | uint32_t basis); |
90 | | |
91 | | int ovsdb_atom_compare_3way(const union ovsdb_atom *, |
92 | | const union ovsdb_atom *, |
93 | | enum ovsdb_atomic_type); |
94 | | |
95 | | /* Returns true if 'a' and 'b', which are both of type 'type', has the same |
96 | | * contents, false if their contents differ. */ |
97 | | static inline bool ovsdb_atom_equals(const union ovsdb_atom *a, |
98 | | const union ovsdb_atom *b, |
99 | | enum ovsdb_atomic_type type) |
100 | 0 | { |
101 | 0 | return !ovsdb_atom_compare_3way(a, b, type); |
102 | 0 | } Unexecuted instantiation: userspace-tso.c:ovsdb_atom_equals Unexecuted instantiation: dpdk-stub.c:ovsdb_atom_equals Unexecuted instantiation: vswitch-idl.c:ovsdb_atom_equals Unexecuted instantiation: ovsdb-data.c:ovsdb_atom_equals Unexecuted instantiation: ovsdb-idl.c:ovsdb_atom_equals Unexecuted instantiation: ovsdb-map-op.c:ovsdb_atom_equals Unexecuted instantiation: ovsdb-set-op.c:ovsdb_atom_equals Unexecuted instantiation: ovsdb-types.c:ovsdb_atom_equals Unexecuted instantiation: ovsdb-cs.c:ovsdb_atom_equals |
103 | | |
104 | | struct ovsdb_error *ovsdb_atom_from_json(union ovsdb_atom *, |
105 | | const struct ovsdb_base_type *, |
106 | | const struct json *, |
107 | | struct ovsdb_symbol_table *) |
108 | | OVS_WARN_UNUSED_RESULT; |
109 | | struct json *ovsdb_atom_to_json(const union ovsdb_atom *, |
110 | | enum ovsdb_atomic_type); |
111 | | |
112 | | char *ovsdb_atom_from_string(union ovsdb_atom *, union ovsdb_atom **, |
113 | | const struct ovsdb_base_type *, const char *, |
114 | | struct ovsdb_symbol_table *) |
115 | | OVS_WARN_UNUSED_RESULT; |
116 | | void ovsdb_atom_to_string(const union ovsdb_atom *, enum ovsdb_atomic_type, |
117 | | struct ds *); |
118 | | void ovsdb_atom_to_bare(const union ovsdb_atom *, enum ovsdb_atomic_type, |
119 | | struct ds *); |
120 | | |
121 | | struct ovsdb_error *ovsdb_atom_check_constraints( |
122 | | const union ovsdb_atom *, const struct ovsdb_base_type *) |
123 | | OVS_WARN_UNUSED_RESULT; |
124 | | |
125 | | /* An instance of an OVSDB type (given by struct ovsdb_type). |
126 | | * |
127 | | * - The 'keys' must be unique and in sorted order. Most functions that modify |
128 | | * an ovsdb_datum maintain these invariants. Functions that don't maintain |
129 | | * the invariants have names that end in "_unsafe". Use ovsdb_datum_sort() |
130 | | * to check and restore these invariants. |
131 | | * |
132 | | * - 'n' is constrained by the ovsdb_type's 'n_min' and 'n_max'. |
133 | | * |
134 | | * If 'n' is nonzero, then 'keys' points to an array of 'n' atoms of the type |
135 | | * specified by the ovsdb_type's 'key_type'. (Otherwise, 'keys' should be |
136 | | * null.) |
137 | | * |
138 | | * If 'n' is nonzero and the ovsdb_type's 'value_type' is not |
139 | | * OVSDB_TYPE_VOID, then 'values' points to an array of 'n' atoms of the type |
140 | | * specified by the 'value_type'. (Otherwise, 'values' should be null.) |
141 | | * |
142 | | * Thus, for 'n' > 0, 'keys' will always be nonnull and 'values' will be |
143 | | * nonnull only for "map" types. |
144 | | */ |
145 | | struct ovsdb_datum { |
146 | | unsigned int n; /* Number of 'keys' and 'values'. */ |
147 | | union ovsdb_atom *keys; /* Each of the ovsdb_type's 'key_type'. */ |
148 | | union ovsdb_atom *values; /* Each of the ovsdb_type's 'value_type'. */ |
149 | | unsigned int *refcnt; /* Number of copies with the same |
150 | | * 'keys' and 'values'. */ |
151 | | }; |
152 | | #define OVSDB_DATUM_INITIALIZER { 0, NULL, NULL } |
153 | | |
154 | | /* Basics. */ |
155 | | void ovsdb_datum_init_empty(struct ovsdb_datum *); |
156 | | void ovsdb_datum_init_default(struct ovsdb_datum *, const struct ovsdb_type *); |
157 | | bool ovsdb_datum_is_default(const struct ovsdb_datum *, |
158 | | const struct ovsdb_type *); |
159 | | const struct ovsdb_datum *ovsdb_datum_default(const struct ovsdb_type *); |
160 | | void ovsdb_datum_clone(struct ovsdb_datum *, const struct ovsdb_datum *); |
161 | | void ovsdb_datum_destroy(struct ovsdb_datum *, const struct ovsdb_type *); |
162 | | void ovsdb_datum_unshare(struct ovsdb_datum *, const struct ovsdb_type *); |
163 | | void ovsdb_datum_swap(struct ovsdb_datum *, struct ovsdb_datum *); |
164 | | |
165 | | /* Checking and maintaining invariants. */ |
166 | | struct ovsdb_error *ovsdb_datum_sort(struct ovsdb_datum *, |
167 | | const struct ovsdb_type *type) |
168 | | OVS_WARN_UNUSED_RESULT; |
169 | | |
170 | | void ovsdb_datum_sort_assert(struct ovsdb_datum *, |
171 | | const struct ovsdb_type *type); |
172 | | |
173 | | size_t ovsdb_datum_sort_unique(struct ovsdb_datum *, |
174 | | const struct ovsdb_type *type); |
175 | | |
176 | | struct ovsdb_error *ovsdb_datum_check_constraints( |
177 | | const struct ovsdb_datum *, const struct ovsdb_type *) |
178 | | OVS_WARN_UNUSED_RESULT; |
179 | | |
180 | | /* Type conversion. */ |
181 | | struct ovsdb_error *ovsdb_datum_from_json(struct ovsdb_datum *, |
182 | | const struct ovsdb_type *, |
183 | | const struct json *, |
184 | | struct ovsdb_symbol_table *) |
185 | | OVS_WARN_UNUSED_RESULT; |
186 | | struct ovsdb_error *ovsdb_transient_datum_from_json( |
187 | | struct ovsdb_datum *, |
188 | | const struct ovsdb_type *, |
189 | | const struct json *) |
190 | | OVS_WARN_UNUSED_RESULT; |
191 | | struct ovsdb_error * |
192 | | ovsdb_unconstrained_datum_from_json(struct ovsdb_datum *, |
193 | | const struct ovsdb_type *, |
194 | | const struct json *) |
195 | | OVS_WARN_UNUSED_RESULT; |
196 | | struct json *ovsdb_datum_to_json(const struct ovsdb_datum *, |
197 | | const struct ovsdb_type *); |
198 | | struct json *ovsdb_datum_to_json_deep(const struct ovsdb_datum *, |
199 | | const struct ovsdb_type *); |
200 | | |
201 | | char *ovsdb_datum_from_string(struct ovsdb_datum *, |
202 | | const struct ovsdb_type *, const char *, |
203 | | struct ovsdb_symbol_table *) |
204 | | OVS_WARN_UNUSED_RESULT; |
205 | | void ovsdb_datum_to_string(const struct ovsdb_datum *, |
206 | | const struct ovsdb_type *, struct ds *); |
207 | | void ovsdb_datum_to_bare(const struct ovsdb_datum *, |
208 | | const struct ovsdb_type *, struct ds *); |
209 | | |
210 | | void ovsdb_datum_from_smap(struct ovsdb_datum *, const struct smap *); |
211 | | |
212 | | struct ovsdb_error *ovsdb_datum_convert(struct ovsdb_datum *dst, |
213 | | const struct ovsdb_type *dst_type, |
214 | | const struct ovsdb_datum *src, |
215 | | const struct ovsdb_type *src_type) |
216 | | OVS_WARN_UNUSED_RESULT; |
217 | | |
218 | | /* Comparison. */ |
219 | | uint32_t ovsdb_datum_hash(const struct ovsdb_datum *, |
220 | | const struct ovsdb_type *, uint32_t basis); |
221 | | int ovsdb_datum_compare_3way(const struct ovsdb_datum *, |
222 | | const struct ovsdb_datum *, |
223 | | const struct ovsdb_type *); |
224 | | bool ovsdb_datum_equals(const struct ovsdb_datum *, |
225 | | const struct ovsdb_datum *, |
226 | | const struct ovsdb_type *); |
227 | | |
228 | | /* Search. */ |
229 | | bool ovsdb_datum_find_key(const struct ovsdb_datum *, |
230 | | const union ovsdb_atom *key, |
231 | | enum ovsdb_atomic_type key_type, |
232 | | unsigned int *pos); |
233 | | unsigned int ovsdb_datum_find_key_value(const struct ovsdb_datum *, |
234 | | const union ovsdb_atom *key, |
235 | | enum ovsdb_atomic_type key_type, |
236 | | const union ovsdb_atom *value, |
237 | | enum ovsdb_atomic_type value_type); |
238 | | |
239 | | /* Set operations. */ |
240 | | bool ovsdb_datum_includes_all(const struct ovsdb_datum *, |
241 | | const struct ovsdb_datum *, |
242 | | const struct ovsdb_type *); |
243 | | bool ovsdb_datum_excludes_all(const struct ovsdb_datum *, |
244 | | const struct ovsdb_datum *, |
245 | | const struct ovsdb_type *); |
246 | | void ovsdb_datum_union(struct ovsdb_datum *, |
247 | | const struct ovsdb_datum *, |
248 | | const struct ovsdb_type *); |
249 | | void ovsdb_datum_subtract(struct ovsdb_datum *a, |
250 | | const struct ovsdb_type *a_type, |
251 | | const struct ovsdb_datum *b, |
252 | | const struct ovsdb_type *b_type); |
253 | | |
254 | | /* Generate and apply diffs */ |
255 | | void ovsdb_datum_added_removed(struct ovsdb_datum *added, |
256 | | struct ovsdb_datum *removed, |
257 | | const struct ovsdb_datum *old, |
258 | | const struct ovsdb_datum *new, |
259 | | const struct ovsdb_datum *diff, |
260 | | const struct ovsdb_type *type); |
261 | | |
262 | | void ovsdb_datum_diff(struct ovsdb_datum *diff, |
263 | | const struct ovsdb_datum *old_datum, |
264 | | const struct ovsdb_datum *new_datum, |
265 | | const struct ovsdb_type *type); |
266 | | |
267 | | struct ovsdb_error *ovsdb_datum_apply_diff(struct ovsdb_datum *new_datum, |
268 | | const struct ovsdb_datum *old_datum, |
269 | | const struct ovsdb_datum *diff, |
270 | | const struct ovsdb_type *type) |
271 | | OVS_WARN_UNUSED_RESULT; |
272 | | |
273 | | struct ovsdb_error * ovsdb_datum_apply_diff_in_place( |
274 | | struct ovsdb_datum *a, |
275 | | const struct ovsdb_datum *diff, |
276 | | const struct ovsdb_type *type) |
277 | | OVS_WARN_UNUSED_RESULT; |
278 | | |
279 | | /* Raw operations that may not maintain the invariants. */ |
280 | | void ovsdb_datum_remove_unsafe(struct ovsdb_datum *, size_t idx, |
281 | | const struct ovsdb_type *); |
282 | | void ovsdb_datum_add_unsafe(struct ovsdb_datum *, |
283 | | const union ovsdb_atom *key, |
284 | | const union ovsdb_atom *value, |
285 | | const struct ovsdb_type *, |
286 | | const union ovsdb_atom *range_end_atom); |
287 | | void ovsdb_datum_add_from_index_unsafe(struct ovsdb_datum *dst, |
288 | | const struct ovsdb_datum *src, |
289 | | size_t idx, |
290 | | const struct ovsdb_type *type); |
291 | | |
292 | | /* Transactions with named-uuid row names. */ |
293 | | struct json *ovsdb_datum_to_json_with_row_names(const struct ovsdb_datum *, |
294 | | const struct ovsdb_type *); |
295 | | char *ovsdb_data_row_name(const struct uuid *); |
296 | | |
297 | | /* Type checking. */ |
298 | | static inline bool |
299 | | ovsdb_datum_conforms_to_type(const struct ovsdb_datum *datum, |
300 | | const struct ovsdb_type *type) |
301 | 0 | { |
302 | 0 | return datum->n >= type->n_min && datum->n <= type->n_max; |
303 | 0 | } Unexecuted instantiation: userspace-tso.c:ovsdb_datum_conforms_to_type Unexecuted instantiation: dpdk-stub.c:ovsdb_datum_conforms_to_type Unexecuted instantiation: vswitch-idl.c:ovsdb_datum_conforms_to_type Unexecuted instantiation: ovsdb-data.c:ovsdb_datum_conforms_to_type Unexecuted instantiation: ovsdb-idl.c:ovsdb_datum_conforms_to_type Unexecuted instantiation: ovsdb-map-op.c:ovsdb_datum_conforms_to_type Unexecuted instantiation: ovsdb-set-op.c:ovsdb_datum_conforms_to_type Unexecuted instantiation: ovsdb-types.c:ovsdb_datum_conforms_to_type Unexecuted instantiation: ovsdb-cs.c:ovsdb_datum_conforms_to_type |
304 | | |
305 | | /* A table mapping from names to data items. Currently the data items are |
306 | | * always UUIDs; perhaps this will be expanded in the future. */ |
307 | | |
308 | | struct ovsdb_symbol_table { |
309 | | struct shash sh; /* Maps from name to struct ovsdb_symbol *. */ |
310 | | }; |
311 | | |
312 | | struct ovsdb_symbol { |
313 | | struct uuid uuid; /* The UUID that the symbol represents. */ |
314 | | bool created; /* Already used to create row? */ |
315 | | bool strong_ref; /* Parsed a strong reference to this row? */ |
316 | | bool weak_ref; /* Parsed a weak reference to this row? */ |
317 | | }; |
318 | | |
319 | | struct ovsdb_symbol_table *ovsdb_symbol_table_create(void); |
320 | | void ovsdb_symbol_table_destroy(struct ovsdb_symbol_table *); |
321 | | struct ovsdb_symbol *ovsdb_symbol_table_get(const struct ovsdb_symbol_table *, |
322 | | const char *name); |
323 | | struct ovsdb_symbol *ovsdb_symbol_table_put(struct ovsdb_symbol_table *, |
324 | | const char *name, |
325 | | const struct uuid *, bool used); |
326 | | struct ovsdb_symbol *ovsdb_symbol_table_insert(struct ovsdb_symbol_table *, |
327 | | const char *name); |
328 | | |
329 | | /* Tokenization |
330 | | * |
331 | | * Used by ovsdb_atom_from_string() and ovsdb_datum_from_string(). */ |
332 | | |
333 | | char *ovsdb_token_parse(const char **, char **outp) OVS_WARN_UNUSED_RESULT; |
334 | | bool ovsdb_token_is_delim(unsigned char); |
335 | | |
336 | | struct ovsdb_error *ovsdb_atom_range_check_size(int64_t range_start, |
337 | | int64_t range_end); |
338 | | |
339 | | #ifdef __cplusplus |
340 | | } |
341 | | #endif |
342 | | |
343 | | #endif /* ovsdb-data.h */ |