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