/* * When a client needs to be terminated then the file descriptors for * its input/output are simply closed. This leads to a graceful * degradation, but may take some time when the client is busy. A more * forcefull method is to kill the client thread, but this may leave * locks and semaphores in an undesirable state. * * The routine freeClient ends a single client session, but through side * effects of sharing IO descriptors, also its children. Conversely, a * child can not close a parent. */ void freeClient(Client c) { Thread t = c->mythread; c->mode = FINISHCLIENT; #ifdef MAL_CLIENT_DEBUG printf("# Free client %d\n", c->idx); #endif MCexitClient(c); /* scope list and curprg can not be removed, because the client may * reside in a quit() command. Therefore the scopelist is re-used. */ c->scenario = NULL; if (c->prompt) GDKfree(c->prompt); c->prompt = NULL; c->promptlength = -1; if (c->errbuf) { GDKsetbuf(0); if (c->father == NULL) GDKfree(c->errbuf); c->errbuf = 0; } c->father = 0; c->login = c->lastcmd = 0; //c->active = 0; c->qtimeout = 0; c->stimeout = 0; c->user = oid_nil; if( c->username){ GDKfree(c->username); c->username = 0; } c->mythread = 0; GDKfree(c->glb); c->glb = NULL; if( c->error_row){ BBPdecref(c->error_row->batCacheid,TRUE); BBPdecref(c->error_fld->batCacheid,TRUE); BBPdecref(c->error_msg->batCacheid,TRUE); BBPdecref(c->error_input->batCacheid,TRUE); c->error_row = c->error_fld = c->error_msg = c->error_input = NULL; } if (t) THRdel(t); /* you may perform suicide */ MT_sema_destroy(&c->s); c->mode = MCshutdowninprogress()? BLOCKCLIENT: FREECLIENT; }
str AGGRsubmaxcand_val(bat *retval, bat *bid, bat *gid, bat *eid, bat *sid, bit *skip_nils) { BAT *a, *b, *r; str res; bat ret; if ((res = AGGRsubgrouped(&ret, NULL, bid, gid, eid, sid, *skip_nils, 0, TYPE_oid, BATgroupmax, NULL, "aggr.submax")) != MAL_SUCCEED) return res; b = BATdescriptor(*bid); if ( b == NULL) throw(MAL,"aggr.max",RUNTIME_OBJECT_MISSING); a = BATdescriptor(ret); if ( a == NULL){ BBPreleaseref(b->batCacheid); throw(MAL,"aggr.max",RUNTIME_OBJECT_MISSING); } r = BATproject(a, b); BBPreleaseref(b->batCacheid); BBPreleaseref(a->batCacheid); BBPdecref(ret, TRUE); BBPkeepref(*retval = r->batCacheid); return MAL_SUCCEED; }
str AGGRsubmin_val(bat *retval, bat *bid, bat *gid, bat *eid, bit *skip_nils) { BAT *a, *b, *r; str res; bat ret; if ((res = AGGRsubgrouped(&ret, NULL, bid, gid, eid, NULL, *skip_nils, 0, TYPE_oid, BATgroupmin, NULL, "aggr.submin")) != MAL_SUCCEED) return res; b = BATdescriptor(*bid); if( b == NULL) throw(MAL,"aggr.submax", INTERNAL_BAT_ACCESS); a = BATdescriptor(ret); if( a == NULL){ BBPreleaseref(b->batCacheid); throw(MAL,"aggr.submax", INTERNAL_BAT_ACCESS); } r = BATproject(a, b); BBPreleaseref(b->batCacheid); BBPreleaseref(a->batCacheid); BBPdecref(ret, TRUE); BBPkeepref(*retval = r->batCacheid); return MAL_SUCCEED; }
str AGGRsubmin_val(bat *retval, bat *bid, bat *gid, bat *eid, bit *skip_nils) { BAT *a, *b, *r; str res; bat ret; if ((res = AGGRsubgrouped(&ret, bid, gid, eid, NULL, *skip_nils, 0, TYPE_oid, BATgroupmin, "aggr.submin")) != MAL_SUCCEED) return res; b = BATdescriptor(*bid); a = BATdescriptor(ret); r = BATouterjoin(a, b, BATcount(a)); BBPreleaseref(b->batCacheid); BBPreleaseref(a->batCacheid); BBPdecref(ret, TRUE); BBPkeepref(*retval = r->batCacheid); return MAL_SUCCEED; }
void temp_destroy(log_bid b) { BBPdecref(b, TRUE); }
static void bat_decref(bat bid) { BBPdecref(bid, TRUE); }
/* import variable given file id and variable name */ str NCDFimportVariable(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { mvc *m = NULL; sql_schema *sch = NULL; sql_table *tfiles = NULL, *arr_table = NULL; sql_column *col; str msg = MAL_SUCCEED, vname = *(str*)getArgReference(stk, pci, 2); str fname = NULL, dimtype = NULL, aname_sys = NULL; int fid = *(int*)getArgReference(stk, pci, 1); int varid, vndims, vnatts, i, j, retval; char buf[BUFSIZ], *s= buf, aname[256], **dname; oid rid = oid_nil; int vdims[NC_MAX_VAR_DIMS]; nc_type vtype; int ncid; /* dataset id */ size_t dlen; bat vbatid = 0, *dim_bids; BAT *vbat = NULL, *dimbat; msg = getSQLContext(cntxt, mb, &m, NULL); if (msg) return msg; sch = mvc_bind_schema(m, "sys"); if ( !sch ) return createException(MAL, "netcdf.importvar", "Cannot get schema sys\n"); tfiles = mvc_bind_table(m, sch, "netcdf_files"); if (tfiles == NULL) return createException(MAL, "netcdf.importvar", "Catalog table missing\n"); /* get the name of the attached NetCDF file */ col = mvc_bind_column(m, tfiles, "file_id"); if (col == NULL) return createException(MAL, "netcdf.importvar", "Could not find \"netcdf_files\".\"file_id\"\n"); rid = table_funcs.column_find_row(m->session->tr, col, (void *)&fid, NULL); if (rid == oid_nil) return createException(MAL, "netcdf.importvar", "File %d not in the NetCDF vault\n", fid); col = mvc_bind_column(m, tfiles, "location"); fname = (str)table_funcs.column_find_value(m->session->tr, col, rid); /* Open NetCDF file */ if ((retval = nc_open(fname, NC_NOWRITE, &ncid))) return createException(MAL, "netcdf.importvar", "Cannot open NetCDF file %s: %s", fname, nc_strerror(retval)); /* Get info for variable vname from NetCDF file */ if ( (retval = nc_inq_varid(ncid, vname, &varid)) ) return createException(MAL, "netcdf.importvar", "Cannot read variable %s: %s", vname, nc_strerror(retval)); if ( (retval = nc_inq_var(ncid, varid, vname, &vtype, &vndims, vdims, &vnatts))) return createException(MAL, "netcdf.importvar", "Cannot read variable %d : %s", varid, nc_strerror(retval)); /* compose 'create table' statement in the buffer */ dname = (char **) GDKzalloc( sizeof(char *) * vndims); for (i = 0; i < vndims; i++) dname[i] = (char *) GDKzalloc(NC_MAX_NAME + 1); snprintf(aname, 256, "%s%d", vname, fid); j = snprintf(buf, BUFSIZ,"create table %s.%s( ", sch->base.name, aname); for (i = 0; i < vndims; i++){ if ((retval = nc_inq_dim(ncid, vdims[i], dname[i], &dlen))) return createException(MAL, "netcdf.importvar", "Cannot read dimension %d : %s", vdims[i], nc_strerror(retval)); if ( dlen <= (int) GDK_bte_max ) dimtype = "TINYINT"; else if ( dlen <= (int) GDK_sht_max ) dimtype = "SMALLINT"; else dimtype = "INT"; (void)dlen; j += snprintf(buf + j, BUFSIZ - j, "%s %s, ", dname[i], dimtype); } j += snprintf(buf + j, BUFSIZ - j, "value %s);", NCDF2SQL(vtype)); /* execute 'create table ' */ msg = SQLstatementIntern(cntxt, &s, "netcdf.importvar", TRUE, FALSE, NULL); if (msg != MAL_SUCCEED) return msg; /* load variable data */ dim_bids = (bat *)GDKmalloc(sizeof(bat) * vndims); msg = NCDFloadVar(&dim_bids, &vbatid, ncid, varid, vtype, vndims, vdims); if ( msg != MAL_SUCCEED ) return msg; /* associate columns in the table with loaded variable data */ aname_sys = toLower(aname); arr_table = mvc_bind_table(m, sch, aname_sys); if (arr_table == NULL) return createException(MAL, "netcdf.importvar", "netcdf table %s missing\n", aname_sys); col = mvc_bind_column(m, arr_table, "value"); if (col == NULL) return createException(MAL, "netcdf.importvar", "Cannot find column %s.value\n", aname_sys); vbat = BATdescriptor(vbatid); store_funcs.append_col(m->session->tr, col, vbat, TYPE_bat); BBPunfix(vbatid); BBPdecref(vbatid, 1); vbat = NULL; /* associate dimension bats */ for (i = 0; i < vndims; i++){ col = mvc_bind_column(m, arr_table, dname[i]); if (col == NULL) return createException(MAL, "netcdf.importvar", "Cannot find column %s.%s\n", aname_sys, dname[i]); dimbat = BATdescriptor(dim_bids[i]); store_funcs.append_col(m->session->tr, col, dimbat, TYPE_bat); BBPunfix(dim_bids[i]); /* phys. ref from BATdescriptor */ BBPdecref(dim_bids[i], 1); /* log. ref. from loadVar */ dimbat = NULL; } for (i = 0; i < vndims; i++) GDKfree(dname[i]); GDKfree(dname); GDKfree(dim_bids); nc_close(ncid); return msg; }
/* Load variable varid from data set ncid into the bat v. Generate dimension * bats dim using NCDFARRAYseries */ static str NCDFloadVar(bat **dim, bat *v, int ncid, int varid, nc_type vtype, int vndims, int *vdims) { BAT *res; bat vbid, *dim_bids; int retval, i, j; char *sermsg = NULL; size_t sz = 1; size_t *dlen = NULL, *val_rep = NULL, *grp_rep = NULL; if ( dim == NULL ) return createException(MAL, "netcdf.importvar", "array of dimension bat is NULL"); dim_bids = *dim; dlen = (size_t *)GDKzalloc(sizeof(size_t) * vndims); for (i = 0; i < vndims; i++){ if ((retval = nc_inq_dimlen(ncid, vdims[i], &dlen[i]))) return createException(MAL, "netcdf.importvar", "Cannot read dimension %d : %s", vdims[i], nc_strerror(retval)); sz *= dlen[i]; } switch (vtype) { case NC_INT: { LOAD_NCDF_VAR(int,int); break; } case NC_FLOAT: case NC_DOUBLE: { LOAD_NCDF_VAR(dbl,double); break; } default: return createException(MAL, "netcdf.importvar", "Type %s not supported yet", prim_type_name(vtype)); } BATsetcount(res, sz); res->T->nonil = TRUE; res->T->nil = FALSE; res->tsorted = FALSE; res->trevsorted = FALSE; BATkey(BATmirror(res), FALSE); BBPkeepref(vbid = res->batCacheid); res = NULL; /* Manually create dimensions with range [0:1:dlen[i]] */ val_rep = (size_t *)GDKmalloc(sizeof(size_t) * vndims); grp_rep = (size_t *)GDKmalloc(sizeof(size_t) * vndims); /* compute the repetition factor inside of the series (val_rep) and of series (grp_rep) */ for (i = 0; i < vndims; i++) { val_rep[i] = grp_rep[i] = 1; for (j = 0; j < i; j++) grp_rep[i] *= dlen[j]; for (j = i + 1; j < vndims; j++) val_rep[i] *= dlen[j]; } for (i = 0; i < vndims; i++) { sermsg = NCDFARRAYseries(&dim_bids[i], 0, 1, dlen[i], val_rep[i], grp_rep[i]); if (sermsg != MAL_SUCCEED) { BBPdecref(vbid, 1); /* undo the BBPkeepref(vbid) above */ for ( j = 0; j < i; j++) /* undo log. ref of previous dimensions */ BBPdecref(dim_bids[j], 1); GDKfree(dlen); GDKfree(val_rep); GDKfree(grp_rep); return createException(MAL, "netcdf.loadvar", "Failed to create a dimension of variable %d", varid); } } /* to do : is descriptor check of dim_bids is needed? */ GDKfree(dlen); GDKfree(val_rep); GDKfree(grp_rep); *v = vbid; return MAL_SUCCEED; }
/* * The shortcut operator for factory calls assumes that the user is * not interested in the results produced. */ str callFactory(Client cntxt, MalBlkPtr mb, ValPtr argv[], char flag){ Plant pl; InstrPtr psig = getInstrPtr(mb, 0); int i; ValPtr lhs,rhs; MalStkPtr stk; str ret; i= findPlant(mb); if( i< 0) { /* first call? prepare the factory */ pl = newPlant(mb); if (pl == NULL) throw(MAL, "factory.call", MAL_MALLOC_FAIL); /* remember context, which does not exist. */ pl->client = cntxt; pl->caller = 0; pl->env = 0; pl->pci = 0; pl->inuse = 1; stk = pl->stk; /* initialize the stack */ stk->stktop= mb->vtop; stk->stksize= mb->vsize; stk->blk= mb; stk->up = 0; stk->cmd= flag; /* initialize the stack */ for(i= psig->argc; i< mb->vtop; i++) if( isVarConstant(mb,i) > 0 ){ lhs = &stk->stk[i]; rhs = &getVarConstant(mb,i); VALcopy(lhs,rhs); } else { lhs = &stk->stk[i]; lhs->vtype = getVarGDKType(mb,i); } pl->stk= stk; } else { pl= plants+i; /* * When you re-enter the factory the old arguments should be * released to make room for the new ones. */ for (i = psig->retc; i < psig->argc; i++) { lhs = &pl->stk->stk[psig->argv[i]]; if( lhs->vtype == TYPE_bat ) BBPdecref(lhs->val.bval, TRUE); } } /* copy the calling arguments onto the stack of the factory */ i = psig->retc; for (i = psig->retc; i < psig->argc; i++) { lhs = &pl->stk->stk[psig->argv[i]]; VALcopy(lhs, argv[i]); if( lhs->vtype == TYPE_bat ) BBPincref(lhs->val.bval, TRUE); } ret= reenterMAL(cntxt, mb, pl->pc, -1, pl->stk); /* garbage collect the string arguments, these positions will simply be overwritten the next time. for (i = psig->retc; i < psig->argc; i++) garbageElement(lhs = &pl->stk->stk[psig->argv[i]]); */ return ret; }
str GRPmulticolumngroup(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { bat *grp = (bat *) getArgReference(stk, pci, 0); bat *ext = (bat *) getArgReference(stk, pci, 1); bat *hist = (bat *) getArgReference(stk, pci, 2); int i, j; bat oldgrp, oldext, oldhist; str msg = MAL_SUCCEED; lng *sizes = (lng *) GDKzalloc(sizeof(lng) * pci->argc), l; bat *bid = (bat *) GDKzalloc(sizeof(bat) * pci->argc), bi; BAT *b, *sample, *uniq; BUN count = 0; assert(pci->argc >= 4); for (i = 3; i < pci->argc; i++) { bid[i] = *(int *) getArgReference(stk, pci, i); b = BATdescriptor(bid[i]); if (b) { sizes[i] = count = BATcount(b); sample = BATsample(b, 1000); if (sample) { uniq = BATkunique(BATmirror(sample)); if (uniq) { sizes[i] = (lng) BATcount(uniq); BBPreleaseref(uniq->batCacheid); } BBPreleaseref(sample->batCacheid); } BBPreleaseref(bid[i]); } } /* for (i=3; i<pci->argc; i++) mnstr_printf(cntxt->fdout,"# before[%d] "LLFMT"\n",i, sizes[i]); */ /* sort order may have influences */ /* SF100 Q16 showed < ordering is 2 times faster as > ordering */ for (i = 3; i < pci->argc; i++) for (j = i + 1; j < pci->argc; j++) if (sizes[j] < sizes[i]) { l = sizes[j]; sizes[j] = sizes[i]; sizes[i] = l; bi = bid[j]; bid[j] = bid[i]; bid[i] = bi; } /* for (i=2; i<pci->argc; i++) mnstr_printf(cntxt->fdout,"# after [%d] "LLFMT"\n",i, sizes[i]); */ /* (grp,ext,hist) := group.subgroup(..) */ *grp = 0; *ext = 0; *hist = 0; msg = GRPsubgroup1(grp, ext, hist, &bid[3]); i = 4; if (msg == MAL_SUCCEED && pci->argc > 4) do { /* early break when there are as many groups as histogram entries */ b = BATdescriptor(*hist); if (b) { j = BATcount(b) == count; BBPreleaseref(*hist); if (j) break; } /* (grp,ext,hist) := group.subgroup(arg,grp,ext,hist) */ oldgrp = *grp; oldext = *ext; oldhist = *hist; *grp = 0; *ext = 0; *hist = 0; msg = GRPsubgroup4(grp, ext, hist, &bid[i], &oldgrp, &oldext, &oldhist); BBPdecref(oldgrp, TRUE); BBPdecref(oldext, TRUE); BBPdecref(oldhist, TRUE); } while (msg == MAL_SUCCEED && ++i < pci->argc); GDKfree(sizes); GDKfree(bid); (void) cntxt; (void) mb; return msg; }