-/* Copyright (c) 2009, 2010 Nicira Networks.
+/* Copyright (c) 2009, 2010, 2011 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
assert(!idl->txn);
jsonrpc_session_run(idl->session);
for (i = 0; jsonrpc_session_is_connected(idl->session) && i < 50; i++) {
- struct jsonrpc_msg *msg, *reply;
+ struct jsonrpc_msg *msg;
unsigned int seqno;
seqno = jsonrpc_session_get_seqno(idl->session);
break;
}
- reply = NULL;
if (msg->type == JSONRPC_NOTIFY
&& !strcmp(msg->method, "update")
&& msg->params->type == JSON_ARRAY
idl->monitor_request_id = NULL;
ovsdb_idl_clear(idl);
ovsdb_idl_parse_update(idl, msg->result);
- } else if (msg->type == JSONRPC_REPLY
- && msg->id && msg->id->type == JSON_STRING
+ } else if (msg->type == JSONRPC_REPLY && msg->id->type == JSON_STRING
&& !strcmp(msg->id->u.string, "echo")) {
/* It's a reply to our echo request. Ignore it. */
} else if ((msg->type == JSONRPC_ERROR
jsonrpc_session_get_name(idl->session),
jsonrpc_msg_type_to_string(msg->type));
}
- if (reply) {
- jsonrpc_session_send(idl->session, reply);
- }
jsonrpc_msg_destroy(msg);
}
return ovsdb_idl_read(row, column);
}
+
+/* Returns false if 'row' was obtained from the IDL, true if it was initialized
+ * to all-zero-bits by some other entity. If 'row' was set up some other way
+ * then the return value is indeterminate. */
+bool
+ovsdb_idl_row_is_synthetic(const struct ovsdb_idl_row *row)
+{
+ return row->table == NULL;
+}
\f
/* Transactions. */
if (row->old == row->new) {
continue;
} else if (!row->new) {
- struct json *op = json_object_create();
- json_object_put_string(op, "op", "delete");
- json_object_put_string(op, "table", class->name);
- json_object_put(op, "where", where_uuid_equals(&row->uuid));
- json_array_add(operations, op);
- any_updates = true;
+ if (class->is_root) {
+ struct json *op = json_object_create();
+ json_object_put_string(op, "op", "delete");
+ json_object_put_string(op, "table", class->name);
+ json_object_put(op, "where", where_uuid_equals(&row->uuid));
+ json_array_add(operations, op);
+ any_updates = true;
+ } else {
+ /* Let ovsdb-server decide whether to really delete it. */
+ }
} else {
struct json *row_json;
struct json *op;
&class->columns[idx];
if (row->old
- ? !ovsdb_datum_equals(&row->old[idx], &row->new[idx],
- &column->type)
- : !ovsdb_datum_is_default(&row->new[idx],
+ || !ovsdb_datum_is_default(&row->new[idx],
&column->type)) {
json_object_put(row_json, column->name,
substitute_uuids(
assert(row->old == NULL ||
row->table->modes[column_idx] & OVSDB_IDL_MONITOR);
+ /* If this is a write-only column and the datum being written is the same
+ * as the one already there, just skip the update entirely. This is worth
+ * optimizing because we have a lot of columns that get periodically
+ * refreshed into the database but don't actually change that often.
+ *
+ * We don't do this for read/write columns because that would break
+ * atomicity of transactions--some other client might have written a
+ * different value in that column since we read it. */
+ if (row->table->modes[column_idx] == OVSDB_IDL_MONITOR
+ && ovsdb_datum_equals(ovsdb_idl_read(row, column),
+ datum, &column->type)) {
+ ovsdb_datum_destroy(datum, &column->type);
+ return;
+ }
+
if (hmap_node_is_null(&row->txn_node)) {
hmap_insert(&row->table->idl->txn->txn_rows, &row->txn_node,
uuid_hash(&row->uuid));