static int BATlocation(str *fnme, int *bid) { /* this function was formerly ATTlocation in removed file * monetdb5/modules/mal/attach.c */ BAT *b = BBPquickdesc(*bid, FALSE); char path[BUFSIZ], *s; *fnme = NULL; if (b == NULL || (!b->T->heap.filename && !b->H->heap.filename)) return 0; s = GDKfilepath(b->T->heap.farmid, BATDIR, (b->T->heap.filename ? b->T->heap.filename : b->H->heap.filename), 0); if (!MT_path_absolute(s)) { snprintf(path, BUFSIZ, "%s%c%s", GDKgetenv("gdk_dbpath"), DIR_SEP, s); } else { snprintf(path, sizeof(path), "%s", s); } GDKfree(s); s = strrchr(path, '.'); if (s) *s = 0; *fnme = GDKstrdup(path); return 1; }
/* in the commit prelude, the delta status in the memory image of all * bats is commited */ static gdk_return prelude(int cnt, bat *subcommit) { int i = 0; while (++i < cnt) { bat bid = subcommit ? subcommit[i] : i; if (BBP_status(bid) & BBPPERSISTENT) { BAT *b = BBP_cache(bid); if (b == NULL && (BBP_status(bid) & BBPSWAPPED)) { b = BBPquickdesc(bid, TRUE); if (b == NULL) return GDK_FAIL; } if (b) { assert(!isVIEW(b)); assert(b->batRole == PERSISTENT); BATcommit(b); } } } return GDK_SUCCEED; }
str BKCgetCapacity(lng *res, const bat *bid) { *res = lng_nil; if (BBPcheck(*bid, "bat.getCapacity")) { BAT *b = BBPquickdesc(abs(*bid), 0); if (b != NULL) *res = (lng) BATcapacity(b); } return MAL_SUCCEED; }
/* * The pack is an ordinary multi BAT insert. Oid synchronistion * between pieces should be ensured by the code generators. * The pack operation could be quite expensive, because it * may create a really large BAT. * The slice over a mat helps to avoid constructing intermediates * that are subsequently reduced. * Contrary to most operations, NIL arguments are skipped and * do not produce RUNTIME_OBJECT_MISSING. */ static str MATpackInternal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p) { int i, *ret = (int*) getArgReference(stk,p,0); BAT *b, *bn; BUN cap = 0; int tt = TYPE_any; (void) cntxt; (void) mb; for (i = 1; i < p->argc; i++) { int bid = stk->stk[getArg(p,i)].val.ival; b = BBPquickdesc(abs(bid),FALSE); if (b && bid < 0) b = BATmirror(b); if( b ){ assert(BAThdense(b)); if (tt == TYPE_any){ tt = b->ttype; } if (!tt && tt != b->ttype) tt = b->ttype; cap += BATcount(b); } } if (tt == TYPE_any){ *ret = 0; return MAL_SUCCEED; } bn = BATnew(TYPE_void, tt, cap, TRANSIENT); if (bn == NULL) throw(MAL, "mat.pack", MAL_MALLOC_FAIL); for (i = 1; i < p->argc; i++) { b = BATdescriptor(stk->stk[getArg(p,i)].val.ival); if( b ){ if (BATcount(bn) == 0) BATseqbase(bn, b->H->seq); if (BATcount(bn) == 0) BATseqbase(BATmirror(bn), b->T->seq); BATappend(bn,b,FALSE); BBPunfix(b->batCacheid); } } assert(!bn->H->nil || !bn->H->nonil); assert(!bn->T->nil || !bn->T->nonil); BATsettrivprop(bn); BATderiveProps(bn,FALSE); BBPkeepref(*ret = bn->batCacheid); return MAL_SUCCEED; }
/* the MAL beautifier is meant to simplify correlation of MAL variables and * the columns in the underlying database. * If the status is set, then we consider the instruction DONE and the result variables * should be shown as well. */ static str shortRenderingTerm(MalBlkPtr mb, MalStkPtr stk, InstrPtr p, int idx) { str s, nme; BAT *b; ValRecord *val; char *cv =0; int varid = getArg(p,idx); size_t len = BUFSIZ; s= GDKmalloc(len); if( s == NULL) return NULL; *s = 0; if( isVarConstant(mb,varid) ){ val =&getVarConstant(mb, varid); if ((cv = VALformat(val)) == NULL) { GDKfree(s); return NULL; } if (strlen(cv) >= len) { char *nbuf; len = strlen(cv); nbuf = GDKrealloc(s, len + 1); if (nbuf == NULL) { GDKfree(s); GDKfree(cv); return NULL; } s = nbuf; } snprintf(s,len + 1,"%s",cv); } else { val = &stk->stk[varid]; if ((cv = VALformat(val)) == NULL) { GDKfree(s); return NULL; } nme = getVarName(mb, varid); if ( isaBatType(getArgType(mb,p,idx))){ b = BBPquickdesc(stk->stk[varid].val.bval, true); snprintf(s,BUFSIZ,"%s["BUNFMT"]" ,nme, b?BATcount(b):0); } else snprintf(s,BUFSIZ,"%s=%s ",nme,cv); } GDKfree(cv); return s; }
str BKCgetColumnType(str *res, const bat *bid) { const char *ret = str_nil; if (BBPcheck(*bid, "bat.getColumnType")) { BAT *b = BBPquickdesc(abs(*bid), 0); if (b) { ret = *bid < 0 ? ATOMname(b->htype) : ATOMname(b->ttype); } } *res = GDKstrdup(ret); return MAL_SUCCEED; }
/* in the commit epilogue, the BBP-status of the bats is changed to * reflect their presence in the succeeded checkpoint. Also bats from * the previous checkpoint that were deleted now are physically * destroyed. */ static void epilogue(int cnt, bat *subcommit) { int i = 0; while (++i < cnt) { bat bid = subcommit ? subcommit[i] : i; if (BBP_status(bid) & BBPPERSISTENT) { BBP_status_on(bid, BBPEXISTING, subcommit ? "TMsubcommit" : "TMcommit"); } else if (BBP_status(bid) & BBPDELETED) { /* check mmap modes of bats that are now * transient. this has to be done after the * commit succeeded, because the mmap modes * allowed on transient bats would be * dangerous on persistent bats. If the commit * failed, the already processed bats that * would become transient after the commit, * but didn't due to the failure, would be a * consistency risk. */ BAT *b = BBP_cache(bid); if (b) { /* check mmap modes */ if (BATcheckmodes(b, true) != GDK_SUCCEED) fprintf(stderr, "#epilogue: BATcheckmodes failed\n"); } } if ((BBP_status(bid) & BBPDELETED) && BBP_refs(bid) <= 0 && BBP_lrefs(bid) <= 0) { BAT *b = BBPquickdesc(bid, TRUE); /* the unloaded ones are deleted without * loading deleted disk images */ if (b) { BATdelete(b); if (BBP_cache(bid)) { /* those that quickdesc * decides to load => free * memory */ BATfree(b); } } BBPclear(bid); /* clear with locking */ } BBP_status_off(bid, BBPDELETED | BBPSWAPPED | BBPNEW, subcommit ? "TMsubcommit" : "TMcommit"); } GDKclrerr(); }
/* the MAL beautifier is meant to simplify correlation of MAL variables and * the columns in the underlying database. * If the status is set, then we consider the instruction DONE and the result variables * should be shown as well. */ static str shortRenderingTerm(MalBlkPtr mb, MalStkPtr stk, InstrPtr p, int idx) { str s, nme; BAT *b; ValRecord *val; char *cv =0; int varid = getArg(p,idx); s= GDKmalloc(BUFSIZ); if( s == NULL) return NULL; *s = 0; if( isVarConstant(mb,varid) ){ val =&getVarConstant(mb, varid); VALformat(&cv, val); snprintf(s,BUFSIZ,"%s",cv); } else { val = &stk->stk[varid]; VALformat(&cv, val); nme = getSTC(mb, varid); if( nme == NULL) nme = getVarName(mb, varid); if ( isaBatType(getArgType(mb,p,idx))){ b = BBPquickdesc(abs(stk->stk[varid].val.ival),TRUE); snprintf(s,BUFSIZ,"%s["BUNFMT"]" ,nme, b?BATcount(b):0); } else if( cv) snprintf(s,BUFSIZ,"%s=%s ",nme,cv); else snprintf(s,BUFSIZ,"%s ",nme); } GDKfree(cv); return s; }
static str renderTerm(MalBlkPtr mb, MalStkPtr stk, InstrPtr p, int idx, int flg) { char *buf =0; char *nme =0; int nameused = 0; size_t len = 0, maxlen = BUFSIZ; ValRecord *val = 0; char *cv =0; str tpe; int showtype = 0, closequote=0; int varid = getArg(p,idx); buf = GDKzalloc(maxlen); if( buf == NULL) { addMalException(mb, "renderTerm:Failed to allocate"); return NULL; } // show the name when required or is used if ((flg & LIST_MAL_NAME) && !isVarConstant(mb,varid) && !isVarTypedef(mb,varid)) { nme = getVarName(mb,varid); len +=snprintf(buf, maxlen, "%s", nme); nameused =1; } // show the value when required or being a constant if( ((flg & LIST_MAL_VALUE) && stk != 0) || isVarConstant(mb,varid) ){ if (nameused){ strcat(buf + len,"="); len++; } // locate value record if (isVarConstant(mb,varid)){ val = &getVarConstant(mb, varid); showtype= getVarType(mb,varid) != TYPE_str && getVarType(mb,varid) != TYPE_bit; } else if( stk) val = &stk->stk[varid]; if ((cv = VALformat(val)) == NULL) { addMalException(mb, "renderTerm:Failed to allocate"); GDKfree(buf); return NULL; } if (len + strlen(cv) >= maxlen) { char *nbuf= GDKrealloc(buf, maxlen =len + strlen(cv) + BUFSIZ); if( nbuf == 0){ GDKfree(buf); GDKfree(cv); addMalException(mb,"renderTerm:Failed to allocate"); return NULL; } buf = nbuf; } if( strcmp(cv,"nil") == 0){ strcat(buf+len,cv); len += strlen(buf+len); GDKfree(cv); showtype = showtype || getBatType(getVarType(mb,varid)) > TYPE_str || ((isVarUDFtype(mb,varid) || isVarTypedef(mb,varid)) && isVarConstant(mb,varid)) || isaBatType(getVarType(mb,varid)); } else{ if ( !isaBatType(getVarType(mb,varid)) && getBatType(getVarType(mb,varid)) > TYPE_str ){ closequote = 1; strcat(buf+len,"\""); len++; } strcat(buf+len,cv); len += strlen(buf+len); GDKfree(cv); if( closequote ){ strcat(buf+len,"\""); len++; } showtype = showtype || closequote > TYPE_str || ((isVarUDFtype(mb,varid) || isVarTypedef(mb,varid) || (flg & (LIST_MAL_REMOTE | LIST_MAL_TYPE))) && isVarConstant(mb,varid)) || (isaBatType(getVarType(mb,varid)) && idx < p->retc); if (stk && isaBatType(getVarType(mb,varid)) && stk->stk[varid].val.bval ){ BAT *d= BBPquickdesc(stk->stk[varid].val.bval, true); if( d) len += snprintf(buf+len,maxlen-len,"[" BUNFMT "]", BATcount(d)); } } } // show the type when required or frozen by the user // special care should be taken with constants, they may have been casted if ((flg & LIST_MAL_TYPE) || (isVarUDFtype(mb, varid) && idx < p->retc) || isVarTypedef(mb,varid) || showtype){ strcat(buf + len,":"); len++; tpe = getTypeName(getVarType(mb, varid)); len += snprintf(buf+len,maxlen-len,"%s",tpe); GDKfree(tpe); } if( len >= maxlen) addMalException(mb,"renderTerm:Value representation too large"); return buf; }
BAT * quick_descriptor(log_bid b) { return BBPquickdesc((bat) b, FALSE); }
static str MATpackSliceInternal(MalBlkPtr mb, MalStkPtr stk, InstrPtr p) { int i, i1 = p->argc, i2 = -1, *ret = (int*) getArgReference(stk,p,0); BAT *b, *bn; BUN cap = 0, fst, lst, cnt, c; int ht = TYPE_any, tt = TYPE_any; assert(p->argc > 3); switch getArgType(mb,p,1) { case TYPE_wrd: fst = (BUN) *(wrd*) getArgReference(stk,p,1); break; case TYPE_lng: fst = (BUN) *(lng*) getArgReference(stk,p,1); break; case TYPE_int: fst = (BUN) *(int*) getArgReference(stk,p,1); break; default: throw(MAL, "mat.packSlice", "wrong type for lower bound"); } switch getArgType(mb,p,2) { case TYPE_wrd: { wrd l = *(wrd*) getArgReference(stk,p,2); if (l == wrd_nil) lst = BUN_MAX; /* no upper bound */ else lst = (BUN) l; break; } case TYPE_lng: { lng l = *(lng*) getArgReference(stk,p,2); if (l == lng_nil) lst = BUN_MAX; /* no upper bound */ else lst = (BUN) l; break; } case TYPE_int: { int l = *(int*) getArgReference(stk,p,2); if (l == int_nil) lst = BUN_MAX; /* no upper bound */ else lst = (BUN) l; break; } default: throw(MAL, "mat.packSlice", "wrong type for upper bound"); } if (lst < BUN_MAX) lst++; /* inclusive -> exclusive upper bound */ if (lst < fst) lst = fst; cnt = lst - fst; for (i = 3; i < p->argc && cap < lst; i++) { int bid = stk->stk[getArg(p,i)].val.ival; b = BBPquickdesc(abs(bid),FALSE); if (b && bid < 0) b = BATmirror(b); if (b == NULL) throw(MAL, "mat.packSlice", RUNTIME_OBJECT_MISSING); if (ht == TYPE_any){ ht = b->htype; tt = b->ttype; } c = BATcount(b); if (cap <= fst) { /* The optimal case is when the requested slice falls completely in one BAT. * In that case, we can simply return a slice (view) of that BAT. * (A pitty that we have calculated the other slices as well.) */ if (lst <= cap + c) { b = BATdescriptor(bid); if( b){ bn = BATslice(b, fst - cap, lst - cap); BBPunfix(b->batCacheid); BBPkeepref(*ret = bn->batCacheid); } else throw(MAL, "mat.packSlice", RUNTIME_OBJECT_MISSING); return MAL_SUCCEED; } if (fst < cap + c) { /* fst falls in BAT i1 == i */ i1 = i; fst -= cap; lst -= cap; cap = 0; } } cap += c; } /* lst falls in BAT i2 == i-1 */ i2 = i - 1; if (cap <= fst) /* i.e., (i1 > i2) */ cap = 0; else cap -= fst; cnt = MIN(cnt, cap); assert(ht== TYPE_void); bn = BATnew(TYPE_void, tt, cnt, TRANSIENT); if (bn == NULL) throw(MAL, "mat.packSlice", MAL_MALLOC_FAIL); /* must set seqbase or else BATins will not materialize column */ BATseqbase(bn, 0); if (tt == TYPE_void) BATseqbase(BATmirror(bn), 0); for (i = i1; i <= i2; i++) { b = BATdescriptor(stk->stk[getArg(p,i)].val.ival); if (b == NULL){ BBPreleaseref(bn->batCacheid); throw(MAL, "mat.packSlice", RUNTIME_OBJECT_MISSING); } c = BATcount(b); /* use the right oid ranges, don't change the input */ if (i == i1 && fst > 0) { BAT *bb = b; b = BATslice(bb, fst, c); BBPunfix(bb->batCacheid); } else if (i == i2 && lst < c) { BAT *bb = b; b = BATslice(bb, 0, lst); BBPunfix(bb->batCacheid); } BATins(bn,b,FALSE); lst -= c; BBPunfix(b->batCacheid); } BBPkeepref(*ret = bn->batCacheid); return MAL_SUCCEED; }