📄 gdk_bat.mx
字号:
if (b->htype != TYPE_void) { int cmp = 0; if (b->hsorted & 1) { ptr prv = BUNhead(b, p - bunsize); cmp = atom_CMP(h, prv, b->htype); if (cmp < 0) { b->H->nosorted = i; b->hsorted = FALSE; } else if (cmp && b->hdense && *(oid *) h != 1 + *(oid *) prv) { b->H->nodense = i; b->hdense = FALSE; } /* as nil < any, we only need to * check on second BUNins if the * first was nil */ if (i == 2 && cmp > 0) { /* StM: i==1 ? */ int ht = b->htype; cmp = atom_CMP(prv, ATOMnilptr(ht), ht); if (cmp == 0) { b->H->nosorted = 1; b->hsorted = FALSE; } } } else if (b->hsorted == (bit)GDK_SORTED_REV) { ptr prv = BUNhead(b, p - bunsize); cmp = atom_CMP(h, prv, b->htype); if (cmp > 0) { b->H->nosorted_rev = i; b->hsorted = FALSE; } } if (b->hkey == TRUE && cmp <= 0) { b->H->nokey[0] = i - 1; b->H->nokey[1] = i; b->hkey = bm->tkey = b->hdense = FALSE; } } if (b->ttype != TYPE_void) { int cmp = 0; if (b->tsorted & 1) { ptr prv = BUNtail(b, p - bunsize); cmp = atom_CMP(t, prv, b->ttype); if (cmp < 0) { b->T->nosorted = i; b->tsorted = FALSE; } else if (cmp && b->tdense && *(oid *) t != 1 + *(oid *) prv) { b->T->nodense = i; b->tdense = FALSE; } /* as nil < any, we only need to * check on second BUNins if the * first was nil */ if (i == 2 && cmp > 0) { /* StM: i==1 ? */ int tt = b->ttype; cmp = atom_CMP(prv, ATOMnilptr(tt), tt); if (cmp == 0) { b->T->nosorted = 1; b->tsorted = FALSE; } } } else if (b->tsorted == (bit)GDK_SORTED_REV) { ptr prv = BUNtail(b, p - bunsize); cmp = atom_CMP(t, prv, b->ttype); if (cmp > 0) { b->T->nosorted_rev = i; b->tsorted = FALSE; } } if (b->tkey == TRUE && cmp <= 0) { b->T->nokey[0] = i - 1; b->T->nokey[1] = i; b->tkey = bm->hkey = b->tdense = FALSE; } } } else { if (b->htype == TYPE_oid) { b->hkey = bm->tkey |= b->hdense = TRUE; b->hseqbase = bm->tseqbase = *(oid *) h; } else if (b->htype) { b->hkey = bm->tkey |= TRUE; } if (b->ttype == TYPE_oid) { b->tkey = bm->hkey |= b->tdense = TRUE; b->tseqbase = bm->hseqbase = *(oid *) t; } else if (b->ttype) { b->tkey = bm->hkey |= TRUE; } } if (!countonly) { bunfastins(b, h, t); } else { b->batBuns->free += 1; BATsetcount(b, b->batCount+1); } /* first adapt the hashes; then the user-defined accelerators. * REASON: some accelerator updates (qsignature) use the hashes! */ if (b->hhash) { HASHins(b, (hash_t) i, h); if (hsize && hsize != b->hheap->size) HEAPwarm(b->hheap); } if (b->thash) { HASHins(bm, (hash_t) i, t); if (tsize && tsize != b->theap->size) HEAPwarm(b->theap); } } return b; bunins_failed: return NULL;}oid MAXoid(BAT *i){ oid o = i->hseqbase-1; if (BATcount(i)) o = *(oid *) BUNhead(i, BUNlast(i) - BUNsize(i)); if (!BAThordered(i)) { BUN r, s; int d; BATloopFast(i, r, s, d) { oid v = *(oid *) BUNhead(i, r); if (v > o) o = v; } } return o;}@+ BUNappendThe BUNappend function can be used to add a single value to void and oid headed bats. The new head value will be a unique number, (max(bat)+1). @cBAT *BUNappend(BAT *b, ptr t, bit force){ size_t i; BUN p; BAT *bm; ptr h = NULL; oid id = 0; int countonly; size_t hsize = 0, tsize = 0; if (b->hhash && b->hheap) hsize = b->hheap->size; if (b->thash && b->theap) tsize = b->theap->size; BATcheck(b, "BUNappend"); bm = BBP_cache(-b->batCacheid); countonly = (b->htype == TYPE_void && b->ttype == TYPE_void); if (b->htype != TYPE_void && b->htype != TYPE_oid) { GDKerror("BUNappend: can only append to void and oid bats\n"); return NULL; } ALIGNapp(b, "BUNappend", force); b->batDirty = 1; p = BUNlast(b); /* insert at end */ i = BUNindex(b, p); if ((b->tkey & BOUND2BTRUE) && BUNfnd(bm, t)) { return b; } if (p > b->batFirst) { unsigned int bunsize = BUNsize(b); if (b->htype == TYPE_oid) { h = &id; id = MAXoid(b)+1; } if (b->ttype != TYPE_void) { int cmp = 0; if (b->tsorted & 1) { ptr prv = BUNtail(b, p - bunsize); cmp = atom_CMP(t, prv, b->ttype); if (cmp < 0) { b->T->nosorted = i; b->tsorted = FALSE; } else if (cmp && b->tdense && *(oid *) t != 1 + *(oid *) prv) { b->T->nodense = i; b->tdense = FALSE; } /* as nil < any, we only need to * check on second BUNins if the * first was nil */ if (i == 2 && cmp > 0) { /* StM: i==1 ? */ int tt = b->ttype; cmp = atom_CMP(prv, ATOMnilptr(tt), tt); if (cmp == 0) { b->T->nosorted = 1; b->tsorted = FALSE; } } } else if (b->tsorted == (bit)GDK_SORTED_REV) { ptr prv = BUNtail(b, p - bunsize); cmp = atom_CMP(t, prv, b->ttype); if (cmp > 0) { b->T->nosorted_rev = i; b->tsorted = FALSE; } } if (b->tkey == TRUE && cmp <= 0) { b->T->nokey[0] = i - 1; b->T->nokey[1] = i; b->tkey = bm->hkey = b->tdense = FALSE; } } else if (b->tseqbase != oid_nil){ /* virtual ids */ if (b->tseqbase + BATcount(b) != *(oid*)t) { size_t cnt = BATcount(b); b = BATmaterializet(b, BATcount(b)+1); countonly=0; b->T->nodense = cnt; b->tdense = FALSE; if (b->tsorted & 1) { if (b->tseqbase + cnt > *(oid*)t || *(oid*)t == oid_nil) { b->T->nosorted = 1; b->tsorted = FALSE; b->T->nokey[0] = cnt - 1; b->T->nokey[1] = cnt; b->tkey = bm->hkey = b->tdense = FALSE; } } else if (b->tsorted == (bit)GDK_SORTED_REV){ if (b->tseqbase + cnt < *(oid*)t) { b->T->nosorted = 1; b->tsorted = FALSE; b->T->nokey[0] = cnt - 1; b->T->nokey[1] = cnt; b->tkey = bm->hkey = b->tdense = FALSE; } } } } } else { b->hkey = bm->tkey |= TRUE; if (b->htype == TYPE_oid) { /* empty oid column */ h = &id; id = 0; b->hdense = TRUE; b->hseqbase = bm->tseqbase = *(oid *) h; } if (b->ttype == TYPE_oid) { b->tkey = bm->hkey |= b->tdense = TRUE; b->tseqbase = bm->hseqbase = *(oid *) t; } else if (b->ttype == TYPE_void && b->tseqbase != oid_nil) { if (*(oid*)t == oid_nil) { BATmaterializet(b, BATcount(b)+1); countonly=0; } else { b->tseqbase = bm->hseqbase = *(oid*)t; } } else if (b->ttype) { b->tkey = bm->hkey |= TRUE; } } if (!countonly) { bunfastins(b, h, t); } else { b->batBuns->free += 1; BATsetcount(b, b->batCount+1); } /* first adapt the hashes; then the user-defined accelerators. * REASON: some accelerator updates (qsignature) use the hashes! */ if (b->hhash && h) { HASHins(b, (hash_t) i, h); if (hsize && hsize != b->hheap->size) HEAPwarm(b->hheap); } if (b->thash) { HASHins(bm, (hash_t) i, t); if (tsize && tsize != b->theap->size) HEAPwarm(b->theap); } return b; bunins_failed: return NULL;}@- BUN DeleteDeletes should maintain the BAT as a contiguous array. Thisimplementation permits using a BATloop for(;;) constructionto use the BUNdelete routines, by not modifying what is infront of the deleted bun. This routine returns the next BUN in b after deletion of p.Note: to cause less trouble when updating BATs with void columnsthe delete policy has been changed. Deleted volatile elements are now being overwritten by the last element; instead of causing a cascade of moves. The sequential deletability propertyis changed somewhat: instead of doing @verbatim BATloop(b,p,q) BUNdelete(b,p,FALSE)one now must do: BATloopDEL(b,p) p = BUNdelete(b,p,FALSE)@end verbatim@@cstatic INLINE BUNBUNdelete_(BAT *b, BUN p, bit force){ BAT *bm = BBP_cache(-b->batCacheid); int bs = BUNsize(b); BUN l, last = BUNlast(b) - bs; size_t idx1, idx2; ALIGNdel(b, "BUNdelete", force); /* zap alignment info */@- Committed Delete. Deleting a (committed) bun the first and deleted swap position.@c if (p < b->batInserted && !force) { idx1 = BUNindex(b, p); if (p == b->batFirst) { /* first can simply be discarded */ @:hacc_update(del,head,p,idx1)@ @:tacc_update(del,tail,p,idx1)@ if (BAThdense(b)) { bm->tseqbase = ++b->hseqbase; } if (BATtdense(b)) { bm->hseqbase = ++b->tseqbase; } } else { @:hacc_update(del,head,p,idx1)@ @:tacc_update(del,tail,p,idx1)@ l = BUNfirst(b); idx2 = BUNindex(b, l); @:acc_move(l,p,idx2,idx1)@ if (b->hsorted & 1) { b->hsorted = FALSE; b->H->nosorted = idx1; } else if (b->hsorted == (bit)GDK_SORTED_REV) { b->hsorted = FALSE; b->H->nosorted_rev = idx1; } if (b->tsorted & 1) { b->tsorted = FALSE; b->T->nosorted = idx1; } else if (b->tsorted == (bit)GDK_SORTED_REV) { b->tsorted = FALSE; b->T->nosorted_rev = idx1; } } b->batFirst += bs; } else {@- Uncommitted Delete.This bun was not committed, and should therefore disappear. The last inserted bun (if present) is copied over it. @c int (*hunfix) (ptr) = BATatoms[b->htype].atomUnfix; int (*tunfix) (ptr) = BATatoms[b->ttype].atomUnfix; void (*hatmdel) (Heap *, var_t *) = BATatoms[b->htype].atomDel; void (*tatmdel) (Heap *, var_t *) = BATatoms[b->ttype].atomDel; if (hunfix) { (*hunfix) (BUNhead(b, p)); } if (tunfix) { (*tunfix) (BUNtail(b, p)); } if (hatmdel) { (*hatmdel) (b->hheap, (var_t *) BUNhloc(b, p)); } if (tatmdel) { (*tatmdel) (b->theap, (var_t *) BUNtloc(b, p)); } idx1 = BUNindex(b, p); @:hacc_update(del,head,p,idx1)@ @:tacc_update(del,tail,p,idx1)@ idx2 = BUNindex(b, last); if (p != last) { @:acc_move(last,p,idx2,idx1)@ if (b->hsorted & 1) { b->hsorted = FALSE; b->H->nosorted = idx1; if (b->hdense) { b->hdense = FALSE; b->H->nodense = idx1; } } else if (b->hsorted == (bit)GDK_SORTED_REV) { b->hsorted = FALSE; b->H->nosorted_rev = idx1; } if (b->tsorted & 1) { b->tsorted = FALSE; b->H->nosorted = idx1; if (b->tdense) { b->tdense = FALSE; b->T->nodense = idx1; } } else if (b->tsorted == (bit)GDK_SORTED_REV) { b->tsorted = FALSE; b->H->nosorted_rev = idx1; } } b->batBuns->free -= bs; p = ((char *) p) - bs; } b->batCount--; b->batDirty = 1; /* bat is dirty */ return p;}BUNBUNdelete(BAT *b, BUN p, bit force){ if (p == NULL) { return p; } if ((b->htype == TYPE_void && b->hseqbase != oid_nil) || (b->ttype == TYPE_void && b->tseqbase != oid_nil)) { int bs = BUNsize(b); BUN last = BUNlast(b) - bs; if ((p < b->batInserted || p != last) && !force) { size_t i = BUNindex(b, p); b = BATmaterialize(b, BATcount(b)); if (b == NULL) return NULL; p = BUNptr(b, i); } } return BUNdelete_(b, p, force);}BAT *BUNdel(BAT *b, ptr x, ptr y, bit force){ BUN p; BATcheck(b, "BUNdel"); BATcheck(x, "BUNdel: head value is nil\n"); if ((p = BUNlocate(b, x, y)) != NULL) { ALIGNdel(b, "BUNdel", force); /* zap alignment info */ BUNdelete(b, p, force); return b; } return 0;}@- The routine @%BUNdelHead@ is similar, but removes all BUNs whose head matchesthe argument passed.@cBAT *BUNdelHead(BAT *b, ptr x, bit force){ BUN p; BATcheck(b, "BUNdelHead"); if (x == NULL) { x = ATOMnilptr(b->htype); } if ((p = BUNfnd(b, x)) != NULL) { ALIGNdel(b, "BUNdelHead", force); /* zap alignment info */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -