forked from Rdatatable/data.table
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfrollapply.c
More file actions
89 lines (83 loc) · 3.35 KB
/
frollapply.c
File metadata and controls
89 lines (83 loc) · 3.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "data.table.h"
static inline void memcpy_sexp(SEXP dest, size_t offset, SEXP src, int count) {
switch (TYPEOF(dest)) {
case LGLSXP: case INTSXP: {
memcpy(INTEGER(dest), INTEGER_RO(src) + offset, count * sizeof(int));
} break;
case REALSXP: {
memcpy(REAL(dest), REAL_RO(src) + offset, count * sizeof(double));
} break;
case STRSXP: {
for (int i = 0; i < count; i++)
SET_STRING_ELT(dest, i, STRING_ELT(src, offset + i));
} break;
case VECSXP: {
for (int i = 0; i < count; i++)
SET_VECTOR_ELT(dest, i, VECTOR_ELT(src, offset + i));
} break;
case CPLXSXP: {
memcpy(COMPLEX(dest), COMPLEX_RO(src) + offset, count * sizeof(Rcomplex));
} break;
case RAWSXP: {
memcpy(RAW(dest), RAW_RO(src) + offset, count * sizeof(Rbyte));
} break;
default: internal_error(__func__, "column type not supported in memcpyVector or memcpyDT function. All known types are supported so please report as bug."); // # nocov
}
}
/*
* memcpy src data into preallocated window
* we don't call memcpyVector from memcpyDT because they are called in tight loop and we don't want to have extra branches inside
*/
SEXP memcpyVector(SEXP dest, SEXP src, SEXP offset, SEXP size) {
memcpy_sexp(dest, INTEGER_RO(offset)[0] - INTEGER_RO(size)[0], src, LENGTH(dest));
return dest;
}
// # nocov start ## does not seem to be reported to codecov most likely due to running in a fork, I manually debugged that it is being called when running froll.Rraw
SEXP memcpyDT(SEXP dest, SEXP src, SEXP offset, SEXP size) {
//Rprintf("%d",1); // manual code coverage to confirm it is reached when marking nocov
const int ncol = LENGTH(dest);
const int nrow = LENGTH(VECTOR_ELT(dest, 0));
for (int i = 0; i < ncol; i++) {
memcpy_sexp(VECTOR_ELT(dest, i), INTEGER_RO(offset)[0] - INTEGER_RO(size)[0], VECTOR_ELT(src, i), nrow);
}
return dest;
}
// # nocov end
SEXP memcpyVectoradaptive(SEXP dest, SEXP src, SEXP offset, SEXP size) {
const size_t oi = INTEGER_RO(offset)[0];
const int nrow = INTEGER_RO(size)[oi - 1];
const size_t o = oi - nrow; // oi should always be bigger than nrow because we filter out incomplete window using ansMask
R_resizeVector(dest, nrow); // must be before memcpy_sexp because attempt to set index 1/1 in SET_STRING_ELT test 6010.150
if (nrow) { // support k[i]==0
memcpy_sexp(dest, o, src, nrow);
}
return dest;
}
// # nocov start ## does not seem to be reported to codecov most likely due to running in a fork, I manually debugged that it is being called when running froll.Rraw
SEXP memcpyDTadaptive(SEXP dest, SEXP src, SEXP offset, SEXP size) {
//Rprintf("%d",2); // manual code coverage to confirm it is reached when marking nocov
size_t oi = INTEGER_RO(offset)[0];
const int nrow = INTEGER_RO(size)[oi - 1];
const size_t o = oi - nrow;
const int ncol = LENGTH(dest);
for (int i = 0; i < ncol; i++) {
SEXP d = VECTOR_ELT(dest, i);
R_resizeVector(d, nrow);
if (nrow) { // support k[i]==0
memcpy_sexp(d, o, VECTOR_ELT(src, i), nrow);
}
}
return dest;
}
// # nocov end
// needed in adaptive=TRUE
SEXP copyAsGrowable(SEXP x) {
if (!isNewList(x))
return R_duplicateAsResizable(x);
SEXP ret = PROTECT(shallow_duplicate(x));
R_xlen_t n = xlength(ret);
for (R_xlen_t i = 0; i < n; ++i)
SET_VECTOR_ELT(ret, i, R_duplicateAsResizable(VECTOR_ELT(ret, i)));
UNPROTECT(1);
return ret;
}