[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