diff --git a/src/data.table.h b/src/data.table.h index 26e074a3d..c4e76e3eb 100644 --- a/src/data.table.h +++ b/src/data.table.h @@ -159,6 +159,7 @@ SEXP int_vec_init(R_len_t n, int val); // vecseq.c SEXP vecseq(SEXP x, SEXP len, SEXP clamp); +SEXP seqexp(SEXP x); // uniqlist.c SEXP uniqlist(SEXP l, SEXP order); diff --git a/src/init.c b/src/init.c index 83917754a..d70780282 100644 --- a/src/init.c +++ b/src/init.c @@ -71,6 +71,7 @@ R_CallMethodDef callMethods[] = { {"Creorder", (DL_FUNC) &reorder, -1}, {"Crbindlist", (DL_FUNC) &rbindlist, -1}, {"Cvecseq", (DL_FUNC) &vecseq, -1}, +{"Cseqexp", (DL_FUNC) &seqexp, -1}, {"Csetlistelt", (DL_FUNC) &setlistelt, -1}, {"Caddress", (DL_FUNC) &address, -1}, {"CexpandAltRep", (DL_FUNC) &expandAltRep, -1}, diff --git a/src/vecseq.c b/src/vecseq.c index 707439ed4..f05d23bbe 100644 --- a/src/vecseq.c +++ b/src/vecseq.c @@ -1,7 +1,6 @@ #include "data.table.h" -SEXP vecseq(SEXP x, SEXP len, SEXP clamp) -{ +SEXP vecseq(SEXP x, SEXP len, SEXP clamp) { // Name taken from bit::vecseq, but, // * implemented in C rather than R // * takes len rather than y endpoints @@ -46,3 +45,37 @@ SEXP vecseq(SEXP x, SEXP len, SEXP clamp) return(ans); } +SEXP seqexp(SEXP x) { + // used in R/mergelist.R + // function(x) unlist(lapply(seq_along(x), function(i) rep(i, x[[i]]))) + // used to expand bmerge()$lens, when $starts does not have NAs (or duplicates?) + // replaces rep.int(indices__, len__) where indices__ was seq_along(x) + // input: 1,1,2, 1,3, 1,0,1,2 + // output: 1,2,3,3,4,5,5,5,6, 8,9,9 + // all1 returns NULL, this is now commented out to reduce overhead becase seqexp is called only when !(ans$allLen1 && (!inner || len.x==length(ans$starts))) if seqexp would be used in another place we could enable that + if (!isInteger(x)) + error("internal error: 'x' must be an integer"); // # nocov + const int *xp = INTEGER(x), nx = LENGTH(x); + int nans = 0; + for (int i=0; i