save writing the same data twice
authorAndrew Tridgell <tridge@samba.org>
Fri, 8 Aug 2008 00:15:23 +0000 (10:15 +1000)
committerAndrew Tridgell <tridge@samba.org>
Fri, 8 Aug 2008 00:15:23 +0000 (10:15 +1000)
client/ctdb_client.c

index 2b31d81bcb08af03246b7bcac0afdee8a6865b3a..6e1a209a7c27a50195896bddff132b751fb671ea 100644 (file)
@@ -3068,12 +3068,13 @@ int ctdb_transaction_store(struct ctdb_transaction_handle *h,
 {
        TALLOC_CTX *tmp_ctx = talloc_new(h);
        struct ctdb_ltdb_header header;
+       TDB_DATA olddata;
        int ret;
 
        ZERO_STRUCT(header);
 
        /* we need the header so we can update the RSN */
-       ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, tmp_ctx, NULL);
+       ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, tmp_ctx, &olddata);
        if (ret == -1 && header.dmaster == (uint32_t)-1) {
                /* the record doesn't exist - create one with us as dmaster.
                   This is only safe because we are in a transaction and this
@@ -3086,6 +3087,13 @@ int ctdb_transaction_store(struct ctdb_transaction_handle *h,
                return ret;
        }
 
+       if (data.dsize == olddata.dsize &&
+           memcmp(data.dptr, olddata.dptr, data.dsize) == 0) {
+               /* save writing the same data */
+               talloc_free(tmp_ctx);
+               return 0;
+       }
+
        header.rsn++;
 
        if (!h->in_replay) {
@@ -3095,13 +3103,13 @@ int ctdb_transaction_store(struct ctdb_transaction_handle *h,
                        talloc_free(tmp_ctx);
                        return -1;
                }
-               
-               h->m_write = ctdb_marshall_add(h, h->m_write, h->ctdb_db->db_id, 0, key, &header, data);
-               if (h->m_write == NULL) {
-                       DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
-                       talloc_free(tmp_ctx);
-                       return -1;
-               }
+       }               
+
+       h->m_write = ctdb_marshall_add(h, h->m_write, h->ctdb_db->db_id, 0, key, &header, data);
+       if (h->m_write == NULL) {
+               DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
+               talloc_free(tmp_ctx);
+               return -1;
        }
        
        ret = ctdb_ltdb_store(h->ctdb_db, key, &header, data);
@@ -3120,6 +3128,8 @@ static int ctdb_replay_transaction(struct ctdb_transaction_handle *h)
        struct ctdb_rec_data *rec = NULL;
 
        h->in_replay = true;
+       talloc_free(h->m_write);
+       h->m_write = NULL;
 
        ret = ctdb_transaction_fetch_start(h);
        if (ret != 0) {
@@ -3176,12 +3186,6 @@ int ctdb_transaction_commit(struct ctdb_transaction_handle *h)
        struct ctdb_context *ctdb = h->ctdb_db->ctdb;
        struct timeval timeout;
 
-       if (h->m_write == NULL) {
-               /* no changes were made */
-               talloc_free(h);
-               return 0;
-       }
-
        talloc_set_destructor(h, NULL);
 
        /* our commit strategy is quite complex.
@@ -3200,6 +3204,13 @@ int ctdb_transaction_commit(struct ctdb_transaction_handle *h)
        */
 
 again:
+       if (h->m_write == NULL) {
+               /* no changes were made */
+               tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
+               talloc_free(h);
+               return 0;
+       }
+
        /* tell ctdbd to commit to the other nodes */
        timeout = timeval_current_ofs(1, 0);
        ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,