Changeset: cbe8460880f7 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=cbe8460880f7
Modified Files:
        gdk/gdk_bbp.c
        gdk/gdk_logger.c
        gdk/gdk_logger_internals.h
        sql/backends/monet5/sql_gencode.c
        sql/storage/bat/bat_storage.c
        sql/storage/store.c
Branch: unlock
Log Message:

add locks on gdk_logger
make sure we don't unload bats which have more rows than we committed.


diffs (truncated from 626 to 300 lines):

diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -2469,6 +2469,14 @@ decref(bat i, bool logical, bool release
                }
        }
 
+       /* Make sure we do not unload bats which have more rows than marked 
persistend */
+       if (b && BBP_lrefs(i) > 0 && DELTAdirty(b)) {
+               b->batDirtydesc = true;
+               b->theap.dirty = true;
+               if (b->tvheap)
+                       b->tvheap->dirty = true;
+       }
+
        /* we destroy transients asap and unload persistent bats only
         * if they have been made cold or are not dirty */
        if (BBP_refs(i) > 0 ||
@@ -2482,6 +2490,7 @@ decref(bat i, bool logical, bool release
                assert((BBP_status(i) & BBPUNLOADING) == 0);
                TRC_DEBUG(BAT_, "%s set to unloading BAT %d\n", func, i);
                BBP_status_on(i, BBPUNLOADING, func);
+               assert(!b || BBP_lrefs(i) == 0 || !DELTAdirty(b));
                swap = true;
        }
 
@@ -2767,6 +2776,7 @@ BBPfree(BAT *b, const char *calledFrom)
        }
        /* clearing bits can be done without the lock */
        TRC_DEBUG(BAT_, "turn off unloading %d\n", bid);
+       assert(!b || BBP_lrefs(bid) == 0 || !DELTAdirty(b));
        BBP_status_off(bid, BBPUNLOADING, calledFrom);
        BBP_unload_dec();
 
diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c
--- a/gdk/gdk_logger.c
+++ b/gdk/gdk_logger.c
@@ -92,6 +92,18 @@ typedef enum {LOG_OK, LOG_EOF, LOG_ERR} 
 static gdk_return bm_commit(logger *lg);
 static gdk_return tr_grow(trans *tr);
 
+static void
+logger_lock(logger *lg)
+{
+       MT_lock_set(&lg->lock);
+}
+
+static void
+logger_unlock(logger *lg)
+{
+       MT_lock_unset(&lg->lock);
+}
+
 static char
 find_type(logger *lg, int tpe)
 {
@@ -153,6 +165,22 @@ log_find(BAT *b, BAT *d, int val)
        return BUN_NONE;
 }
 
+static log_bid
+internal_find_bat(logger *lg, log_id id)
+{
+       BATiter cni = bat_iterator(lg->catalog_id);
+       BUN p;
+
+       if (BAThash(lg->catalog_id) == GDK_SUCCEED) {
+               HASHloop_int(cni, cni.b->thash, p, &id) {
+                       oid pos = p;
+                       if (BUNfnd(lg->dcatalog, &pos) == BUN_NONE)
+                               return *(log_bid *) Tloc(lg->catalog_bid, p);
+               }
+       }
+       return 0;
+}
+
 static void
 logbat_destroy(BAT *b)
 {
@@ -210,7 +238,7 @@ log_read_clear(logger *lg, trans *tr, lo
 static gdk_return
 la_bat_clear(logger *lg, logaction *la)
 {
-       log_bid bid = logger_find_bat(lg, la->cid);
+       log_bid bid = internal_find_bat(lg, la->cid);
        BAT *b;
 
        if (lg->debug & 1)
@@ -426,7 +454,7 @@ la_bat_update_count(logger *lg, log_id i
 static gdk_return
 la_bat_updates(logger *lg, logaction *la)
 {
-       log_bid bid = logger_find_bat(lg, la->cid);
+       log_bid bid = internal_find_bat(lg, la->cid);
 
        if (bid == 0)
                return GDK_SUCCEED; /* ignore bats no longer in the catalog */
@@ -515,7 +543,7 @@ log_read_destroy(logger *lg, trans *tr, 
 static gdk_return
 la_bat_destroy(logger *lg, logaction *la)
 {
-       log_bid bid = logger_find_bat(lg, la->cid);
+       log_bid bid = internal_find_bat(lg, la->cid);
 
        if (bid && logger_del_bat(lg, bid) != GDK_SUCCEED)
                return GDK_FAIL;
@@ -1703,6 +1731,7 @@ logger_new(int debug, const char *fn, co
                .saved_id = getBBPlogno(),              /* get saved log numer 
from bbp */
                .saved_tid = (int)getBBPtransid(),      /* get saved 
transaction id from bbp */
        };
+       MT_lock_init(&lg->lock, fn);
 
        /* probably open file and check version first, then call call old 
logger code */
        len = snprintf(filename, sizeof(filename), "%s%c%s%c", logdir, DIR_SEP, 
fn, DIR_SEP);
@@ -1737,6 +1766,7 @@ void
 logger_destroy(logger *lg)
 {
        if (lg->catalog_bid) {
+               logger_lock(lg);
                BUN p, q;
                BAT *b = lg->catalog_bid;
 
@@ -1758,6 +1788,7 @@ logger_destroy(logger *lg)
                logbat_destroy(lg->dcatalog);
 
                logbat_destroy(lg->catalog_cnt);
+               logger_unlock(lg);
        }
        GDKfree(lg->fn);
        GDKfree(lg->dir);
@@ -1830,6 +1861,7 @@ logger_flush(logger *lg)
                GDKfree(filename);
        }
        /* we read the full file because skipping is impossible with current 
log format */
+       logger_lock(lg);
        lg->flushing = 1;
        log_return res = logger_read_transaction(lg);
        lg->flushing = 0;
@@ -1843,9 +1875,12 @@ logger_flush(logger *lg)
                }
 
                /* remove old log file */
-               if (res != LOG_ERR)
+               if (res != LOG_ERR) {
+                       logger_unlock(lg);
                        return logger_cleanup(lg, lg->saved_id);
+               }
        }
+       logger_unlock(lg);
        return res == LOG_ERR ? GDK_FAIL : GDK_SUCCEED;
 }
 
@@ -1861,68 +1896,21 @@ logger_changes(logger *lg)
 int
 logger_sequence(logger *lg, int seq, lng *id)
 {
+       logger_lock(lg);
        BUN p = log_find(lg->seqs_id, lg->dseqs, seq);
 
        if (p != BUN_NONE) {
                *id = *(lng *) Tloc(lg->seqs_val, p);
 
+               logger_unlock(lg);
                return 1;
        }
+       logger_unlock(lg);
        return 0;
 }
 
-/*
- * Changes made to the BAT descriptor should be stored in the log
- * files.  Actually, we need to save the descriptor file, perhaps we
- * should simply introduce a versioning scheme.
- */
-gdk_return
-log_bat_persists(logger *lg, BAT *b, int id)
-{
-       char ta = find_type(lg, b->ttype);
-       logformat l;
-
-       if (logger_add_bat(lg, b, id) != GDK_SUCCEED)
-               return GDK_FAIL;
-
-       l.flag = LOG_CREATE;
-       l.id = id;
-       if (!lg->inmemory && !LOG_DISABLED(lg)) {
-               if (log_write_format(lg, &l) != GDK_SUCCEED ||
-                   mnstr_write(lg->output_log, &ta, 1, 1) != 1) 
-                       return GDK_FAIL;
-       }
-       if (lg->debug & 1)
-               fprintf(stderr, "#persists id (%d) bat (%d)\n", id, 
b->batCacheid);
-       if (lg->inmemory || LOG_DISABLED(lg))
-               return GDK_SUCCEED;
-       return log_bat(lg, b, id, 0, BATcount(b));
-}
-
-gdk_return
-log_bat_transient(logger *lg, int id)
-{
-       log_bid bid = logger_find_bat(lg, id);
-       logformat l;
-
-       l.flag = LOG_DESTROY;
-       l.id = id;
-
-       if (lg->inmemory || LOG_DISABLED(lg))
-               return GDK_SUCCEED;
-
-       if (log_write_format(lg, &l) != GDK_SUCCEED) {
-               TRC_CRITICAL(GDK, "write failed\n");
-               return GDK_FAIL;
-       }
-       if (lg->debug & 1)
-               fprintf(stderr, "#Logged destroyed bat (%d)\n", id);
-
-       return logger_del_bat(lg, bid);
-}
-
 static gdk_return
-_log_bat(logger *lg, BAT *b, log_id id, lng offset, lng cnt, int sliced)
+internal_log_bat(logger *lg, BAT *b, log_id id, lng offset, lng cnt, int 
sliced)
 {
        char tpe = find_type(lg, b->ttype);
        gdk_return ok = GDK_SUCCEED;
@@ -1979,23 +1967,94 @@ static gdk_return
        return ok;
 }
 
+/*
+ * Changes made to the BAT descriptor should be stored in the log
+ * files.  Actually, we need to save the descriptor file, perhaps we
+ * should simply introduce a versioning scheme.
+ */
+gdk_return
+log_bat_persists(logger *lg, BAT *b, int id)
+{
+       logger_lock(lg);
+       char ta = find_type(lg, b->ttype);
+       logformat l;
+
+       if (logger_add_bat(lg, b, id) != GDK_SUCCEED) {
+               logger_unlock(lg);
+               return GDK_FAIL;
+       }
+
+       l.flag = LOG_CREATE;
+       l.id = id;
+       if (!lg->inmemory && !LOG_DISABLED(lg)) {
+               if (log_write_format(lg, &l) != GDK_SUCCEED ||
+                   mnstr_write(lg->output_log, &ta, 1, 1) != 1) {
+                       logger_unlock(lg);
+                       return GDK_FAIL;
+               }
+       }
+       if (lg->debug & 1)
+               fprintf(stderr, "#persists id (%d) bat (%d)\n", id, 
b->batCacheid);
+       if (lg->inmemory || LOG_DISABLED(lg)) {
+               logger_unlock(lg);
+               return GDK_SUCCEED;
+       }
+       gdk_return r = internal_log_bat(lg, b, id, 0, BATcount(b), 0);
+       logger_unlock(lg);
+       return r;
+}
+
+gdk_return
+log_bat_transient(logger *lg, int id)
+{
+       logger_lock(lg);
+       log_bid bid = internal_find_bat(lg, id);
+       logformat l;
+
+       l.flag = LOG_DESTROY;
+       l.id = id;
+
+       if (lg->inmemory || LOG_DISABLED(lg)) {
+               logger_unlock(lg);
+               return GDK_SUCCEED;
+       }
+
+       if (log_write_format(lg, &l) != GDK_SUCCEED) {
+               TRC_CRITICAL(GDK, "write failed\n");
+               logger_unlock(lg);
+               return GDK_FAIL;
+       }
+       if (lg->debug & 1)
+               fprintf(stderr, "#Logged destroyed bat (%d)\n", id);
+       gdk_return r =  logger_del_bat(lg, bid);
+       logger_unlock(lg);
+       return r;
+}
+
 gdk_return
 log_bat(logger *lg, BAT *b, log_id id, lng offset, lng cnt)
 {
-       return _log_bat(lg, b, id, offset, cnt, 0);
+       logger_lock(lg);
+       gdk_return r = internal_log_bat(lg, b, id, offset, cnt, 0);
+       logger_unlock(lg);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to