/* * The routines @emph{ALIGN_synced} and @emph{ALIGN_ordered} allow to * simply query the alignment status of the two head columns of two * BATs. */ int ALIGNsynced(BAT *b1, BAT *b2) { BATcheck(b1, "ALIGNsynced: bat 1 required", 0); BATcheck(b2, "ALIGNsynced: bat 2 required", 0); /* first try to prove head columns are not in sync */ if (BATcount(b1) != BATcount(b2)) return 0; if (ATOMtype(BAThtype(b1)) != ATOMtype(BAThtype(b2))) return 0; if (BAThvoid(b1) && BAThvoid(b2)) return (b1->hseqbase == b2->hseqbase); /* then try that they are */ if (b1->batCacheid == b2->batCacheid) return 1; /* same bat. trivial case */ if (BATcount(b1) == 0) return 1; /* empty bats of same type. trivial case */ if (b1->halign && b1->halign == b2->halign) return 1; /* columns marked as equal by algorithmics */ if (VIEWparentcol(b1) && ALIGNsynced(BBPcache(VIEWhparent(b1)), b2)) return 1; /* view on same bat --- left recursive def.. */ if (VIEWparentcol(b2) && ALIGNsynced(b1, BBPcache(VIEWhparent(b2)))) return 1; /* view on same bat --- right recursive def.. */ return 0; /* we simply don't know */ }
void ALIGNsetH(BAT *b1, BAT *b2) { ssize_t diff; if (b1 == NULL || b2 == NULL) return; diff = (ssize_t) (BUNfirst(b1) - BUNfirst(b2)); if (b2->halign == 0) { b2->halign = OIDnew(1); b2->batDirtydesc = TRUE; } if (BAThvoid(b2)) { /* b2 is either dense or has a void(nil) head */ if (b1->htype != TYPE_void) b1->hdense = TRUE; else if (b2->hseqbase == oid_nil) b1->H->nonil = FALSE; BATseqbase(b1, b2->hseqbase); } else if (b1->htype != TYPE_void) { /* b2 is not dense, so set b1 not dense */ b1->hdense = FALSE; BATseqbase(b1, oid_nil); b1->H->nonil = b2->H->nonil; } else if (BAThkey(b2)) BATseqbase(b1, 0); BATkey(b1, BAThkey(b2)); b1->hsorted = BAThordered(b2); b1->hrevsorted = BAThrevordered(b2); b1->halign = b2->halign; b1->batDirtydesc = TRUE; b1->H->norevsorted = (BUN) (b2->H->norevsorted + diff); b1->H->nokey[0] = (BUN) (b2->H->nokey[0] + diff); b1->H->nokey[1] = (BUN) (b2->H->nokey[1] + diff); b1->H->nosorted = (BUN) (b2->H->nosorted + diff); b1->H->nodense = (BUN) (b2->H->nodense + diff); }
str MKEYbathash(bat *res, const bat *bid) { BAT *b, *dst; wrd *r; BUN n; if ((b = BATdescriptor(*bid)) == NULL) throw(SQL, "mkey.bathash", RUNTIME_OBJECT_MISSING); assert(BAThvoid(b) || BAThrestricted(b)); n = BATcount(b); dst = BATnew(TYPE_void, TYPE_wrd, n, TRANSIENT); if (dst == NULL) { BBPunfix(b->batCacheid); throw(SQL, "mkey.bathash", MAL_MALLOC_FAIL); } BATseqbase(dst, b->hseqbase); BATsetcount(dst, n); r = (wrd *) Tloc(dst, BUNfirst(dst)); switch (ATOMstorage(b->ttype)) { case TYPE_void: { oid o = b->tseqbase; if (o == oid_nil) while (n-- > 0) *r++ = wrd_nil; else while (n-- > 0) *r++ = (wrd) o++; break; } case TYPE_bte: { bte *v = (bte *) Tloc(b, BUNfirst(b)); while (n-- > 0) { *r++ = MKEYHASH_bte(v); v++; } break; } case TYPE_sht: { sht *v = (sht *) Tloc(b, BUNfirst(b)); while (n-- > 0) { *r++ = MKEYHASH_sht(v); v++; } break; } case TYPE_int: case TYPE_flt: { int *v = (int *) Tloc(b, BUNfirst(b)); while (n-- > 0) { *r++ = MKEYHASH_int(v); v++; } break; } case TYPE_lng: case TYPE_dbl: { lng *v = (lng *) Tloc(b, BUNfirst(b)); while (n-- > 0) { *r++ = MKEYHASH_lng(v); v++; } break; } #ifdef HAVE_HGE case TYPE_hge: { hge *v = (hge *) Tloc(b, BUNfirst(b)); while (n-- > 0) { *r++ = MKEYHASH_hge(v); v++; } break; } #endif default: { BATiter bi = bat_iterator(b); BUN (*hash)(const void *) = BATatoms[b->ttype].atomHash; int (*cmp)(const void *, const void *) = ATOMcompare(b->ttype); void *nil = ATOMnilptr(b->ttype); BUN i; const void *v; BATloop(b, i, n) { v = BUNtail(bi, i); if ((*cmp)(v, nil) == 0) *r++ = wrd_nil; else *r++ = (wrd) (*hash)(v); } break; } }