Changeset: 5eed5e4abacc for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=5eed5e4abacc
Modified Files:
        sql/storage/bat/bat_table.c
        sql/storage/sql_storage.h
        sql/storage/store.c
Branch: Jul2015
Log Message:

optimized hash based lookup of column_row and improved loading of
table/columns functions/arguments. Improves both single value
lookup as needed for the statistics table (optimizer) and startup of
the server.


diffs (truncated from 406 to 300 lines):

diff --git a/sql/storage/bat/bat_table.c b/sql/storage/bat/bat_table.c
--- a/sql/storage/bat/bat_table.c
+++ b/sql/storage/bat/bat_table.c
@@ -143,23 +143,42 @@ column_find_row(sql_trans *tr, sql_colum
        va_list va;
        BAT *b = NULL, *s = NULL, *r = NULL;
        oid rid = oid_nil;
+       sql_column *n = NULL;
 
        s = delta_cands(tr, c->t);
        va_start(va, value);
        b = full_column(tr, c);
+       if ((n = va_arg(va, sql_column *)) == NULL) {
+               if (b->T->hash || BAThash(b, 0) == GDK_SUCCEED) {
+                       BATiter cni = bat_iterator(b);
+                       BUN p;
+
+                       HASHloop(cni, cni.b->T->hash, p, value) {
+                               oid pos = p;
+
+                               if (s && BUNfnd(s, &pos) != BUN_NONE) {
+                                       rid = p;
+                                       break;
+                               }
+                       }
+               }
+               bat_destroy(s);
+               return rid;
+       }
        r = BATsubselect(b, s, value, NULL, 1, 0, 0);
        bat_destroy(s);
        s = r;
        full_destroy(c, b);
-       while ((c = va_arg(va, sql_column *)) != NULL) {
+       do {
                value = va_arg(va, void *);
+               c = n;
 
                b = full_column(tr, c);
                r = BATsubselect(b, s, value, NULL, 1, 0, 0);
                bat_destroy(s);
                s = r;
                full_destroy(c, b);
-       }
+       } while ((n = va_arg(va, sql_column *)) != NULL); 
        va_end(va);
        if (BATcount(s) == 1) {
                BATiter ri = bat_iterator(s);
@@ -367,18 +386,135 @@ rids_destroy(rids *r)
        _DELETE(r);
 }
 
+static int
+rids_empty(rids *r )
+{
+       BAT *b = r->data;
+       return BATcount(b) <= 0;
+}
+
 static rids *
 rids_join(sql_trans *tr, rids *l, sql_column *lc, rids *r, sql_column *rc)
 {
-       BAT *lcb, *rcb, *s = NULL;
+       BAT *lcb, *rcb, *s = NULL, *d = NULL;
        
        lcb = full_column(tr, lc);
        rcb = full_column(tr, rc);
-       BATsubjoin(&s, NULL, lcb, rcb, l->data, r->data, FALSE, BATcount(lcb));
+       BATsubjoin(&s, &d, lcb, rcb, l->data, r->data, FALSE, BATcount(lcb));
        bat_destroy(l->data);
+       bat_destroy(d);
        l->data = s;
+       full_destroy(lc, lcb);
+       full_destroy(rc, rcb);
+       return l;
+}
+
+static subrids *
+subrids_create(sql_trans *tr, rids *t1, sql_column *rc, sql_column *lc, 
sql_column *obc)
+{
+       /* join t1.rc with lc order by obc */
+       subrids *r = ZNEW(subrids);
+       BAT *lcb, *rcb, *s, *obb, *d = NULL, *o, *g, *ids, *rids = NULL;
+       
+       lcb = full_column(tr, lc);
+       rcb = full_column(tr, rc);
+
+       s = delta_cands(tr, lc->t);
+       BATsubjoin(&rids, &d, lcb, rcb, s, t1->data, FALSE, BATcount(lcb));
+       bat_destroy(d);
+       bat_destroy(s);
+       full_destroy(rc, rcb);
+
+       s = BATproject(rids, lcb);
+       full_destroy(lc, lcb);
+       lcb = s;
+
+       obb = full_column(tr, obc);
+       s = BATproject(rids, obb);
+       full_destroy(obc, obb);
+       obb = s;
+
+       /* need id, obc */
+       ids = o = g = NULL;
+       BATsubsort(&ids, &o, &g, lcb, NULL, NULL, 0, 0);
        bat_destroy(lcb);
+
+       s = NULL;
+       BATsubsort(NULL, &s, NULL, obb, o, g, 0, 0);
+       bat_destroy(obb);
+       bat_destroy(o);
+       bat_destroy(g);
+
+       o = BATproject(s, rids);
+       bat_destroy(rids);
+       rids = o;
+
+       assert(ids->ttype == TYPE_int && rids->ttype == TYPE_oid);
+       r->id = r->pos = 0;
+       r->ids = ids;
+       r->rids = rids;
+       return r;
+}
+
+static oid
+subrids_next(subrids *r)
+{
+       if (r->pos < BATcount((BAT *) r->ids)) {
+               BATiter ii = bat_iterator((BAT *) r->ids);
+               BATiter ri = bat_iterator((BAT *) r->rids);
+               int id = *(int*)BUNtail(ii, r->pos);
+               if (id == r->id)
+                       return *(oid*)BUNtail(ri, r->pos++);
+       }
+       return oid_nil;
+}
+
+static sqlid
+subrids_nextid(subrids *r)
+{
+       if (r->pos < BATcount((BAT *) r->ids)) {
+               BATiter ii = bat_iterator((BAT *) r->ids);
+               r->id = *(int*)BUNtail(ii, r->pos);
+               return r->id;
+       }
+       return -1;
+}
+
+static void
+subrids_destroy(subrids *r )
+{
+       if (r->ids)
+               bat_destroy(r->ids);
+       if (r->rids)
+               bat_destroy(r->rids);
+       _DELETE(r);
+}
+
+/* get the non - join results */
+static rids *
+rids_diff(sql_trans *tr, rids *l, sql_column *lc, subrids *r, sql_column *rc )
+{
+       BAT *lcb = full_column(tr, lc), *s, *d, *rids;
+       BAT *rcb = full_column(tr, rc);
+
+       s = BATproject(r->rids, rcb);
+       full_destroy(rc, rcb);
+       rcb = s;
+
+       s = BATproject(l->data, lcb);
+
+       d = BATkdiff(BATmirror(s), BATmirror(rcb));
+       s = BATmirror(BATmark(d, 0));
+       bat_destroy(d);
        bat_destroy(rcb);
+
+       BATsubjoin(&rids, &d, lcb, s, NULL, NULL, FALSE, BATcount(s));
+       bat_destroy(d);
+       full_destroy(lc, lcb);
+       bat_destroy(s);
+
+       bat_destroy(l->data);
+       l->data = rids;
        return l;
 }
 
@@ -397,5 +533,12 @@ bat_table_init( table_functions *tf )
        tf->rids_join = rids_join;
        tf->rids_next = rids_next;
        tf->rids_destroy = rids_destroy;
+       tf->rids_empty = rids_empty;
+
+       tf->subrids_create = subrids_create;
+       tf->subrids_next = subrids_next;
+       tf->subrids_nextid = subrids_nextid;
+       tf->subrids_destroy = subrids_destroy;
+       tf->rids_diff = rids_diff;
        return LOG_OK;
 }
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
@@ -49,9 +49,15 @@ typedef int (*table_delete_fptr)(sql_tra
 typedef struct rids {
        BUN cur;
        void *data;
-       BUN l,h;        /* subselect using slices */
 } rids;
 
+typedef struct subrids {
+       BUN pos;
+       int id;
+       void *ids;
+       void *rids;
+} subrids;
+
 /* returns table rids, for the given select ranges */
 typedef rids *(*rids_select_fptr)( sql_trans *tr, sql_column *key, void 
*key_value_low, void *key_value_high, ...);
 
@@ -59,12 +65,24 @@ typedef rids *(*rids_select_fptr)( sql_t
 typedef rids *(*rids_orderby_fptr)( sql_trans *tr, rids *r, sql_column 
*orderby_col);
 
 typedef rids *(*rids_join_fptr)( sql_trans *tr, rids *l, sql_column *lc, rids 
*r, sql_column *rc);
+typedef rids *(*rids_diff_fptr)( sql_trans *tr, rids *l, sql_column *lc, 
subrids *r, sql_column *rc);
 
 /* return table rids from result of table_select, return (-1) when done */
 typedef oid (*rids_next_fptr)(rids *r);
 
 /* clean up the resources taken by the result of table_select */
 typedef void (*rids_destroy_fptr)(rids *r);
+typedef int (*rids_empty_fptr)(rids *r);
+
+typedef subrids *(*subrids_create_fptr)( sql_trans *tr, rids *l, sql_column 
*jc1, sql_column *jc2, sql_column *obc);
+
+/* return table rids from result of table_select, return (-1) when done */
+typedef oid (*subrids_next_fptr)(subrids *r);
+typedef sqlid (*subrids_nextid_fptr)(subrids *r);
+
+/* clean up the resources taken by the result of table_select */
+typedef void (*subrids_destroy_fptr)(subrids *r);
+
 
 typedef struct table_functions {
        column_find_row_fptr column_find_row;
@@ -78,6 +96,13 @@ typedef struct table_functions {
        rids_join_fptr rids_join;
        rids_next_fptr rids_next;
        rids_destroy_fptr rids_destroy;
+       rids_empty_fptr rids_empty;
+
+       subrids_create_fptr subrids_create;
+       subrids_next_fptr subrids_next;
+       subrids_nextid_fptr subrids_nextid;
+       subrids_destroy_fptr subrids_destroy;
+       rids_diff_fptr rids_diff;
 } table_functions; 
 
 extern table_functions table_funcs;
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -550,24 +550,21 @@ load_tables_of_tables(sql_trans *tr, sql
 }
 
 static sql_table *
-load_table(sql_trans *tr, sql_schema *s, oid rid)
+load_table(sql_trans *tr, sql_schema *s, sqlid tid, subrids *nrs)
 {
        void *v;
        sql_table *t = SA_ZNEW(tr->sa, sql_table);
        sql_schema *syss = find_sql_schema(tr, "sys");
        sql_table *tables = find_sql_table(syss, "_tables");
-       sql_table *columns = find_sql_table(syss, "_columns");
        sql_table *idxs = find_sql_table(syss, "idxs");
        sql_table *keys = find_sql_table(syss, "keys");
        sql_table *triggers = find_sql_table(syss, "triggers");
        char *query;
-       sql_column *column_table_id, *column_number, *idx_table_id;
-       sql_column *key_table_id, *trigger_table_id;
-       sqlid tid;
+       sql_column *idx_table_id, *key_table_id, *trigger_table_id;
+       oid rid;
        rids *rs;
 
-       v = table_funcs.column_find_value(tr, find_sql_column(tables, "id"), 
rid);
-       tid = *(sqlid *)v;                      _DELETE(v);     
+       rid = table_funcs.column_find_row(tr, find_sql_column(tables, "id"), 
&tid, NULL);
        v = table_funcs.column_find_value(tr, find_sql_column(tables, "name"), 
rid);
        base_init(tr->sa, &t->base, tid, TR_OLD, v);    _DELETE(v);
        v = table_funcs.column_find_value(tr, find_sql_column(tables, "query"), 
rid);
@@ -614,14 +611,8 @@ load_table(sql_trans *tr, sql_schema *s,
        if (bs_debug)
                fprintf(stderr, "#\tload table %s\n", t->base.name);
 
-       column_table_id = find_sql_column(columns, "table_id");
-       column_number = find_sql_column(columns, "number");
-       rs = table_funcs.rids_select(tr, column_table_id, &t->base.id, 
&t->base.id, NULL);
-       rs = table_funcs.rids_orderby(tr, rs, column_number); 
-       
-       for(rid = table_funcs.rids_next(rs); rid != oid_nil; rid = 
table_funcs.rids_next(rs)) 
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to