Changeset: d644a90a96ee for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/d644a90a96ee
Modified Files:
        sql/storage/sql_storage.h
        sql/storage/store.c
Branch: iso
Log Message:

Clean older dependency changes, so future transactions have less chance to 
conflict


diffs (truncated from 410 to 300 lines):

diff --git a/sql/storage/sql_storage.h b/sql/storage/sql_storage.h
--- a/sql/storage/sql_storage.h
+++ b/sql/storage/sql_storage.h
@@ -480,6 +480,11 @@ typedef struct sqlstore {
        void *logger;                   /* space to keep logging structure of 
storage backend */
 } sqlstore;
 
+typedef struct sql_dependency_change {
+       sqlid objid; /* id of the object where the dependency was created */
+       ulng ts; /* committed timestamp */
+} sql_dependency_change;
+
 typedef struct sql_change {
        sql_base *obj;
        ulng ts;        /* commit/rollback timestamp */
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -1676,23 +1676,18 @@ id_hash(sqlid *id)
 static void
 id_hash_clear(sql_hash *h)
 {
-       if (h == NULL || h->sa)
+       if (h == NULL || h->sa || h->entries == 0)
                return;
        for (int i = 0; i < h->size; i++) {
-               sql_hash_e *e = h->buckets[i], *c = NULL;
-
-               if (e) {
+               sql_hash_e *e = h->buckets[i];
+
+               while (e) {
+                       sql_hash_e *next = e->chain;
+
                        _DELETE(e->value);
-                       c = e->chain;
+                       _DELETE(e);
+                       e = next;
                }
-               while (c) {
-                       sql_hash_e *next = c->chain;
-
-                       _DELETE(c->value);
-                       _DELETE(c);
-                       c = next;
-               }
-               _DELETE(e);
                h->buckets[i] = NULL;
        }
        h->entries = 0;
@@ -1704,20 +1699,15 @@ id_hash_destroy(sql_hash *h)
        if (h == NULL || h->sa)
                return;
        for (int i = 0; i < h->size; i++) {
-               sql_hash_e *e = h->buckets[i], *c = NULL;
-
-               if (e) {
+               sql_hash_e *e = h->buckets[i];
+
+               while (e) {
+                       sql_hash_e *next = e->chain;
+
                        _DELETE(e->value);
-                       c = e->chain;
+                       _DELETE(e);
+                       e = next;
                }
-               while (c) {
-                       sql_hash_e *next = c->chain;
-
-                       _DELETE(c->value);
-                       _DELETE(c);
-                       c = next;
-               }
-               _DELETE(e);
        }
        _DELETE(h->buckets);
        _DELETE(h);
@@ -2175,6 +2165,35 @@ store_resume_log(sqlstore *store)
 }
 
 static void
+id_hash_clear_older(sql_hash *h, ulng oldest)
+{
+       for (int i = 0; i < h->size; i++) {
+               sql_hash_e *e = h->buckets[i], *c = NULL, *first = NULL;
+
+               while (e) {
+                       sql_hash_e *next = e->chain;
+                       sql_dependency_change *dc = e->value;
+
+                       if (dc->ts < oldest) {
+                               _DELETE(e->value);
+                               _DELETE(e);
+                               h->entries--;
+                       } else {
+                               if (c)
+                                       c->chain = e;
+                               else
+                                       first = e;
+                               c = e;
+                       }
+                       e = next;
+               }
+               if (c)
+                       c->chain = NULL;
+               h->buckets[i] = first;
+       }
+}
+
+static void
 store_pending_changes(sqlstore *store, ulng oldest)
 {
        ulng oldest_changes = store_get_timestamp(store);
@@ -2194,6 +2213,10 @@ store_pending_changes(sqlstore *store, u
                        n = next;
                }
        }
+       if (!hash_empty(store->dependencies))
+               id_hash_clear_older(store->dependencies, oldest);
+       if (!hash_empty(store->removals))
+               id_hash_clear_older(store->removals, oldest);
        store->oldest_pending = oldest_changes;
 }
 
@@ -3416,11 +3439,11 @@ sql_trans_rollback(sql_trans *tr)
                                c->commit(tr, c, 0 /* ie rollback */, oldest);
                        c->ts = commit_ts;
                }
-               store_pending_changes(store, oldest);
                if (ATOMIC_GET(&store->nr_active) == 1 && !tr->parent) {
                        id_hash_clear(store->dependencies);
                        id_hash_clear(store->removals);
                }
+               store_pending_changes(store, oldest);
                for(node *n=nl->h; n; n = n->next) {
                        sql_change *c = n->data;
 
@@ -3438,12 +3461,12 @@ sql_trans_rollback(sql_trans *tr)
                store_unlock(store);
        } else if (ATOMIC_GET(&store->nr_active) == 1) { /* just me cleanup */
                store_lock(store);
-               ulng oldest = store_timestamp(store);
-               store_pending_changes(store, oldest);
                if (ATOMIC_GET(&store->nr_active) == 1 && !tr->parent) {
                        id_hash_clear(store->dependencies);
                        id_hash_clear(store->removals);
                }
+               ulng oldest = store_timestamp(store);
+               store_pending_changes(store, oldest);
                store_unlock(store);
        }
        if (tr->localtmps.dset) {
@@ -3598,21 +3621,25 @@ sql_trans_valid(sql_trans *tr)
        return ok;
 }
 
-static int
-transaction_add_hash_entry(sql_hash *h, sqlid id)
+static inline int
+transaction_add_hash_entry(sql_hash *h, sqlid id, ulng commit_ts)
 {
        int key = h->key(&id);
-       sqlid *local_id = MNEW(sqlid);
-
-       if (!local_id)
+       sql_dependency_change *next_change = MNEW(sql_dependency_change);
+
+       if (!next_change)
                return LOG_ERR;
-       *local_id = id;
-       hash_add(h, key, local_id);
+       *next_change = (sql_dependency_change) {
+               .objid = id,
+               .ts = commit_ts
+       };
+
+       hash_add(h, key, next_change);
        return LOG_OK;
 }
 
 static int
-transaction_check_dependencies_and_removals(sql_trans *tr)
+transaction_check_dependencies_and_removals(sql_trans *tr, ulng commit_ts)
 {
        int ok = LOG_OK;
        sqlstore *store = tr->store;
@@ -3625,9 +3652,9 @@ transaction_check_dependencies_and_remov
                        sql_hash_e *he = 
store->removals->buckets[key&(store->removals->size-1)];
 
                        for (; he && ok == LOG_OK; he = he->chain) {
-                               sqlid nid = *(sqlid*) he->value;
-
-                               if (id == nid)
+                               sql_dependency_change *nid = 
(sql_dependency_change*) he->value;
+
+                               if (id == nid->objid)
                                        ok = LOG_CONFLICT;
                        }
                }
@@ -3639,9 +3666,9 @@ transaction_check_dependencies_and_remov
                        sql_hash_e *he = 
store->dependencies->buckets[key&(store->dependencies->size-1)];
 
                        for (; he && ok == LOG_OK; he = he->chain) {
-                               sqlid nid = *(sqlid*) he->value;
-
-                               if (id == nid)
+                               sql_dependency_change *nid = 
(sql_dependency_change*) he->value;
+
+                               if (id == nid->objid)
                                        ok = LOG_CONFLICT;
                        }
                }
@@ -3649,10 +3676,10 @@ transaction_check_dependencies_and_remov
        /* if all checks passed, add them to the storage */
        if (ok == LOG_OK && !list_empty(tr->dependencies))
                for (node *n = tr->dependencies->h; n && ok == LOG_OK; n = 
n->next)
-                       ok = transaction_add_hash_entry(store->dependencies, 
*(sqlid*)n->data);
+                       ok = transaction_add_hash_entry(store->dependencies, 
*(sqlid*)n->data, commit_ts);
        if (ok == LOG_OK && !list_empty(tr->removals))
                for (node *n = tr->removals->h; n && ok == LOG_OK; n = n->next)
-                       ok = transaction_add_hash_entry(store->removals, 
*(sqlid*)n->data);
+                       ok = transaction_add_hash_entry(store->removals, 
*(sqlid*)n->data, commit_ts);
        return ok;
 }
 
@@ -3673,108 +3700,102 @@ sql_trans_commit(sql_trans *tr)
                store_unlock(store);
        }
 
-       if (!tr->parent && (!list_empty(tr->dependencies) || 
!list_empty(tr->removals))) {
+       if (!list_empty(tr->changes) || (!tr->parent && 
(!list_empty(tr->dependencies) || !list_empty(tr->removals)))) {
+               int flush = 0;
+               ulng commit_ts = tr->parent ? tr->parent->tid : 
store_timestamp(store);
+
                MT_lock_set(&store->commit);
                store_lock(store);
-
-               if ((ok = transaction_check_dependencies_and_removals(tr)) != 
LOG_OK) {
+               ulng oldest = store_oldest(store);
+               store_pending_changes(store, oldest);
+               oldest = store_oldest_pending(store);
+
+               if (!tr->parent && (!list_empty(tr->dependencies) || 
!list_empty(tr->removals)) &&
+                       (ok = transaction_check_dependencies_and_removals(tr, 
commit_ts)) != LOG_OK) {
                        store_unlock(store);
                        MT_lock_unset(&store->commit);
                        sql_trans_rollback(tr);
                        return ok == LOG_CONFLICT ? SQL_CONFLICT : SQL_ERR;
                }
                store_unlock(store);
-               MT_lock_unset(&store->commit);
-       }
-
-       if (!list_empty(tr->changes)) {
-               MT_lock_set(&store->commit);
-               store_lock(store);
-
-               ulng oldest = store_oldest(store);
-               store_pending_changes(store, oldest);
-               oldest = store_oldest_pending(store);
-               store_unlock(store);
-               ulng commit_ts = 0;
-               int flush = 0;
-               /* log changes should only be done if there is something to log 
*/
-               if (!tr->parent && tr->logchanges > 0) {
-                       int min_changes = GDKdebug & FORCEMITOMASK ? 5 : 
1000000;
-                       flush = (tr->logchanges > min_changes && 
list_empty(store->changes));
-                       if (flush)
-                               MT_lock_set(&store->flush);
-                       ok = store->logger_api.log_tstart(store, flush);
-                       /* log */
+               if (!list_empty(tr->changes)) {
+                       /* log changes should only be done if there is 
something to log */
+                       if (!tr->parent && tr->logchanges > 0) {
+                               int min_changes = GDKdebug & FORCEMITOMASK ? 5 
: 1000000;
+                               flush = (tr->logchanges > min_changes && 
list_empty(store->changes));
+                               if (flush)
+                                       MT_lock_set(&store->flush);
+                               ok = store->logger_api.log_tstart(store, flush);
+                               /* log */
+                               for(node *n=tr->changes->h; n && ok == LOG_OK; 
n = n->next) {
+                                       sql_change *c = n->data;
+
+                                       if (c->log && ok == LOG_OK)
+                                               ok = c->log(tr, c);
+                               }
+                               if (ok == LOG_OK && store->prev_oid != 
store->obj_id)
+                                       ok = 
store->logger_api.log_sequence(store, OBJ_SID, store->obj_id);
+                               store->prev_oid = store->obj_id;
+                               store_lock(store);
+                               if (ok == LOG_OK && !flush)
+                                       ok = store->logger_api.log_tend(store, 
commit_ts);
+                       } else {
+                               oldest = tr->parent ? commit_ts : oldest;
+                               if (tr->parent)
+                                       tr->parent->logchanges += 
tr->logchanges;
+                               store_lock(store);
+                       }
+                       tr->logchanges = 0;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to