Changeset: 90d68726176c for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=90d68726176c Modified Files: gdk/gdk_cand.c Branch: candidate-exceptions Log Message:
Use candidate iterators for candidate functions. diffs (truncated from 641 to 300 lines): diff --git a/gdk/gdk_cand.c b/gdk/gdk_cand.c --- a/gdk/gdk_cand.c +++ b/gdk/gdk_cand.c @@ -13,10 +13,10 @@ /* create a new, dense candidate list with values from `first' up to, * but not including, `last' */ -static BAT * +static inline BAT * newdensecand(oid first, oid last) { - if (last < first) + if (last <= first) first = last = 0; /* empty range */ return BATdense(0, first, last - first); } @@ -30,113 +30,113 @@ BAT * BATmergecand(BAT *a, BAT *b) { BAT *bn; - const oid *restrict ap, *restrict bp, *ape, *bpe; oid *restrict p, i; - oid af, al, bf, bl; - bit ad, bd; + struct canditer cia, cib; BATcheck(a, "BATmergecand", NULL); BATcheck(b, "BATmergecand", NULL); - assert(ATOMtype(a->ttype) == TYPE_oid); - assert(ATOMtype(b->ttype) == TYPE_oid); - assert(BATcount(a) <= 1 || a->tsorted); - assert(BATcount(b) <= 1 || b->tsorted); - assert(BATcount(a) <= 1 || a->tkey); - assert(BATcount(b) <= 1 || b->tkey); - assert(a->tnonil); - assert(b->tnonil); + + canditer_init(&cia, NULL, a); + canditer_init(&cib, NULL, b); /* we can return a if b is empty (and v.v.) */ - if (BATcount(a) == 0) { - return COLcopy(b, b->ttype, false, TRANSIENT); + if (cia.ncand == 0) { + return canditer_slice(&cib, 0, cib.ncand); } - if (BATcount(b) == 0) { - return COLcopy(a, a->ttype, false, TRANSIENT); + if (cib.ncand == 0) { + return canditer_slice(&cia, 0, cia.ncand); } /* we can return a if a fully covers b (and v.v) */ - af = BUNtoid(a, 0); - bf = BUNtoid(b, 0); - al = BUNtoid(a, BUNlast(a) - 1); - bl = BUNtoid(b, BUNlast(b) - 1); - ad = (af + BATcount(a) - 1 == al); /* i.e., dense */ - bd = (bf + BATcount(b) - 1 == bl); /* i.e., dense */ - if (ad && bd) { + if (cia.tpe == cand_dense && cib.tpe == cand_dense) { /* both are dense */ - if (af <= bf && bf <= al + 1) { + if (cia.seq <= cib.seq && cib.seq <= cia.seq + cia.ncand) { /* partial overlap starting with a, or b is * smack bang after a */ - return newdensecand(af, al < bl ? bl + 1 : al + 1); + return newdensecand(cia.seq, cia.seq + cia.ncand < cib.seq + cib.ncand ? cib.seq + cib.ncand : cia.seq + cia.ncand); } - if (bf <= af && af <= bl + 1) { + if (cib.seq <= cia.seq && cia.seq <= cib.seq + cib.ncand) { /* partial overlap starting with b, or a is * smack bang after b */ - return newdensecand(bf, al < bl ? bl + 1 : al + 1); + return newdensecand(cib.seq, cia.seq + cia.ncand < cib.seq + cib.ncand ? cib.seq + cib.ncand : cia.seq + cia.ncand); } } - if (ad && af <= bf && al >= bl) { - return newdensecand(af, al + 1); + if (cia.tpe == cand_dense + && cia.seq <= cib.seq + && canditer_last(&cia) >= canditer_last(&cib)) { + return canditer_slice(&cia, 0, cia.ncand); } - if (bd && bf <= af && bl >= al) { - return newdensecand(bf, bl + 1); + if (cib.tpe == cand_dense + && cib.seq <= cia.seq + && canditer_last(&cib) >= canditer_last(&cia)) { + return canditer_slice(&cib, 0, cib.ncand); } - bn = COLnew(0, TYPE_oid, BATcount(a) + BATcount(b), TRANSIENT); + bn = COLnew(0, TYPE_oid, cia.ncand + cib.ncand, TRANSIENT); if (bn == NULL) return NULL; p = (oid *) Tloc(bn, 0); - if (BATtdense(a) && BATtdense(b)) { + if (cia.tpe == cand_dense && cib.tpe == cand_dense) { /* both lists are dense */ - if (a->tseqbase > b->tseqbase) { - BAT *t = a; - - a = b; - b = t; + if (cia.seq > cib.seq) { + struct canditer ci; + ci = cia; + cia = cib; + cib = ci; } - /* a->tseqbase <= b->tseqbase */ - for (i = a->tseqbase; i < a->tseqbase + BATcount(a); i++) + /* cia completely before cib */ + assert(cia.seq + cia.ncand < cib.seq); + for (i = cia.seq; i < cia.seq + cia.ncand; i++) *p++ = i; - for (i = MAX(b->tseqbase, i); - i < b->tseqbase + BATcount(b); - i++) + /* there is a gap */ + for (i = cib.seq; i < cib.seq + cib.ncand; i++) *p++ = i; - } else if (BATtdense(a) || BATtdense(b)) { - if (BATtdense(b)) { - BAT *t = a; - - a = b; - b = t; + } else if (cia.tpe == cand_dense || cib.tpe == cand_dense) { + if (cib.tpe == cand_dense) { + struct canditer ci; + ci = cia; + cia = cib; + cib = ci; } - /* only a is dense */ - bp = (const oid *) Tloc(b, 0); - bpe = bp + BATcount(b); - while (bp < bpe && *bp < a->tseqbase) - *p++ = *bp++; - for (i = a->tseqbase; i < a->tseqbase + BATcount(a); i++) + /* only cia is dense */ + + /* copy part of cib that's before the start of cia */ + while (canditer_peek(&cib) < cia.seq) { + *p++ = canditer_next(&cib); + } + /* copy all of cia */ + for (i = cia.seq; i < cia.seq + cia.ncand; i++) *p++ = i; - while (bp < bpe && *bp < i) - bp++; - while (bp < bpe) - *p++ = *bp++; + /* skip over part of cib that overlaps with cia */ + canditer_setidx(&cib, canditer_search(&cib, cia.seq + cia.ncand, true)); + /* copy rest of cib */ + while (cib.next < cib.ncand) { + *p++ = canditer_next(&cib); + } } else { /* a and b are both not dense */ - ap = (const oid *) Tloc(a, 0); - ape = ap + BATcount(a); - bp = (const oid *) Tloc(b, 0); - bpe = bp + BATcount(b); - while (ap < ape && bp < bpe) { - if (*ap < *bp) - *p++ = *ap++; - else if (*ap > *bp) - *p++ = *bp++; - else { - *p++ = *ap++; - bp++; + oid ao = canditer_next(&cia); + oid bo = canditer_next(&cib); + while (!is_oid_nil(ao) && !is_oid_nil(bo)) { + if (ao < bo) { + *p++ = ao; + ao = canditer_next(&cia); + } else if (bo < ao) { + *p++ = bo; + bo = canditer_next(&cib); + } else { + *p++ = ao; + ao = canditer_next(&cia); + bo = canditer_next(&cib); } } - while (ap < ape) - *p++ = *ap++; - while (bp < bpe) - *p++ = *bp++; + while (!is_oid_nil(ao)) { + *p++ = ao; + ao = canditer_next(&cia); + } + while (!is_oid_nil(bo)) { + *p++ = bo; + bo = canditer_next(&cib); + } } /* properties */ @@ -158,67 +158,55 @@ BAT * BATintersectcand(BAT *a, BAT *b) { BAT *bn; - const oid *restrict ap, *restrict bp, *ape, *bpe; oid *restrict p; - oid af, al, bf, bl; + struct canditer cia, cib; BATcheck(a, "BATintersectcand", NULL); BATcheck(b, "BATintersectcand", NULL); - assert(ATOMtype(a->ttype) == TYPE_oid); - assert(ATOMtype(b->ttype) == TYPE_oid); - assert(a->tsorted); - assert(b->tsorted); - assert(a->tkey); - assert(b->tkey); - assert(a->tnonil); - assert(b->tnonil); - if (BATcount(a) == 0 || BATcount(b) == 0) { - return newdensecand(0, 0); + canditer_init(&cia, NULL, a); + canditer_init(&cib, NULL, b); + + if (cia.ncand == 0 || cib.ncand == 0) { + return BATdense(0, 0, 0); } - af = BUNtoid(a, 0); - bf = BUNtoid(b, 0); - al = BUNtoid(a, BUNlast(a) - 1); - bl = BUNtoid(b, BUNlast(b) - 1); - - if ((af + BATcount(a) - 1 == al) && (bf + BATcount(b) - 1 == bl)) { + if (cia.tpe == cand_dense && cib.tpe == cand_dense) { /* both lists are dense */ - return newdensecand(MAX(af, bf), MIN(al, bl) + 1); + return newdensecand(MAX(cia.seq, cib.seq), MIN(cia.seq + cia.ncand, cib.seq + cib.ncand)); } - bn = COLnew(0, TYPE_oid, MIN(BATcount(a), BATcount(b)), TRANSIENT); + bn = COLnew(0, TYPE_oid, MIN(cia.ncand, cib.ncand), TRANSIENT); if (bn == NULL) return NULL; p = (oid *) Tloc(bn, 0); - if (BATtdense(a) || BATtdense(b)) { - if (BATtdense(b)) { - BAT *t = a; - - a = b; - b = t; + if (cia.tpe == cand_dense || cib.tpe == cand_dense) { + if (cib.tpe == cand_dense) { + struct canditer ci; + ci = cia; + cia = cib; + cib = ci; } - /* only a is dense */ - bp = (const oid *) Tloc(b, 0); - bpe = bp + BATcount(b); - while (bp < bpe && *bp < a->tseqbase) - bp++; - while (bp < bpe && *bp < a->tseqbase + BATcount(a)) - *p++ = *bp++; + /* only cia is dense */ + + /* search for first value in cib that is contained in cia */ + canditer_setidx(&cib, canditer_search(&cib, cia.seq, true)); + oid bo; + while (!is_oid_nil(bo = canditer_next(&cib)) && bo < cia.seq + cia.ncand) + *p++ = bo; } else { /* a and b are both not dense */ - ap = (const oid *) Tloc(a, 0); - ape = ap + BATcount(a); - bp = (const oid *) Tloc(b, 0); - bpe = bp + BATcount(b); - while (ap < ape && bp < bpe) { - if (*ap < *bp) - ap++; - else if (*ap > *bp) - bp++; + oid ao = canditer_next(&cia); + oid bo = canditer_next(&cib); + while (!is_oid_nil(ao) && !is_oid_nil(bo)) { + if (ao < bo) + ao = canditer_next(&cia); + else if (bo < ao) + bo = canditer_next(&cib); else { - *p++ = *ap++; - bp++; + *p++ = ao; + ao = canditer_next(&cia); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list