2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 01:51:26 +00:00

ovsdb: Add lazy-copy support for ovsdb_datum objects.

Currently ovsdb-server is using shallow copies of some JSON objects
by keeping a reference counter.  JSON string objects are also used
directly as ovsdb atoms in database rows to avoid extra copies.

Taking this approach one step further ovsdb_datum objects can also
be mostly deduplicated by postponing the copy until it actually
needed.  datum object itself contains a type and 2 pointers to
data arrays.  Adding a one more pointer to a reference counter
we may create a shallow copy of the datum by simply copying type
and pointers and increasing the reference counter.

Before modifying the datum, special function needs to be called
to perform an actual copy of the object, a.k.a. unshare it.
Most of the datum modifications are performed inside the special
functions in ovsdb-data.c, so that is not very hard to track.
A few places like ovsdb-server.c and column mutations are accessing
and changing the data directly, so a few extra unshare() calls
has to be added there.

This change doesn't affect the maximum memory consumption too much,
because most of the copies are short-living.  However, not actually
performing these copies saves up to 40% of CPU time on operations
with large sets.

Reported-at: https://bugzilla.redhat.com/2069089
Acked-by: Dumitru Ceara <dceara@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
This commit is contained in:
Ilya Maximets 2022-07-01 01:34:06 +02:00
parent 02dabb21f2
commit 485ac63d10
13 changed files with 137 additions and 80 deletions

View File

@ -1503,7 +1503,7 @@ cmd_add(struct ctl_context *ctx)
}
type = &column->type;
ovsdb_datum_clone(&old, ovsdb_idl_read(row, column), &column->type);
ovsdb_datum_clone(&old, ovsdb_idl_read(row, column));
for (i = 4; i < ctx->argc; i++) {
struct ovsdb_type add_type;
struct ovsdb_datum add;
@ -1588,7 +1588,7 @@ cmd_remove(struct ctl_context *ctx)
}
type = &column->type;
ovsdb_datum_clone(&old, ovsdb_idl_read(row, column), &column->type);
ovsdb_datum_clone(&old, ovsdb_idl_read(row, column));
for (i = 4; i < ctx->argc; i++) {
struct ovsdb_type rm_type;
struct ovsdb_datum rm;

View File

@ -896,6 +896,7 @@ ovsdb_datum_init_empty(struct ovsdb_datum *datum)
datum->n = 0;
datum->keys = NULL;
datum->values = NULL;
datum->refcnt = NULL;
}
/* Initializes 'datum' as a datum that has the default value for 'type'.
@ -917,6 +918,7 @@ ovsdb_datum_init_default(struct ovsdb_datum *datum,
datum->n = type->n_min;
datum->keys = alloc_default_atoms(type->key.type, datum->n);
datum->values = alloc_default_atoms(type->value.type, datum->n);
datum->refcnt = NULL;
}
/* Returns a read-only datum of the given 'type' that has the default value for
@ -928,10 +930,12 @@ const struct ovsdb_datum *
ovsdb_datum_default(const struct ovsdb_type *type)
{
if (type->n_min == 0) {
static const struct ovsdb_datum empty;
static unsigned int refcnt = 1;
static const struct ovsdb_datum empty = { .refcnt = &refcnt };
return &empty;
} else if (type->n_min == 1) {
static struct ovsdb_datum default_data[OVSDB_N_TYPES][OVSDB_N_TYPES];
static unsigned int refcnt[OVSDB_N_TYPES][OVSDB_N_TYPES];
struct ovsdb_datum *d;
int kt = type->key.type;
int vt = type->value.type;
@ -946,6 +950,8 @@ ovsdb_datum_default(const struct ovsdb_type *type)
d->values = CONST_CAST(union ovsdb_atom *,
ovsdb_atom_default(vt));
}
d->refcnt = &refcnt[kt][vt];
*d->refcnt = 1;
}
return d;
} else {
@ -999,18 +1005,23 @@ clone_atoms(const union ovsdb_atom *old, enum ovsdb_atomic_type type, size_t n)
}
}
/* Initializes 'new' as a copy of 'old', with the given 'type'.
/* Initializes 'new' as a shallow copy of 'old_'.
*
* The caller must eventually arrange for 'new' to be destroyed (with
* ovsdb_datum_destroy()). */
* ovsdb_datum_destroy()). The caller must call ovsdb_datum_unshare()
* before attempting direct modifications of the 'new' or 'old_', i.e.
* modifications outside of the ovsdb_datum_* API. */
void
ovsdb_datum_clone(struct ovsdb_datum *new, const struct ovsdb_datum *old,
const struct ovsdb_type *type)
ovsdb_datum_clone(struct ovsdb_datum *new, const struct ovsdb_datum *old_)
{
unsigned int n = old->n;
new->n = n;
new->keys = clone_atoms(old->keys, type->key.type, n);
new->values = clone_atoms(old->values, type->value.type, n);
struct ovsdb_datum *old = CONST_CAST(struct ovsdb_datum *, old_);
if (!old->refcnt) {
old->refcnt = xmalloc(sizeof *old->refcnt);
*old->refcnt = 1;
}
memcpy(new, old, sizeof *new);
(*new->refcnt)++;
}
static void
@ -1037,8 +1048,25 @@ free_data(enum ovsdb_atomic_type type,
void
ovsdb_datum_destroy(struct ovsdb_datum *datum, const struct ovsdb_type *type)
{
free_data(type->key.type, datum->keys, datum->n);
free_data(type->value.type, datum->values, datum->n);
if (!datum->refcnt || !--(*datum->refcnt)) {
free_data(type->key.type, datum->keys, datum->n);
free_data(type->value.type, datum->values, datum->n);
free(datum->refcnt);
}
}
/* This function should be called before attempting direct modifications
* of the 'datum', i.e. modifications outside of the ovsdb_datum_* API. */
void
ovsdb_datum_unshare(struct ovsdb_datum *datum, const struct ovsdb_type *type)
{
if (!datum->refcnt || *datum->refcnt == 1) {
return;
}
datum->keys = clone_atoms(datum->keys, type->key.type, datum->n);
datum->values = clone_atoms(datum->values, type->value.type, datum->n);
(*datum->refcnt)--;
datum->refcnt = NULL;
}
/* Swaps the contents of 'a' and 'b', which need not have the same type. */
@ -1107,7 +1135,7 @@ ovsdb_datum_sort__(struct ovsdb_datum *datum, enum ovsdb_atomic_type key_type,
* caller must free the returned error when it is no longer needed. On error,
* 'datum' is sorted but not unique. */
struct ovsdb_error *
ovsdb_datum_sort(struct ovsdb_datum *datum, enum ovsdb_atomic_type key_type)
ovsdb_datum_sort(struct ovsdb_datum *datum, const struct ovsdb_type *type)
{
size_t i;
@ -1115,11 +1143,13 @@ ovsdb_datum_sort(struct ovsdb_datum *datum, enum ovsdb_atomic_type key_type)
return NULL;
}
ovsdb_datum_sort__(datum, key_type, OVSDB_TYPE_VOID);
ovsdb_datum_unshare(datum, type);
ovsdb_datum_sort__(datum, type->key.type, OVSDB_TYPE_VOID);
for (i = 0; i < datum->n - 1; i++) {
if (ovsdb_atom_equals(&datum->keys[i], &datum->keys[i + 1],
key_type)) {
type->key.type)) {
if (datum->values) {
return ovsdb_error(NULL, "map contains duplicate key");
} else {
@ -1135,9 +1165,9 @@ ovsdb_datum_sort(struct ovsdb_datum *datum, enum ovsdb_atomic_type key_type)
* this function assert-fails if it actually does. */
void
ovsdb_datum_sort_assert(struct ovsdb_datum *datum,
enum ovsdb_atomic_type key_type)
const struct ovsdb_type *type)
{
struct ovsdb_error *error = ovsdb_datum_sort(datum, key_type);
struct ovsdb_error *error = ovsdb_datum_sort(datum, type);
if (error) {
OVS_NOT_REACHED();
}
@ -1150,8 +1180,7 @@ ovsdb_datum_sort_assert(struct ovsdb_datum *datum,
* Returns the number of keys (or pairs) that were dropped. */
size_t
ovsdb_datum_sort_unique(struct ovsdb_datum *datum,
enum ovsdb_atomic_type key_type,
enum ovsdb_atomic_type value_type)
const struct ovsdb_type *type)
{
size_t src, dst;
@ -1159,20 +1188,21 @@ ovsdb_datum_sort_unique(struct ovsdb_datum *datum,
return 0;
}
ovsdb_datum_sort__(datum, key_type, value_type);
ovsdb_datum_unshare(datum, type);
ovsdb_datum_sort__(datum, type->key.type, type->value.type);
dst = 1;
for (src = 1; src < datum->n; src++) {
if (ovsdb_atom_equals(&datum->keys[src], &datum->keys[dst - 1],
key_type)) {
ovsdb_atom_destroy(&datum->keys[src], key_type);
if (value_type != OVSDB_TYPE_VOID) {
ovsdb_atom_destroy(&datum->values[src], value_type);
type->key.type)) {
ovsdb_atom_destroy(&datum->keys[src], type->key.type);
if (type->value.type != OVSDB_TYPE_VOID) {
ovsdb_atom_destroy(&datum->values[src], type->value.type);
}
} else {
if (src != dst) {
datum->keys[dst] = datum->keys[src];
if (value_type != OVSDB_TYPE_VOID) {
if (type->value.type != OVSDB_TYPE_VOID) {
datum->values[dst] = datum->values[src];
}
}
@ -1258,6 +1288,7 @@ ovsdb_datum_from_json__(struct ovsdb_datum *datum,
datum->n = 0;
datum->keys = xmalloc(n * sizeof *datum->keys);
datum->values = is_map ? xmalloc(n * sizeof *datum->values) : NULL;
datum->refcnt = NULL;
for (i = 0; i < n; i++) {
const struct json *element = inner->array.elems[i];
const struct json *key = NULL;
@ -1298,6 +1329,7 @@ ovsdb_datum_from_json__(struct ovsdb_datum *datum,
datum->n = 1;
datum->keys = xmalloc(sizeof *datum->keys);
datum->values = NULL;
datum->refcnt = NULL;
error = ovsdb_atom_from_json(&datum->keys[0], &type->key,
json, symtab);
@ -1331,7 +1363,7 @@ ovsdb_datum_from_json(struct ovsdb_datum *datum,
return error;
}
error = ovsdb_datum_sort(datum, type->key.type);
error = ovsdb_datum_sort(datum, type);
if (error) {
ovsdb_datum_destroy(datum, type);
}
@ -1609,7 +1641,7 @@ ovsdb_datum_from_string(struct ovsdb_datum *datum,
goto error;
}
dberror = ovsdb_datum_sort(datum, type->key.type);
dberror = ovsdb_datum_sort(datum, type);
if (dberror) {
ovsdb_error_destroy(dberror);
if (ovsdb_type_is_map(type)) {
@ -1687,6 +1719,7 @@ ovsdb_datum_from_smap(struct ovsdb_datum *datum, const struct smap *smap)
datum->n = smap_count(smap);
datum->keys = xmalloc(datum->n * sizeof *datum->keys);
datum->values = xmalloc(datum->n * sizeof *datum->values);
datum->refcnt = NULL;
struct smap_node *node;
size_t i = 0;
@ -1697,7 +1730,11 @@ ovsdb_datum_from_smap(struct ovsdb_datum *datum, const struct smap *smap)
}
ovs_assert(i == datum->n);
ovsdb_datum_sort_unique(datum, OVSDB_TYPE_STRING, OVSDB_TYPE_STRING);
struct ovsdb_type type = {
OVSDB_BASE_STRING_INIT, OVSDB_BASE_STRING_INIT,
0, UINT_MAX
};
ovsdb_datum_sort_unique(datum, &type);
}
struct ovsdb_error * OVS_WARN_UNUSED_RESULT
@ -1774,6 +1811,10 @@ ovsdb_datum_compare_3way(const struct ovsdb_datum *a,
return a->n < b->n ? -1 : 1;
}
if (a->refcnt && a->refcnt == b->refcnt) {
return 0;
}
cmp = atom_arrays_compare_3way(a->keys, b->keys, type->key.type, a->n);
if (cmp) {
return cmp;
@ -1893,6 +1934,8 @@ static void
ovsdb_datum_reallocate(struct ovsdb_datum *a, const struct ovsdb_type *type,
unsigned int capacity)
{
ovsdb_datum_unshare(a, type);
a->keys = xrealloc(a->keys, capacity * sizeof *a->keys);
if (type->value.type != OVSDB_TYPE_VOID) {
a->values = xrealloc(a->values, capacity * sizeof *a->values);
@ -1909,6 +1952,8 @@ void
ovsdb_datum_remove_unsafe(struct ovsdb_datum *datum, size_t idx,
const struct ovsdb_type *type)
{
ovsdb_datum_unshare(datum, type);
ovsdb_atom_destroy(&datum->keys[idx], type->key.type);
datum->keys[idx] = datum->keys[datum->n - 1];
if (type->value.type != OVSDB_TYPE_VOID) {
@ -1940,6 +1985,9 @@ ovsdb_datum_add_unsafe(struct ovsdb_datum *datum,
const union ovsdb_atom *range_end_atom)
{
size_t idx = datum->n;
ovsdb_datum_unshare(datum, type);
datum->n += range_end_atom ?
(range_end_atom->integer - key->integer + 1) : 1;
datum->keys = xrealloc(datum->keys, datum->n * sizeof *datum->keys);
@ -1984,6 +2032,8 @@ ovsdb_datum_push_unsafe(struct ovsdb_datum *dst,
return;
}
ovsdb_datum_unshare(dst, type);
memcpy(&dst->keys[dst->n], &src->keys[start_idx], n * sizeof src->keys[0]);
if (type->value.type != OVSDB_TYPE_VOID) {
memcpy(&dst->values[dst->n], &src->values[start_idx],
@ -1999,6 +2049,7 @@ ovsdb_datum_union(struct ovsdb_datum *a, const struct ovsdb_datum *b,
struct ovsdb_datum result;
unsigned int copied, pos;
ovsdb_datum_unshare(a, type);
ovsdb_datum_init_empty(&result);
copied = 0;
@ -2050,6 +2101,8 @@ ovsdb_datum_subtract(struct ovsdb_datum *a, const struct ovsdb_type *a_type,
ovs_assert(a_type->value.type == b_type->value.type
|| b_type->value.type == OVSDB_TYPE_VOID);
ovsdb_datum_unshare(a, a_type);
idx = xmalloc(b->n * sizeof *idx);
n_idx = 0;
for (size_t bi = 0; bi < b->n; bi++) {
@ -2168,8 +2221,8 @@ ovsdb_datum_added_removed(struct ovsdb_datum *added,
ovsdb_datum_init_empty(added);
ovsdb_datum_init_empty(removed);
if (!ovsdb_type_is_composite(type)) {
ovsdb_datum_clone(removed, old, type);
ovsdb_datum_clone(added, new, type);
ovsdb_datum_clone(removed, old);
ovsdb_datum_clone(added, new);
return;
}
@ -2228,7 +2281,7 @@ ovsdb_datum_diff(struct ovsdb_datum *diff,
ovsdb_datum_init_empty(diff);
if (!ovsdb_type_is_composite(type)) {
ovsdb_datum_clone(diff, new, type);
ovsdb_datum_clone(diff, new);
return;
}
@ -2283,10 +2336,12 @@ ovsdb_datum_apply_diff_in_place(struct ovsdb_datum *a,
if (!ovsdb_type_is_composite(type)) {
ovsdb_datum_destroy(a, type);
ovsdb_datum_clone(a, diff, type);
ovsdb_datum_clone(a, diff);
return NULL;
}
ovsdb_datum_unshare(a, type);
operation = xmalloc(diff->n * sizeof *operation);
idx = xmalloc(diff->n * sizeof *idx);
new_size = a->n;

View File

@ -146,6 +146,8 @@ struct ovsdb_datum {
unsigned int n; /* Number of 'keys' and 'values'. */
union ovsdb_atom *keys; /* Each of the ovsdb_type's 'key_type'. */
union ovsdb_atom *values; /* Each of the ovsdb_type's 'value_type'. */
unsigned int *refcnt; /* Number of copies with the same
* 'keys' and 'values'. */
};
#define OVSDB_DATUM_INITIALIZER { 0, NULL, NULL }
@ -155,22 +157,21 @@ void ovsdb_datum_init_default(struct ovsdb_datum *, const struct ovsdb_type *);
bool ovsdb_datum_is_default(const struct ovsdb_datum *,
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 *,
const struct ovsdb_type *);
void ovsdb_datum_clone(struct ovsdb_datum *, const struct ovsdb_datum *);
void ovsdb_datum_destroy(struct ovsdb_datum *, const struct ovsdb_type *);
void ovsdb_datum_unshare(struct ovsdb_datum *, const struct ovsdb_type *);
void ovsdb_datum_swap(struct ovsdb_datum *, struct ovsdb_datum *);
/* Checking and maintaining invariants. */
struct ovsdb_error *ovsdb_datum_sort(struct ovsdb_datum *,
enum ovsdb_atomic_type key_type)
const struct ovsdb_type *type)
OVS_WARN_UNUSED_RESULT;
void ovsdb_datum_sort_assert(struct ovsdb_datum *,
enum ovsdb_atomic_type key_type);
const struct ovsdb_type *type);
size_t ovsdb_datum_sort_unique(struct ovsdb_datum *,
enum ovsdb_atomic_type key_type,
enum ovsdb_atomic_type value_type);
const struct ovsdb_type *type);
struct ovsdb_error *ovsdb_datum_check_constraints(
const struct ovsdb_datum *, const struct ovsdb_type *)

View File

@ -1088,7 +1088,7 @@ ovsdb_idl_condition_add_clause__(struct ovsdb_idl_condition *condition,
struct ovsdb_idl_clause *clause = xmalloc(sizeof *clause);
clause->function = src->function;
clause->column = src->column;
ovsdb_datum_clone(&clause->arg, &src->arg, &src->column->type);
ovsdb_datum_clone(&clause->arg, &src->arg);
hmap_insert(&condition->clauses, &clause->hmap_node, hash);
}
@ -1128,12 +1128,14 @@ ovsdb_idl_condition_add_clause(struct ovsdb_idl_condition *condition,
struct ovsdb_idl_clause clause = {
.function = function,
.column = column,
.arg = *arg,
};
ovsdb_datum_clone(&clause.arg, arg);
uint32_t hash = ovsdb_idl_clause_hash(&clause);
if (!ovsdb_idl_condition_find_clause(condition, &clause, hash)) {
ovsdb_idl_condition_add_clause__(condition, &clause, hash);
}
ovsdb_datum_destroy(&clause.arg, &column->type);
}
}
@ -3611,7 +3613,7 @@ ovsdb_idl_txn_write__(const struct ovsdb_idl_row *row_,
if (owns_datum) {
row->new_datum[column_idx] = *datum;
} else {
ovsdb_datum_clone(&row->new_datum[column_idx], datum, &column->type);
ovsdb_datum_clone(&row->new_datum[column_idx], datum);
}
(column->unparse)(row);
(column->parse)(row, &row->new_datum[column_idx]);
@ -3650,8 +3652,7 @@ ovsdb_idl_txn_write(const struct ovsdb_idl_row *row,
const struct ovsdb_idl_column *column,
struct ovsdb_datum *datum)
{
ovsdb_datum_sort_unique(datum,
column->type.key.type, column->type.value.type);
ovsdb_datum_sort_unique(datum, &column->type);
ovsdb_idl_txn_write__(row, column, datum, true);
}

View File

@ -189,8 +189,7 @@ ovsdb_base_type_clone(struct ovsdb_base_type *dst,
if (src->enum_) {
dst->enum_ = xmalloc(sizeof *dst->enum_);
ovsdb_datum_clone(dst->enum_, src->enum_,
ovsdb_base_type_get_enum_type(dst->type));
ovsdb_datum_clone(dst->enum_, src->enum_);
}
switch (dst->type) {

View File

@ -376,9 +376,7 @@ ovsdb_clause_clone(struct ovsdb_clause *new, struct ovsdb_clause *old)
{
new->function = old->function;
new->column = old->column;
ovsdb_datum_clone(&new->arg,
&old->arg,
&old->column->type);
ovsdb_datum_clone(&new->arg, &old->arg);
}
bool

View File

@ -334,9 +334,8 @@ clone_monitor_row_data(const struct ovsdb_monitor_table *mt,
const struct ovsdb_column *c = mt->columns[i].column;
const struct ovsdb_datum *src = &row->fields[c->index];
struct ovsdb_datum *dst = &data[i];
const struct ovsdb_type *type = &c->type;
ovsdb_datum_clone(dst, src, type);
ovsdb_datum_clone(dst, src);
}
return data;
}
@ -359,7 +358,7 @@ update_monitor_row_data(const struct ovsdb_monitor_table *mt,
if (!ovsdb_datum_equals(src, dst, type)) {
ovsdb_datum_destroy(dst, type);
ovsdb_datum_clone(dst, src, type);
ovsdb_datum_clone(dst, src);
}
}
}

View File

@ -287,6 +287,8 @@ mutate_scalar(const struct ovsdb_type *dst_type, struct ovsdb_datum *dst,
struct ovsdb_error *error;
unsigned int i;
ovsdb_datum_unshare(dst, dst_type);
if (base->type == OVSDB_TYPE_INTEGER) {
int64_t y = arg->integer;
for (i = 0; i < dst->n; i++) {
@ -322,7 +324,7 @@ mutate_scalar(const struct ovsdb_type *dst_type, struct ovsdb_datum *dst,
}
}
error = ovsdb_datum_sort(dst, dst_type->key.type);
error = ovsdb_datum_sort(dst, dst_type);
if (error) {
ovsdb_error_destroy(error);
return ovsdb_error("constraint violation",

View File

@ -951,7 +951,10 @@ void
'c': columnName,
'args': ', '.join(['%(type)s%(name)s'
% m for m in members])})
print()
print(" datum.refcnt = NULL;")
if type.n_min == 1 and type.n_max == 1:
print()
print(" union ovsdb_atom *key = xmalloc(sizeof *key);")
if type.value:
print(" union ovsdb_atom *value = xmalloc(sizeof *value);")
@ -1004,10 +1007,6 @@ void
if type.value:
print(" " + type.value.copyCValue("datum.values[i].%s" % type.value.type.to_lvalue_string(), "%s[i]" % valueVar))
print(" }")
if type.value:
valueType = type.value.toAtomicType()
else:
valueType = "OVSDB_TYPE_VOID"
txn_write_func = "ovsdb_idl_txn_write"
print(" %(f)s(&row->header_, &%(s)s_col_%(c)s, &datum);" \
% {'f': txn_write_func,
@ -1035,6 +1034,7 @@ void
datum->n = 1;
datum->keys = xmalloc(datum->n * sizeof *datum->keys);
datum->values = xmalloc(datum->n * sizeof *datum->values);
datum->refcnt = NULL;
''' % {'s': structName, 'c': columnName,'coltype':column.type.key.to_const_c_type(prefix),
'valtype':column.type.value.to_const_c_type(prefix), 'S': structName.upper(),
'C': columnName.upper(), 't': tableName})
@ -1060,6 +1060,7 @@ void
datum->n = 1;
datum->keys = xmalloc(datum->n * sizeof *datum->keys);
datum->values = NULL;
datum->refcnt = NULL;
''' % {'s': structName, 'c': columnName,'coltype':column.type.key.to_const_c_type(prefix),
'valtype':column.type.value.to_const_c_type(prefix), 'S': structName.upper(),
'C': columnName.upper(), 't': tableName})
@ -1087,6 +1088,7 @@ void
datum->n = 1;
datum->keys = xmalloc(datum->n * sizeof *datum->values);
datum->values = NULL;
datum->refcnt = NULL;
''' % {'s': structName, 'c': columnName,
'valtype':column.type.key.to_const_c_type(prefix), 't': tableName})
print(" " + type.key.copyCValue("datum->keys[0].%s" % type.key.type.to_lvalue_string(), "new_value"))
@ -1110,6 +1112,7 @@ void
datum->n = 1;
datum->keys = xmalloc(datum->n * sizeof *datum->values);
datum->values = NULL;
datum->refcnt = NULL;
''' % {'s': structName, 'c': columnName,'coltype':column.type.key.to_const_c_type(prefix),
'valtype':column.type.key.to_const_c_type(prefix), 'S': structName.upper(),
'C': columnName.upper(), 't': tableName})
@ -1179,8 +1182,11 @@ void
'args': ', '.join(['%(type)s%(name)s' % m for m in members])})
print("{")
print(" struct ovsdb_datum datum;")
print("")
print(" datum.refcnt = NULL;")
free = []
if type.n_min == 1 and type.n_max == 1:
print()
print(" union ovsdb_atom *key = xmalloc(sizeof *key);")
if type.value:
print(" union ovsdb_atom *value = xmalloc(sizeof *value);")
@ -1228,12 +1234,8 @@ void
if type.value:
print(" " + type.value.copyCValue("datum.values[i].%s" % type.value.type.to_lvalue_string(), "%s[i]" % valueVar, refTable=False))
print(" }")
if type.value:
valueType = type.value.toAtomicType()
else:
valueType = "OVSDB_TYPE_VOID"
print(" ovsdb_datum_sort_unique(&datum, %s, %s);" % (
type.key.toAtomicType(), valueType))
print(" ovsdb_datum_sort_unique(&datum, &%(s)s_col_%(c)s.type);" \
% {'s': structName, 'c': columnName})
print(""" ovsdb_idl_condition_add_clause(cond,
function,
@ -1341,6 +1343,7 @@ struct %(s)s *
datum->n = smap_count(%(c)s);
datum->keys = xmalloc(datum->n * sizeof *datum->keys);
datum->values = xmalloc(datum->n * sizeof *datum->values);
datum->refcnt = NULL;
i = 0;
SMAP_FOR_EACH (node, %(c)s) {
@ -1348,7 +1351,7 @@ struct %(s)s *
datum->values[i].s = ovsdb_atom_string_create(node->value);
i++;
}
ovsdb_datum_sort_unique(datum, OVSDB_TYPE_STRING, OVSDB_TYPE_STRING);
ovsdb_datum_sort_unique(datum, &%(s)s_col_%(c)s.type);
} else {
ovsdb_datum_init_empty(datum);
}
@ -1387,6 +1390,8 @@ struct %(s)s *
'args': ', '.join(['%(type)s%(name)s' % m for m in members])})
print("{")
print(" struct ovsdb_datum datum;")
print()
print(" datum.refcnt = NULL;")
if type.n_min == 1 and type.n_max == 1:
print(" union ovsdb_atom *key = xmalloc(sizeof(union ovsdb_atom));")
if type.value:
@ -1443,12 +1448,8 @@ struct %(s)s *
if type.value:
print(" " + type.value.copyCValue("datum.values[i].%s" % type.value.type.to_lvalue_string(), "%s[i]" % valueVar))
print(" }")
if type.value:
valueType = type.value.toAtomicType()
else:
valueType = "OVSDB_TYPE_VOID"
print(" ovsdb_datum_sort_unique(&datum, %s, %s);" % (
type.key.toAtomicType(), valueType))
print(" ovsdb_datum_sort_unique(&datum, &%(s)s_col_%(c)s.type);"
% {'s': structName, 'c': columnName})
txn_write_func = "ovsdb_idl_index_write"
print(" %(f)s(CONST_CAST(struct ovsdb_idl_row *, &row->header_), &%(s)s_columns[ %(S)s_COL_%(C)s ], &datum, &%(p)stable_classes[%(P)sTABLE_%(T)s]);" \
% {'f': txn_write_func,

View File

@ -221,6 +221,8 @@ ovsdb_util_write_singleton(struct ovsdb_row *row, const char *column_name,
return;
}
ovsdb_datum_unshare(datum, &column->type);
if (datum->n == 1) {
if (ovsdb_atom_equals(&datum->keys[0], atom, type)) {
return;
@ -231,6 +233,7 @@ ovsdb_util_write_singleton(struct ovsdb_row *row, const char *column_name,
datum->n = 1;
datum->keys = xmalloc(sizeof *datum->keys);
datum->values = NULL;
datum->refcnt = NULL;
}
ovsdb_atom_clone(&datum->keys[0], atom, type);
}
@ -305,6 +308,7 @@ ovsdb_util_write_string_string_column(struct ovsdb_row *row,
datum->n = n;
datum->keys = xmalloc(n * sizeof *datum->keys);
datum->values = xmalloc(n * sizeof *datum->values);
datum->refcnt = NULL;
for (i = 0; i < n; ++i) {
datum->keys[i].s = ovsdb_atom_string_create_nocopy(keys[i]);
@ -312,5 +316,5 @@ ovsdb_util_write_string_string_column(struct ovsdb_row *row,
}
/* Sort and check constraints. */
ovsdb_datum_sort_assert(datum, column->type.key.type);
ovsdb_datum_sort_assert(datum, &column->type);
}

View File

@ -143,8 +143,7 @@ ovsdb_row_clone(const struct ovsdb_row *old)
SHASH_FOR_EACH (node, &table->schema->columns) {
const struct ovsdb_column *column = node->data;
ovsdb_datum_clone(&new->fields[column->index],
&old->fields[column->index],
&column->type);
&old->fields[column->index]);
}
struct ovsdb_weak_ref *weak, *clone;
@ -257,8 +256,7 @@ ovsdb_row_update_columns(struct ovsdb_row *dst,
} else {
ovsdb_datum_destroy(&dst->fields[column->index], &column->type);
ovsdb_datum_clone(&dst->fields[column->index],
&src->fields[column->index],
&column->type);
&src->fields[column->index]);
}
}
return NULL;

View File

@ -693,8 +693,7 @@ assess_weak_refs(struct ovsdb_txn *txn, struct ovsdb_txn_row *txn_row)
ovs_list_init(&weak->src_node);
}
}
ovsdb_datum_sort_unique(&deleted_refs, column->type.key.type,
column->type.value.type);
ovsdb_datum_sort_unique(&deleted_refs, &column->type);
/* Removing elements that references deleted rows. */
ovsdb_datum_subtract(datum, &column->type,
@ -708,7 +707,7 @@ assess_weak_refs(struct ovsdb_txn *txn, struct ovsdb_txn_row *txn_row)
datum, &column->type);
} else {
ovsdb_datum_init_empty(&removed);
ovsdb_datum_clone(&added, datum, &column->type);
ovsdb_datum_clone(&added, datum);
}
/* Checking added data and creating new references. */
@ -732,8 +731,7 @@ assess_weak_refs(struct ovsdb_txn *txn, struct ovsdb_txn_row *txn_row)
}
if (deleted_refs.n) {
/* Removing all the references that doesn't point to valid rows. */
ovsdb_datum_sort_unique(&deleted_refs, column->type.key.type,
column->type.value.type);
ovsdb_datum_sort_unique(&deleted_refs, &column->type);
ovsdb_datum_subtract(datum, &column->type,
&deleted_refs, &column->type);
ovsdb_datum_destroy(&deleted_refs, &column->type);

View File

@ -1679,6 +1679,7 @@ do_transact_set_integer(struct ovsdb_row *row, const char *column_name,
column = ovsdb_table_schema_get_column(do_transact_table->schema,
column_name);
ovsdb_datum_unshare(&row->fields[column->index], &column->type);
row->fields[column->index].keys[0].integer = integer;
}
}