Changeset: 1b1b3916ebd3 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=1b1b3916ebd3
Modified Files:
        gdk/gdk_logger.c
        sql/include/sql_catalog.h
        sql/server/sql_mvc.c
        sql/storage/bat/bat_storage.c
        sql/storage/store.c
Branch: unlock
Log Message:

we now allow for concurrent inserts


diffs (truncated from 633 to 300 lines):

diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c
--- a/gdk/gdk_logger.c
+++ b/gdk/gdk_logger.c
@@ -338,21 +338,25 @@ log_read_updates(logger *lg, trans *tr, 
                        tv = lg->buf;
 
                assert(nr <= (lng) BUN_MAX);
-               if (l->flag == LOG_UPDATE) {
+               if (!lg->flushing && l->flag == LOG_UPDATE) {
                        uid = COLnew(0, TYPE_oid, (BUN)nr, PERSISTENT);
                        if (uid == NULL) {
                                return LOG_ERR;
                        }
                }
-               r = COLnew(0, tpe, (BUN) nr, PERSISTENT);
-               if (r == NULL) {
-                       BBPreclaim(uid);
-                       return LOG_ERR;
+               if (!lg->flushing) {
+                       r = COLnew(0, tpe, (BUN) nr, PERSISTENT);
+                       if (r == NULL) {
+                               if (uid) 
+                                       BBPreclaim(uid);
+                               return LOG_ERR;
+                       }
                }
 
                if (l->flag == LOG_UPDATE_BULK) {
                        if (!mnstr_readLng(lg->input_log, &offset)) {
-                               BBPreclaim(r);
+                               if (r) 
+                                       BBPreclaim(r);
                                return LOG_ERR;
                        }
                        for (; res == LOG_OK && nr > 0; nr--) {
@@ -2075,11 +2079,10 @@ log_delta(logger *lg, BAT *uid, BAT *uva
 
        if (log_write_format(lg, &l) != GDK_SUCCEED ||
            !mnstr_writeLng(lg->output_log, nr) ||
-           mnstr_write(lg->output_log, &tpe, 1, 1) != 1) {
+            mnstr_write(lg->output_log, &tpe, 1, 1) != 1){ 
                logger_unlock(lg);
                return GDK_FAIL;
        }
-       /* TODO call efficient n-value writes */
        for (p = 0; p < BUNlast(uid) && ok == GDK_SUCCEED; p++) {
                const oid id = BUNtoid(uid, p);
 
diff --git a/sql/include/sql_catalog.h b/sql/include/sql_catalog.h
--- a/sql/include/sql_catalog.h
+++ b/sql/include/sql_catalog.h
@@ -195,6 +195,7 @@ typedef int sqlid;
 typedef struct sql_base {
        int wtime;
        int rtime;
+       int atime;      /* appends should not conflict */
        int stime;
        int allocated;
        int flags;
@@ -242,6 +243,7 @@ typedef struct sql_trans {
        int wstime;             /* first write transaction time stamp */
        int rtime;              /* timestamp of latest read performed in 
transaction*/
        int wtime;              /* timestamp of latest write performed in 
transaction*/
+       int atime;              
        int schema_number;      /* schema timestamp */
        int schema_updates;     /* set on schema changes */
        int active;             /* active transaction */
diff --git a/sql/server/sql_mvc.c b/sql/server/sql_mvc.c
--- a/sql/server/sql_mvc.c
+++ b/sql/server/sql_mvc.c
@@ -509,6 +509,8 @@ sql_trans_deref( sql_trans *tr )
 
                                if (t->base.rtime < p->base.rtime)
                                        t->base.rtime = p->base.rtime;
+                               if (t->base.atime < p->base.atime)
+                                       t->base.atime = p->base.atime;
                                if (t->base.wtime < p->base.wtime)
                                        t->base.wtime = p->base.wtime;
                                t->po = p->po;
@@ -525,6 +527,8 @@ sql_trans_deref( sql_trans *tr )
 
                                                if (c->base.rtime < 
p->base.rtime)
                                                        c->base.rtime = 
p->base.rtime;
+                                               if (c->base.atime < 
p->base.atime)
+                                                       c->base.atime = 
p->base.atime;
                                                if (c->base.wtime < 
p->base.wtime)
                                                        c->base.wtime = 
p->base.wtime;
                                                c->po = p->po;
@@ -547,6 +551,8 @@ sql_trans_deref( sql_trans *tr )
 
                                        if (i->base.rtime < p->base.rtime)
                                                i->base.rtime = p->base.rtime;
+                                       if (i->base.atime < p->base.atime)
+                                               i->base.atime = p->base.atime;
                                        if (i->base.wtime < p->base.wtime)
                                                i->base.wtime = p->base.wtime;
                                        i->po = p->po;
@@ -633,7 +639,7 @@ build up the hash (not copied in the tra
 
        store_lock();
        /* if there is nothing to commit reuse the current transaction */
-       if (tr->wtime == 0) {
+       if (tr->wtime == 0 && tr->atime == 0) {
                if (!chain) 
                        sql_trans_end(m->session, 1);
                m->type = Q_TRANS;
@@ -708,7 +714,7 @@ mvc_rollback(mvc *m, int chain, const ch
                tr = m->session->tr;
                while (!tr->name || strcmp(tr->name, name) != 0) {
                        /* make sure we do not reuse changed data */
-                       if (tr->wtime)
+                       if (tr->wtime || tr->atime)
                                tr->status = 1;
                        tr = sql_trans_destroy(tr, true);
                }
@@ -724,7 +730,7 @@ mvc_rollback(mvc *m, int chain, const ch
                }
                m->session-> tr = tr;
                /* make sure we do not reuse changed data */
-               if (tr->wtime)
+               if (tr->wtime || tr->atime)
                        tr->status = 1;
                sql_trans_end(m->session, 0);
                if (chain) 
@@ -740,7 +746,7 @@ mvc_rollback(mvc *m, int chain, const ch
        TRC_INFO(SQL_TRANS, 
                "Commit%s%s rolled back%s%s%.200s\n",
                name ? " " : "", name ? name : "",
-               tr->wtime == 0 ? " (no changes)" : "",
+               (tr->wtime == 0 || tr->atime) ? " (no changes)" : "",
                m->query ? ", query: " : "",
                m->query ? m->query : "");
        return msg;
diff --git a/sql/storage/bat/bat_storage.c b/sql/storage/bat/bat_storage.c
--- a/sql/storage/bat/bat_storage.c
+++ b/sql/storage/bat/bat_storage.c
@@ -13,6 +13,7 @@
 #include "algebra.h"
 #include "gdk_atoms.h"
 
+static MT_Lock segs_lock = MT_LOCK_INITIALIZER("segs_lock");
 static MT_Lock destroy_lock = MT_LOCK_INITIALIZER("destroy_lock");
 storage *tobe_destroyed_dbat = NULL;
 sql_delta *tobe_destroyed_delta = NULL;
@@ -363,7 +364,6 @@ cs_update_bat( column_storage *cs, BAT *
                if (b == NULL)
                        return LOG_ERR;
                if (BATcount(b)==0) { /* alter add column */
-                       assert(BATtdense(tids));
                        if (BATappend(b, updates, NULL, true) != GDK_SUCCEED) {
                                bat_destroy(b);
                                return LOG_ERR;
@@ -579,7 +579,7 @@ delta_append_bat( sql_delta *bat, size_t
                }
                bat_destroy(ui);
        } else {
-               assert (isNew(t) || isTempTable(t) || bat->cs.cleared);
+               //assert (isNew(t) || isTempTable(t) || bat->cs.cleared);
                if (BATcount(b) < offset) { /* add space */
                        const void *tv = ATOMnilptr(b->ttype);
                        lng i, d = offset - BATcount(b);
@@ -624,7 +624,7 @@ delta_append_val( sql_delta *bat, size_t
                        return LOG_ERR;
                }
        } else {
-               assert (isNew(t) || isTempTable(t) || bat->cs.cleared);
+               //assert (isNew(t) || isTempTable(t) || bat->cs.cleared);
                if (BATcount(b) < offset) { /* add space */
                        const void *tv = ATOMnilptr(b->ttype);
                        lng i, d = offset - BATcount(b);
@@ -731,7 +731,9 @@ dup_dbat(storage *obat, storage *bat, in
                bat->end = bat->segs->end;
        } else {
                bat->end = obat->end = obat->segs->end;
+               MT_lock_set(&segs_lock);
                bat->segs = dup_segments(obat->segs);
+               MT_lock_unset(&segs_lock);
                assert(bat->end <= bat->segs->end);
        }
        return dup_cs(&obat->cs, &bat->cs, TYPE_bit, is_new, temp);
@@ -767,11 +769,7 @@ append_col(sql_trans *tr, sql_column *c,
 
        bat = c->data;
        /* appends only write */
-       bat->cs.wtime = c->base.wtime = c->t->base.wtime = c->t->s->base.wtime 
= tr->wtime = tr->wstime;
-       /* inserts are ordered with the current delta implementation */
-       /* therefor mark appends as reads */
-       assert(tr != gtrans);
-       c->t->s->base.rtime = c->t->base.rtime = tr->stime;
+       bat->cs.wtime = c->base.atime = c->t->base.atime = c->t->s->base.atime 
= tr->atime = tr->wstime;
        if (tpe == TYPE_bat)
                ok = delta_append_bat(bat, offset, i, c->t);
        else
@@ -794,7 +792,7 @@ append_idx(sql_trans *tr, sql_idx * i, s
 
        bat = i->data;
        /* appends only write */
-       bat->cs.wtime = i->base.wtime = i->t->base.wtime = i->t->s->base.wtime 
= tr->wtime = tr->wstime;
+       bat->cs.wtime = i->base.atime = i->t->base.atime = i->t->s->base.atime 
= tr->atime = tr->wstime;
        if (tpe == TYPE_bat)
                ok = delta_append_bat(bat, offset, ib, i->t);
        else
@@ -887,12 +885,12 @@ table_claim_space(sql_trans *tr, sql_tab
        node *n = t->columns.set->h;
        sql_column *c = n->data;
 
-       t->base.wtime = t->s->base.wtime = tr->wtime = tr->wstime;
-       c->base.wtime = tr->wstime;
+       t->base.atime = t->s->base.atime = tr->atime = tr->wstime;
+       c->base.atime = tr->wstime;
 
        for (n = t->columns.set->h; n; n = n->next) {
                c = n->data;
-               c->base.wtime = tr->wstime;
+               c->base.atime = tr->wstime;
 
                if (bind_col_data(tr, c) == LOG_ERR)
                        return LOG_ERR;
@@ -903,7 +901,7 @@ table_claim_space(sql_trans *tr, sql_tab
                for (n = t->idxs.set->h; n; n = n->next) {
                        sql_idx *ci = n->data;
 
-                       ci->base.wtime = tr->wstime;
+                       ci->base.atime = tr->wstime;
                        if (isTable(ci->t) && idx_has_column(ci->type)) {
                                if (bind_idx_data(tr, ci) == LOG_ERR)
                                        return LOG_ERR;
@@ -969,7 +967,7 @@ claim_tab(sql_trans *tr, sql_table *t, s
                /* add updates */
                BAT *ui, *uv;
 
-               if (table_claim_space(tr, t, cnt) == LOG_ERR) {
+               if (0 && table_claim_space(tr, t, cnt) == LOG_ERR) {
                        store_unlock();
                        return LOG_ERR;
                }
@@ -1007,7 +1005,7 @@ claim_tab(sql_trans *tr, sql_table *t, s
        assert(isTempTable(t) || s->cs.cleared || ps->cs.bid == s->cs.bid);
 
        /* inserts only write */
-       s->cs.wtime = t->base.wtime = t->s->base.wtime = tr->wtime = tr->wstime;
+       s->cs.wtime = t->base.atime = t->s->base.atime = tr->atime = tr->wstime;
        store_unlock();
        return (size_t)slot;
 }
@@ -1426,8 +1424,12 @@ destroy_segs(segment *s)
 static void
 destroy_segments(segments *s) 
 {
-       if (sql_ref_dec(&s->r) > 0)
+       MT_lock_set(&segs_lock);
+       if (sql_ref_dec(&s->r) > 0) {
+               MT_lock_unset(&segs_lock);
                return;
+       }
+       MT_lock_unset(&segs_lock);
        destroy_segs(s->head);
        _DELETE(s);
 }
@@ -1691,7 +1693,7 @@ minmax( sql_trans *tr )
        for(sn = tr->schemas.set->h; sn && ok == LOG_OK; sn = sn->next) {
                sql_schema *s = sn->data;
                
-               if (!s->base.wtime)
+               if (!s->base.wtime && !s->base.atime)
                        continue;
                if (!isTempSchema(s) && s->tables.set) {
                        node *n;
@@ -1853,7 +1855,9 @@ tr_update_dbat( sql_trans *tr, storage *
 {
        if (fs->cs.cleared) {
                destroy_segments(ts->segs);
+               MT_lock_set(&segs_lock);
                ts->segs = dup_segments(fs->segs);
+               MT_lock_unset(&segs_lock);
                ts->end = ts->segs->end;
                assert(ts->segs->head);
        } else {
@@ -1950,8 +1954,7 @@ update_table(sql_trans *tr, sql_table *f
                sql_column *cc = n->data; // TODO: either stick to to/from 
terminology or old/current terminology
                sql_column *oc = m->data;
 
-               if (ATOMIC_GET(&store_nr_active) == 1 || (cc->base.wtime && 
cc->base.allocated)) {
-                       assert(!cc->base.wtime || oc->base.wtime < 
cc->base.wtime);
+               if (ATOMIC_GET(&store_nr_active) == 1 || ((cc->base.wtime || 
cc->base.atime) && cc->base.allocated)) {
                        if (ATOMIC_GET(&store_nr_active) > 1 && cc->data) { /* 
move delta */
                                sql_delta *b = cc->data;
                                sql_column *oldc = NULL;
@@ -2013,6 +2016,8 @@ update_table(sql_trans *tr, sql_table *f
 
                if (oc->base.rtime < cc->base.rtime)
                        oc->base.rtime = cc->base.rtime;
+               if (oc->base.atime < cc->base.atime)
+                       oc->base.atime = cc->base.atime;
                if (oc->base.wtime < cc->base.wtime)
                        oc->base.wtime = cc->base.wtime;
                if (cc->data) 
@@ -2033,7 +2038,7 @@ update_table(sql_trans *tr, sql_table *f
                                ci->base.allocated = 0;
                                continue;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to