size_t allocateDT(int8_t *typeArg, int8_t *sizeArg, int ncolArg, int ndrop, size_t allocNrow) { // save inputs for use by pushBuffer size = sizeArg; type = typeArg; int newDT = (ncol == 0); if (newDT) { ncol = ncolArg; dtnrows = allocNrow; SET_VECTOR_ELT(RCHK, 0, DT=allocVector(VECSXP,ncol-ndrop)); if (ndrop==0) { setAttrib(DT,R_NamesSymbol,colNamesSxp); // colNames mkChar'd in userOverride step } else { SEXP tt = PROTECT(allocVector(STRSXP, ncol-ndrop)); setAttrib(DT, R_NamesSymbol, tt); UNPROTECT(1); // tt; now that it's safely a member of protected object for (int i=0,resi=0; i<ncol; i++) if (type[i]!=CT_DROP) { SET_STRING_ELT(tt,resi++,STRING_ELT(colNamesSxp,i)); } } } // TODO: move DT size calculation into a separate function (since the final size is different from the initial size anyways) size_t DTbytes = SIZEOF(DT)*(ncol-ndrop)*2; // the VECSXP and its column names (exclude global character cache usage) // For each column we could have one of the following cases: // * if the DataTable is "new", then make a new vector // * if the column's type has changed, then replace it with a new vector // (however if column's type[i] is negative, then it means we're skipping // the column in the rerun, and its type hasn't actually changed). // * if dtnrows≠allocNrow and the column's type has not changed, then that // column needs to be re-alloced (using growVector). // * otherwise leave the column as-is. for (int i=0, resi=0; i<ncol; i++) { if (type[i] == CT_DROP) continue; SEXP col = VECTOR_ELT(DT, resi); int oldIsInt64 = newDT? 0 : INHERITS(col, char_integer64); int newIsInt64 = type[i] == CT_INT64; int typeChanged = (type[i] > 0) && (newDT || TYPEOF(col) != typeSxp[type[i]] || oldIsInt64 != newIsInt64); int nrowChanged = (allocNrow != dtnrows); if (typeChanged || nrowChanged) { SEXP thiscol = typeChanged ? allocVector(typeSxp[type[i]], allocNrow) // no need to PROTECT, passed immediately to SET_VECTOR_ELT, see R-exts 5.9.1 : growVector(col, allocNrow); SET_VECTOR_ELT(DT,resi,thiscol); if (type[i]==CT_INT64) { SEXP tt = PROTECT(ScalarString(char_integer64)); setAttrib(thiscol, R_ClassSymbol, tt); UNPROTECT(1); } SET_TRUELENGTH(thiscol, allocNrow); DTbytes += SIZEOF(thiscol)*allocNrow; } resi++; } dtnrows = allocNrow; return DTbytes; }
/** \brief The generator for a specified dimension. Will create if not existent */ container_type_t generate(unsigned int dim) { // Assure that the dimension is in the range of the vector. growVector(dim); // Assure that the dimension is allocated: allocateDimension(dim); // Return the generator return (*dimVector_.at(dim).second)(); };