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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list