mirror of
https://github.com/openvswitch/ovs
synced 2025-10-15 14:17:18 +00:00
ovsdb: New functions ovsdb_atom_default(), ovsdb_datum_default().
Having access to const copies of default atoms and data will allow OVSDB code to avoid memory allocations and reduce copying in upcoming commits.
This commit is contained in:
@@ -84,6 +84,31 @@ ovsdb_atom_init_default(union ovsdb_atom *atom, enum ovsdb_atomic_type type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns a read-only atom of the given 'type' that has the default value for
|
||||||
|
* 'type'. The caller must not modify or free the returned atom.
|
||||||
|
*
|
||||||
|
* See ovsdb_atom_init_default() for an explanation of the default value of an
|
||||||
|
* atom. */
|
||||||
|
const union ovsdb_atom *
|
||||||
|
ovsdb_atom_default(enum ovsdb_atomic_type type)
|
||||||
|
{
|
||||||
|
static union ovsdb_atom default_atoms[OVSDB_N_TYPES];
|
||||||
|
static bool inited;
|
||||||
|
|
||||||
|
if (!inited) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < OVSDB_N_TYPES; i++) {
|
||||||
|
if (i != OVSDB_TYPE_VOID) {
|
||||||
|
ovsdb_atom_init_default(&default_atoms[i], i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(ovsdb_atomic_type_is_valid(type));
|
||||||
|
return &default_atoms[type];
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns true if 'atom', which must have the given 'type', has the default
|
/* Returns true if 'atom', which must have the given 'type', has the default
|
||||||
* value for that type.
|
* value for that type.
|
||||||
@@ -349,8 +374,11 @@ ovsdb_atom_from_json__(union ovsdb_atom *atom, enum ovsdb_atomic_type type,
|
|||||||
* returns an error and the contents of 'atom' are indeterminate. The caller
|
* returns an error and the contents of 'atom' are indeterminate. The caller
|
||||||
* is responsible for freeing the error or the atom that is returned.
|
* is responsible for freeing the error or the atom that is returned.
|
||||||
*
|
*
|
||||||
|
* Violations of constraints expressed by 'base' are treated as errors.
|
||||||
|
*
|
||||||
* If 'symtab' is nonnull, then named UUIDs in 'symtab' are accepted. Refer to
|
* If 'symtab' is nonnull, then named UUIDs in 'symtab' are accepted. Refer to
|
||||||
* ovsdb/SPECS information about this and other syntactical details. */
|
* ovsdb/SPECS for information about this, and for the syntax that this
|
||||||
|
* function accepts. */
|
||||||
struct ovsdb_error *
|
struct ovsdb_error *
|
||||||
ovsdb_atom_from_json(union ovsdb_atom *atom,
|
ovsdb_atom_from_json(union ovsdb_atom *atom,
|
||||||
const struct ovsdb_base_type *base,
|
const struct ovsdb_base_type *base,
|
||||||
@@ -372,7 +400,10 @@ ovsdb_atom_from_json(union ovsdb_atom *atom,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Converts 'atom', of the specified 'type', to JSON format, and returns the
|
/* Converts 'atom', of the specified 'type', to JSON format, and returns the
|
||||||
* JSON. The caller is responsible for freeing the returned JSON. */
|
* JSON. The caller is responsible for freeing the returned JSON.
|
||||||
|
*
|
||||||
|
* Refer to ovsdb/SPECS for the format of the JSON that this function
|
||||||
|
* produces. */
|
||||||
struct json *
|
struct json *
|
||||||
ovsdb_atom_to_json(const union ovsdb_atom *atom, enum ovsdb_atomic_type type)
|
ovsdb_atom_to_json(const union ovsdb_atom *atom, enum ovsdb_atomic_type type)
|
||||||
{
|
{
|
||||||
@@ -776,6 +807,39 @@ ovsdb_datum_init_default(struct ovsdb_datum *datum,
|
|||||||
datum->values = alloc_default_atoms(type->value.type, datum->n);
|
datum->values = alloc_default_atoms(type->value.type, datum->n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns a read-only datum of the given 'type' that has the default value for
|
||||||
|
* 'type'. The caller must not modify or free the returned datum.
|
||||||
|
*
|
||||||
|
* See ovsdb_datum_init_default() for an explanation of the default value of a
|
||||||
|
* datum. */
|
||||||
|
const struct ovsdb_datum *
|
||||||
|
ovsdb_datum_default(const struct ovsdb_type *type)
|
||||||
|
{
|
||||||
|
if (type->n_min == 0) {
|
||||||
|
static const struct ovsdb_datum empty;
|
||||||
|
return ∅
|
||||||
|
} else if (type->n_min == 1) {
|
||||||
|
static struct ovsdb_datum default_data[OVSDB_N_TYPES][OVSDB_N_TYPES];
|
||||||
|
struct ovsdb_datum *d;
|
||||||
|
int kt = type->key.type;
|
||||||
|
int vt = type->value.type;
|
||||||
|
|
||||||
|
assert(ovsdb_type_is_valid(type));
|
||||||
|
|
||||||
|
d = &default_data[kt][vt];
|
||||||
|
if (!d->n) {
|
||||||
|
d->n = 1;
|
||||||
|
d->keys = (union ovsdb_atom *) ovsdb_atom_default(kt);
|
||||||
|
if (vt != OVSDB_TYPE_VOID) {
|
||||||
|
d->values = (union ovsdb_atom *) ovsdb_atom_default(vt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
} else {
|
||||||
|
NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns true if 'datum', which must have the given 'type', has the default
|
/* Returns true if 'datum', which must have the given 'type', has the default
|
||||||
* value for that type.
|
* value for that type.
|
||||||
*
|
*
|
||||||
@@ -979,6 +1043,16 @@ ovsdb_datum_check_constraints(const struct ovsdb_datum *datum,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Parses 'json' as a datum of the type described by 'type'. If successful,
|
||||||
|
* returns NULL and initializes 'datum' with the parsed datum. On failure,
|
||||||
|
* returns an error and the contents of 'datum' are indeterminate. The caller
|
||||||
|
* is responsible for freeing the error or the datum that is returned.
|
||||||
|
*
|
||||||
|
* Violations of constraints expressed by 'type' are treated as errors.
|
||||||
|
*
|
||||||
|
* If 'symtab' is nonnull, then named UUIDs in 'symtab' are accepted. Refer to
|
||||||
|
* ovsdb/SPECS for information about this, and for the syntax that this
|
||||||
|
* function accepts. */
|
||||||
struct ovsdb_error *
|
struct ovsdb_error *
|
||||||
ovsdb_datum_from_json(struct ovsdb_datum *datum,
|
ovsdb_datum_from_json(struct ovsdb_datum *datum,
|
||||||
const struct ovsdb_type *type,
|
const struct ovsdb_type *type,
|
||||||
@@ -1069,12 +1143,18 @@ ovsdb_datum_from_json(struct ovsdb_datum *datum,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Converts 'datum', of the specified 'type', to JSON format, and returns the
|
||||||
|
* JSON. The caller is responsible for freeing the returned JSON.
|
||||||
|
*
|
||||||
|
* 'type' constraints on datum->n are ignored.
|
||||||
|
*
|
||||||
|
* Refer to ovsdb/SPECS for the format of the JSON that this function
|
||||||
|
* produces. */
|
||||||
struct json *
|
struct json *
|
||||||
ovsdb_datum_to_json(const struct ovsdb_datum *datum,
|
ovsdb_datum_to_json(const struct ovsdb_datum *datum,
|
||||||
const struct ovsdb_type *type)
|
const struct ovsdb_type *type)
|
||||||
{
|
{
|
||||||
/* These tests somewhat tolerate a 'datum' that does not exactly match
|
|
||||||
* 'type', in particular a datum with 'n' not in the allowed range. */
|
|
||||||
if (datum->n == 1 && !ovsdb_type_is_map(type)) {
|
if (datum->n == 1 && !ovsdb_type_is_map(type)) {
|
||||||
return ovsdb_atom_to_json(&datum->keys[0], type->key.type);
|
return ovsdb_atom_to_json(&datum->keys[0], type->key.type);
|
||||||
} else if (type->value.type == OVSDB_TYPE_VOID) {
|
} else if (type->value.type == OVSDB_TYPE_VOID) {
|
||||||
|
@@ -33,6 +33,7 @@ union ovsdb_atom {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void ovsdb_atom_init_default(union ovsdb_atom *, enum ovsdb_atomic_type);
|
void ovsdb_atom_init_default(union ovsdb_atom *, enum ovsdb_atomic_type);
|
||||||
|
const union ovsdb_atom *ovsdb_atom_default(enum ovsdb_atomic_type);
|
||||||
bool ovsdb_atom_is_default(const union ovsdb_atom *, enum ovsdb_atomic_type);
|
bool ovsdb_atom_is_default(const union ovsdb_atom *, enum ovsdb_atomic_type);
|
||||||
void ovsdb_atom_clone(union ovsdb_atom *, const union ovsdb_atom *,
|
void ovsdb_atom_clone(union ovsdb_atom *, const union ovsdb_atom *,
|
||||||
enum ovsdb_atomic_type);
|
enum ovsdb_atomic_type);
|
||||||
@@ -128,6 +129,7 @@ void ovsdb_datum_init_empty(struct ovsdb_datum *);
|
|||||||
void ovsdb_datum_init_default(struct ovsdb_datum *, const struct ovsdb_type *);
|
void ovsdb_datum_init_default(struct ovsdb_datum *, const struct ovsdb_type *);
|
||||||
bool ovsdb_datum_is_default(const struct ovsdb_datum *,
|
bool ovsdb_datum_is_default(const struct ovsdb_datum *,
|
||||||
const struct ovsdb_type *);
|
const struct ovsdb_type *);
|
||||||
|
const struct ovsdb_datum *ovsdb_datum_default(const struct ovsdb_type *);
|
||||||
void ovsdb_datum_clone(struct ovsdb_datum *, const struct ovsdb_datum *,
|
void ovsdb_datum_clone(struct ovsdb_datum *, const struct ovsdb_datum *,
|
||||||
const struct ovsdb_type *);
|
const struct ovsdb_type *);
|
||||||
void ovsdb_datum_destroy(struct ovsdb_datum *, const struct ovsdb_type *);
|
void ovsdb_datum_destroy(struct ovsdb_datum *, const struct ovsdb_type *);
|
||||||
|
@@ -1,3 +1,76 @@
|
|||||||
|
AT_BANNER([OVSDB -- default values])
|
||||||
|
|
||||||
|
OVSDB_CHECK_POSITIVE([default atoms],
|
||||||
|
[default-atoms],
|
||||||
|
[[integer: OK
|
||||||
|
real: OK
|
||||||
|
boolean: OK
|
||||||
|
string: OK
|
||||||
|
uuid: OK]])
|
||||||
|
|
||||||
|
OVSDB_CHECK_POSITIVE([default data],
|
||||||
|
[default-data],
|
||||||
|
[[key integer, value void, n_min 0: OK
|
||||||
|
key integer, value integer, n_min 0: OK
|
||||||
|
key integer, value real, n_min 0: OK
|
||||||
|
key integer, value boolean, n_min 0: OK
|
||||||
|
key integer, value string, n_min 0: OK
|
||||||
|
key integer, value uuid, n_min 0: OK
|
||||||
|
key real, value void, n_min 0: OK
|
||||||
|
key real, value integer, n_min 0: OK
|
||||||
|
key real, value real, n_min 0: OK
|
||||||
|
key real, value boolean, n_min 0: OK
|
||||||
|
key real, value string, n_min 0: OK
|
||||||
|
key real, value uuid, n_min 0: OK
|
||||||
|
key boolean, value void, n_min 0: OK
|
||||||
|
key boolean, value integer, n_min 0: OK
|
||||||
|
key boolean, value real, n_min 0: OK
|
||||||
|
key boolean, value boolean, n_min 0: OK
|
||||||
|
key boolean, value string, n_min 0: OK
|
||||||
|
key boolean, value uuid, n_min 0: OK
|
||||||
|
key string, value void, n_min 0: OK
|
||||||
|
key string, value integer, n_min 0: OK
|
||||||
|
key string, value real, n_min 0: OK
|
||||||
|
key string, value boolean, n_min 0: OK
|
||||||
|
key string, value string, n_min 0: OK
|
||||||
|
key string, value uuid, n_min 0: OK
|
||||||
|
key uuid, value void, n_min 0: OK
|
||||||
|
key uuid, value integer, n_min 0: OK
|
||||||
|
key uuid, value real, n_min 0: OK
|
||||||
|
key uuid, value boolean, n_min 0: OK
|
||||||
|
key uuid, value string, n_min 0: OK
|
||||||
|
key uuid, value uuid, n_min 0: OK
|
||||||
|
key integer, value void, n_min 1: OK
|
||||||
|
key integer, value integer, n_min 1: OK
|
||||||
|
key integer, value real, n_min 1: OK
|
||||||
|
key integer, value boolean, n_min 1: OK
|
||||||
|
key integer, value string, n_min 1: OK
|
||||||
|
key integer, value uuid, n_min 1: OK
|
||||||
|
key real, value void, n_min 1: OK
|
||||||
|
key real, value integer, n_min 1: OK
|
||||||
|
key real, value real, n_min 1: OK
|
||||||
|
key real, value boolean, n_min 1: OK
|
||||||
|
key real, value string, n_min 1: OK
|
||||||
|
key real, value uuid, n_min 1: OK
|
||||||
|
key boolean, value void, n_min 1: OK
|
||||||
|
key boolean, value integer, n_min 1: OK
|
||||||
|
key boolean, value real, n_min 1: OK
|
||||||
|
key boolean, value boolean, n_min 1: OK
|
||||||
|
key boolean, value string, n_min 1: OK
|
||||||
|
key boolean, value uuid, n_min 1: OK
|
||||||
|
key string, value void, n_min 1: OK
|
||||||
|
key string, value integer, n_min 1: OK
|
||||||
|
key string, value real, n_min 1: OK
|
||||||
|
key string, value boolean, n_min 1: OK
|
||||||
|
key string, value string, n_min 1: OK
|
||||||
|
key string, value uuid, n_min 1: OK
|
||||||
|
key uuid, value void, n_min 1: OK
|
||||||
|
key uuid, value integer, n_min 1: OK
|
||||||
|
key uuid, value real, n_min 1: OK
|
||||||
|
key uuid, value boolean, n_min 1: OK
|
||||||
|
key uuid, value string, n_min 1: OK
|
||||||
|
key uuid, value uuid, n_min 1: OK]])
|
||||||
|
|
||||||
AT_BANNER([OVSDB -- atoms without constraints])
|
AT_BANNER([OVSDB -- atoms without constraints])
|
||||||
|
|
||||||
OVSDB_CHECK_POSITIVE([integer atom from JSON],
|
OVSDB_CHECK_POSITIVE([integer atom from JSON],
|
||||||
|
@@ -121,6 +121,10 @@ usage(void)
|
|||||||
"usage: %s [OPTIONS] COMMAND [ARG...]\n\n"
|
"usage: %s [OPTIONS] COMMAND [ARG...]\n\n"
|
||||||
" log-io FILE FLAGS COMMAND...\n"
|
" log-io FILE FLAGS COMMAND...\n"
|
||||||
" open FILE with FLAGS, run COMMANDs\n"
|
" open FILE with FLAGS, run COMMANDs\n"
|
||||||
|
" default-atoms\n"
|
||||||
|
" test ovsdb_atom_default()\n"
|
||||||
|
" default-data\n"
|
||||||
|
" test ovsdb_datum_default()\n"
|
||||||
" parse-atomic-type TYPE\n"
|
" parse-atomic-type TYPE\n"
|
||||||
" parse TYPE as OVSDB atomic type, and re-serialize\n"
|
" parse TYPE as OVSDB atomic type, and re-serialize\n"
|
||||||
" parse-base-type TYPE\n"
|
" parse-base-type TYPE\n"
|
||||||
@@ -314,6 +318,71 @@ do_log_io(int argc, char *argv[])
|
|||||||
ovsdb_log_close(log);
|
ovsdb_log_close(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_default_atoms(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
|
||||||
|
for (type = 0; type < OVSDB_N_TYPES; type++) {
|
||||||
|
union ovsdb_atom atom;
|
||||||
|
|
||||||
|
if (type == OVSDB_TYPE_VOID) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s: ", ovsdb_atomic_type_to_string(type));
|
||||||
|
|
||||||
|
ovsdb_atom_init_default(&atom, type);
|
||||||
|
if (!ovsdb_atom_equals(&atom, ovsdb_atom_default(type), type)) {
|
||||||
|
printf("wrong\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
ovsdb_atom_destroy(&atom, type);
|
||||||
|
|
||||||
|
printf("OK\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_default_data(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
|
||||||
|
{
|
||||||
|
unsigned int n_min;
|
||||||
|
int key, value;
|
||||||
|
|
||||||
|
for (n_min = 0; n_min <= 1; n_min++) {
|
||||||
|
for (key = 0; key < OVSDB_N_TYPES; key++) {
|
||||||
|
if (key == OVSDB_TYPE_VOID) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (value = 0; value < OVSDB_N_TYPES; value++) {
|
||||||
|
struct ovsdb_datum datum;
|
||||||
|
struct ovsdb_type type;
|
||||||
|
|
||||||
|
ovsdb_base_type_init(&type.key, key);
|
||||||
|
ovsdb_base_type_init(&type.value, value);
|
||||||
|
type.n_min = n_min;
|
||||||
|
type.n_max = 1;
|
||||||
|
assert(ovsdb_type_is_valid(&type));
|
||||||
|
|
||||||
|
printf("key %s, value %s, n_min %u: ",
|
||||||
|
ovsdb_atomic_type_to_string(key),
|
||||||
|
ovsdb_atomic_type_to_string(value), n_min);
|
||||||
|
|
||||||
|
ovsdb_datum_init_default(&datum, &type);
|
||||||
|
if (!ovsdb_datum_equals(&datum, ovsdb_datum_default(&type),
|
||||||
|
&type)) {
|
||||||
|
printf("wrong\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
ovsdb_datum_destroy(&datum, &type);
|
||||||
|
ovsdb_type_destroy(&type);
|
||||||
|
|
||||||
|
printf("OK\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_parse_atomic_type(int argc OVS_UNUSED, char *argv[])
|
do_parse_atomic_type(int argc OVS_UNUSED, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -1813,6 +1882,8 @@ do_idl(int argc, char *argv[])
|
|||||||
|
|
||||||
static struct command all_commands[] = {
|
static struct command all_commands[] = {
|
||||||
{ "log-io", 2, INT_MAX, do_log_io },
|
{ "log-io", 2, INT_MAX, do_log_io },
|
||||||
|
{ "default-atoms", 0, 0, do_default_atoms },
|
||||||
|
{ "default-data", 0, 0, do_default_data },
|
||||||
{ "parse-atomic-type", 1, 1, do_parse_atomic_type },
|
{ "parse-atomic-type", 1, 1, do_parse_atomic_type },
|
||||||
{ "parse-base-type", 1, 1, do_parse_base_type },
|
{ "parse-base-type", 1, 1, do_parse_base_type },
|
||||||
{ "parse-type", 1, 1, do_parse_type },
|
{ "parse-type", 1, 1, do_parse_type },
|
||||||
|
Reference in New Issue
Block a user