[ovs-dev] [PATCH v2 1/3] lib: Add Partial Map Updates functionality
Ben Pfaff
blp at ovn.org
Wed May 18 17:15:23 UTC 2016
Thanks for the revision. I'm happy with this version.
I folded some mostly stylistic changes into patch 1. The one
non-stylistic change I made was to factor out error checking from
ovsdb_idl_txn_write_partial_map() and ovsdb_idl_txn_delete_partial_map()
into a common function is_valid_partial_update(). This reduced
duplication and made the code easier to read.
I'm appending the changes I folded in.
I applied these patches to master. Thank you!
diff --git a/lib/ovsdb-idl-provider.h b/lib/ovsdb-idl-provider.h
index 1aafb00..04cf419 100644
--- a/lib/ovsdb-idl-provider.h
+++ b/lib/ovsdb-idl-provider.h
@@ -37,9 +37,8 @@ struct ovsdb_idl_row {
unsigned long int *prereqs; /* Bitmap of columns to verify in "old". */
unsigned long int *written; /* Bitmap of columns from "new" to write. */
struct hmap_node txn_node; /* Node in ovsdb_idl_txn's list. */
- unsigned long int *map_op_written; /* Bitmap of columns with pending map
- * operations. */
- struct map_op_list **map_op_lists; /* List of lists of map operations. */
+ unsigned long int *map_op_written; /* Bitmap of columns pending map ops. */
+ struct map_op_list **map_op_lists; /* Per-column map operations. */
/* Tracking data */
unsigned int change_seqno[OVSDB_IDL_CHANGE_MAX];
diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c
index a0796bb..2b372cb 100644
--- a/lib/ovsdb-idl.c
+++ b/lib/ovsdb-idl.c
@@ -1628,7 +1628,8 @@ ovsdb_idl_row_destroy(struct ovsdb_idl_row *row)
}
static void
-ovsdb_idl_destroy_all_map_op_lists(struct ovsdb_idl_row *row){
+ovsdb_idl_destroy_all_map_op_lists(struct ovsdb_idl_row *row)
+{
if (row->map_op_written) {
/* Clear Map Operation Lists */
size_t idx, n_columns;
@@ -2235,7 +2236,7 @@ ovsdb_idl_txn_extract_mutations(struct ovsdb_idl_row *row,
map_op = map_op_list_next(map_op_list, map_op)) {
if (map_op_type(map_op) == MAP_OP_UPDATE) {
- /* Find out if value really changed */
+ /* Find out if value really changed. */
struct ovsdb_datum *new_datum;
unsigned int pos;
new_datum = map_op_datum(map_op);
@@ -2249,13 +2250,13 @@ ovsdb_idl_txn_extract_mutations(struct ovsdb_idl_row *row,
continue;
}
} else if (map_op_type(map_op) == MAP_OP_DELETE){
- /* Verify that there is a key to delete */
+ /* Verify that there is a key to delete. */
unsigned int pos;
pos = ovsdb_datum_find_key(old_datum,
&map_op_datum(map_op)->keys[0],
key_type);
if (pos == UINT_MAX) {
- /* No key to delete. Move on to next update. */
+ /* No key to delete. Move on to next update. */
VLOG_WARN("Trying to delete a key that doesn't "
"exist in the map.");
continue;
@@ -2277,7 +2278,7 @@ ovsdb_idl_txn_extract_mutations(struct ovsdb_idl_row *row,
any_del = true;
}
- /* Generates an additional insert mutate for updates */
+ /* Generate an additional insert mutate for updates. */
if (map_op_type(map_op) == MAP_OP_UPDATE) {
map = json_array_create_2(
ovsdb_atom_to_json(&map_op_datum(map_op)->keys[0],
@@ -2500,7 +2501,7 @@ ovsdb_idl_txn_commit(struct ovsdb_idl_txn *txn)
}
}
- /* Add Map Operation (Partial Map Updates). */
+ /* Add mutate operation, for partial map updates. */
if (row->map_op_written) {
struct json *op, *mutations;
bool any_mutations;
@@ -3343,7 +3344,7 @@ ovsdb_idl_txn_add_map_op(struct ovsdb_idl_row *row,
class = row->table->class;
column_idx = column - class->columns;
- /* Check if a Map Operation List exist for this column */
+ /* Check if a map operation list exists for this column. */
if (!row->map_op_written) {
row->map_op_written = bitmap_allocate(class->n_columns);
row->map_op_lists = xzalloc(class->n_columns *
@@ -3353,18 +3354,39 @@ ovsdb_idl_txn_add_map_op(struct ovsdb_idl_row *row,
row->map_op_lists[column_idx] = map_op_list_create();
}
- /* Add a Map Operation to the corresponding list */
+ /* Add a map operation to the corresponding list. */
map_op = map_op_create(datum, op_type);
bitmap_set1(row->map_op_written, column_idx);
map_op_list_add(row->map_op_lists[column_idx], map_op, &column->type);
- /* Add this row to transaction's list of rows */
+ /* Add this row to transaction's list of rows. */
if (hmap_node_is_null(&row->txn_node)) {
hmap_insert(&row->table->idl->txn->txn_rows, &row->txn_node,
uuid_hash(&row->uuid));
}
}
+static bool
+is_valid_partial_update(const struct ovsdb_idl_row *row,
+ const struct ovsdb_idl_column *column,
+ struct ovsdb_datum *datum)
+{
+ /* Verify that this column is being monitored. */
+ unsigned int column_idx = column - row->table->class->columns;
+ if (!(row->table->modes[column_idx] & OVSDB_IDL_MONITOR)) {
+ VLOG_WARN("cannot partially update non-monitored column");
+ return false;
+ }
+
+ /* Verify that the update affects a single element. */
+ if (datum->n != 1) {
+ VLOG_WARN("invalid datum for partial update");
+ return false;
+ }
+
+ return true;
+}
+
/* Inserts the key-value specified in 'datum' into the map in 'column' in
* 'row_'. If the key already exist in 'column', then it's value is updated
* with the value in 'datum'. The key-value in 'datum' must be of the same type
@@ -3380,36 +3402,20 @@ ovsdb_idl_txn_write_partial_map(const struct ovsdb_idl_row *row_,
struct ovsdb_idl_row *row = CONST_CAST(struct ovsdb_idl_row *, row_);
enum ovsdb_atomic_type key_type;
enum map_op_type op_type;
- unsigned int column_idx, pos;
+ unsigned int pos;
const struct ovsdb_datum *old_datum;
- /* Verify that this column is being monitored */
- column_idx = column - row->table->class->columns;
- if (!(row->table->modes[column_idx] & OVSDB_IDL_MONITOR)) {
- VLOG_WARN("ovsdb_idl_txn_write_partial_map(): Trying to update a non"
- "-monitored column.");
- ovsdb_datum_destroy(datum, &column->type);
- return;
- }
-
- if (datum->n != 1) {
- VLOG_WARN("ovsdb_idl_txn_write_partial_map(): Trying to set an invalid"
- " datum.");
+ if (!is_valid_partial_update(row, column, datum)) {
ovsdb_datum_destroy(datum, &column->type);
return;
}
- /* Find out if this is an insert or an update */
+ /* Find out if this is an insert or an update. */
key_type = column->type.key.type;
old_datum = ovsdb_idl_read(row, column);
pos = ovsdb_datum_find_key(old_datum, &datum->keys[0], key_type);
- if (pos == UINT_MAX) {
- /* Insert operation */
- op_type = MAP_OP_INSERT;
- } else {
- /* Update operation */
- op_type = MAP_OP_UPDATE;
- }
+ op_type = pos == UINT_MAX ? MAP_OP_INSERT : MAP_OP_UPDATE;
+
ovsdb_idl_txn_add_map_op(row, column, datum, op_type);
}
@@ -3426,28 +3432,13 @@ ovsdb_idl_txn_delete_partial_map(const struct ovsdb_idl_row *row_,
struct ovsdb_datum *datum)
{
struct ovsdb_idl_row *row = CONST_CAST(struct ovsdb_idl_row *, row_);
- unsigned int column_idx;
-
- /* Verify that this column is being monitored */
- column_idx = column - row->table->class->columns;
- if (!(row->table->modes[column_idx] & OVSDB_IDL_MONITOR)) {
- VLOG_WARN("ovsdb_idl_txn_delete_partial_map(): Trying to update a non"
- "-monitored column.");
- struct ovsdb_type type_ = column->type;
- type_.value.type = OVSDB_TYPE_VOID;
- ovsdb_datum_destroy(datum, &type_);
- return;
- }
- if (datum->n != 1) {
- VLOG_WARN("ovsdb_idl_txn_delete_partial_map(): Trying to delete using"
- " an invalid datum.");
+ if (!is_valid_partial_update(row, column, datum)) {
struct ovsdb_type type_ = column->type;
type_.value.type = OVSDB_TYPE_VOID;
ovsdb_datum_destroy(datum, &type_);
return;
}
-
ovsdb_idl_txn_add_map_op(row, column, datum, MAP_OP_DELETE);
}
diff --git a/lib/ovsdb-map-op.c b/lib/ovsdb-map-op.c
index 67c3dee..58f43dc 100644
--- a/lib/ovsdb-map-op.c
+++ b/lib/ovsdb-map-op.c
@@ -33,7 +33,7 @@ struct map_op_list {
};
static void map_op_destroy_datum(struct map_op *, const struct ovsdb_type *);
-static struct map_op* map_op_list_find(struct map_op_list *, struct map_op *,
+static struct map_op *map_op_list_find(struct map_op_list *, struct map_op *,
const struct ovsdb_type *, size_t);
struct map_op*
diff --git a/lib/ovsdb-map-op.h b/lib/ovsdb-map-op.h
index 8fd0b9e..140b0f3 100644
--- a/lib/ovsdb-map-op.h
+++ b/lib/ovsdb-map-op.h
@@ -29,17 +29,17 @@ struct map_op; /* Map Operation: a Partial Map Update */
struct map_op_list; /* List of Map Operations */
/* Map Operation functions */
-struct map_op* map_op_create(struct ovsdb_datum *, enum map_op_type);
+struct map_op *map_op_create(struct ovsdb_datum *, enum map_op_type);
void map_op_destroy(struct map_op *, const struct ovsdb_type *);
-struct ovsdb_datum* map_op_datum(const struct map_op*);
+struct ovsdb_datum *map_op_datum(const struct map_op*);
enum map_op_type map_op_type(const struct map_op*);
/* Map Operation List functions */
-struct map_op_list* map_op_list_create(void);
+struct map_op_list *map_op_list_create(void);
void map_op_list_destroy(struct map_op_list *, const struct ovsdb_type *);
void map_op_list_add(struct map_op_list *, struct map_op *,
const struct ovsdb_type *);
-struct map_op* map_op_list_first(struct map_op_list *);
-struct map_op* map_op_list_next(struct map_op_list *, struct map_op *);
+struct map_op *map_op_list_first(struct map_op_list *);
+struct map_op *map_op_list_next(struct map_op_list *, struct map_op *);
#endif /* ovsdb-map-op.h */
More information about the dev
mailing list