Skip to content

Commit 4a71875

Browse files
committed
replace temporary objects with subscript operator
1 parent e2e0173 commit 4a71875

File tree

1 file changed

+29
-39
lines changed

1 file changed

+29
-39
lines changed

src/subset.c

Lines changed: 29 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,11 @@ void subsetVectorRaw(SEXP ans, SEXP source, SEXP idx, const bool anyNA)
2525
if (nth>1) { \
2626
_Pragma("omp parallel for num_threads(nth)") \
2727
for (int i=0; i<n; ++i) { \
28-
int elem = idxp[i]; \
29-
ap[i] = elem==NA_INTEGER ? _NAVAL_ : sp[elem-1]; \
28+
ap[i] = idxp[i]==NA_INTEGER ? _NAVAL_ : sp[idxp[i]-1]; \
3029
} \
3130
} else { \
3231
for (int i=0; i<n; ++i) { \
33-
int elem = idxp[i]; \
34-
ap[i] = elem==NA_INTEGER ? _NAVAL_ : sp[elem-1]; \
32+
ap[i] = idxp[i]==NA_INTEGER ? _NAVAL_ : sp[idxp[i]-1]; \
3533
} \
3634
} \
3735
} else { \
@@ -74,17 +72,17 @@ void subsetVectorRaw(SEXP ans, SEXP source, SEXP idx, const bool anyNA)
7472
// Aside: setkey() is a separate special case (a permutation) and does do this in parallel without using SET_*.
7573
const SEXP *sp = SEXPPTR_RO(source);
7674
if (anyNA) {
77-
for (int i=0; i<n; i++) { int elem = idxp[i]; SET_STRING_ELT(ans, i, elem==NA_INTEGER ? NA_STRING : sp[elem-1]); }
75+
for (int i=0; i<n; i++) { SET_STRING_ELT(ans, i, idxp[i] ==NA_INTEGER ? NA_STRING : sp[idxp[i] -1]); }
7876
} else {
79-
for (int i=0; i<n; i++) { SET_STRING_ELT(ans, i, sp[idxp[i]-1]); }
77+
for (int i=0; i<n; i++) { SET_STRING_ELT(ans, i, sp[idxp[i]-1]); }
8078
}
8179
} break;
8280
case VECSXP: case EXPRSXP: {
8381
const SEXP *sp = SEXPPTR_RO(source);
8482
if (anyNA) {
85-
for (int i=0; i<n; i++) { int elem = idxp[i]; SET_VECTOR_ELT(ans, i, elem==NA_INTEGER ? R_NilValue : sp[elem-1]); }
83+
for (int i=0; i<n; i++) { SET_VECTOR_ELT(ans, i, idxp[i]==NA_INTEGER ? R_NilValue : sp[idxp[i]-1]); }
8684
} else {
87-
for (int i=0; i<n; i++) { SET_VECTOR_ELT(ans, i, sp[idxp[i]-1]); }
85+
for (int i=0; i<n; i++) { SET_VECTOR_ELT(ans, i, sp[idxp[i]-1]); }
8886
}
8987
} break;
9088
case CPLXSXP : {
@@ -112,15 +110,14 @@ const char *check_idx(SEXP idx, int max, bool *anyNA_out, bool *orderedSubset_ou
112110
int last = INT32_MIN;
113111
int *idxp = INTEGER(idx), n=LENGTH(idx);
114112
for (int i=0; i<n; i++) {
115-
int elem = idxp[i];
116-
if (elem<=0 && elem!=NA_INTEGER) return "Internal inefficiency: idx contains negatives or zeros. Should have been dealt with earlier."; // e.g. test 762 (TODO-fix)
117-
if (elem>max) return "Internal inefficiency: idx contains an item out-of-range. Should have been dealt with earlier."; // e.g. test 1639.64
118-
anyNA |= elem==NA_INTEGER;
119-
anyLess |= elem<last;
120-
last = elem;
113+
if (idxp[i]<=0 && idxp[i]!=NA_INTEGER) return "Internal inefficiency: idx contains negatives or zeros. Should have been dealt with earlier."; // e.g. test 762 (TODO-fix)
114+
if (idxp[i]>max) return "Internal inefficiency: idx contains an item out-of-range. Should have been dealt with earlier."; // e.g. test 1639.64
115+
anyNA |= idxp[i]==NA_INTEGER;
116+
anyLess |= idxp[i]<last;
117+
last = idxp[i];
121118
}
122119
*anyNA_out = anyNA;
123-
*orderedSubset_out = !anyLess; // for the purpose of ordered keys elem==last is allowed
120+
*orderedSubset_out = !anyLess; // for the purpose of ordered keys idxp[i]==last is allowed
124121
return NULL;
125122
}
126123

@@ -150,8 +147,7 @@ SEXP convertNegAndZeroIdx(SEXP idx, SEXP maxArg, SEXP allowOverMax, SEXP allowNA
150147
#pragma omp parallel for num_threads(getDTthreads(n, true))
151148
for (int i=0; i<n; ++i) {
152149
if (stop) continue;
153-
int elem = idxp[i];
154-
if ((elem<1 && (elem!=NA_INTEGER || !allowNA)) || elem>max) stop=true;
150+
if ((idxp[i]<1 && (idxp[i]!=NA_INTEGER || !allowNA)) || idxp[i]>max) stop=true;
155151
}
156152
if (!stop) return(idx); // most common case to return early: no 0, no negative; all idx either NA (if allowNA) or in range [1-max]
157153

@@ -160,11 +156,10 @@ SEXP convertNegAndZeroIdx(SEXP idx, SEXP maxArg, SEXP allowOverMax, SEXP allowNA
160156

161157
int countNeg=0, countZero=0, countNA=0, firstOverMax=0, countOverMax=0;
162158
for (int i=0; i<n; ++i) {
163-
int elem = idxp[i];
164-
if (elem==NA_INTEGER) countNA++;
165-
else if (elem<0) countNeg++;
166-
else if (elem==0) countZero++;
167-
else if (elem>max && ++countOverMax && firstOverMax==0) firstOverMax=i+1;
159+
if (idxp[i]==NA_INTEGER) countNA++;
160+
else if (idxp[i]<0) countNeg++;
161+
else if (idxp[i]==0) countZero++;
162+
else if (idxp[i]>max && ++countOverMax && firstOverMax==0) firstOverMax=i+1;
168163
}
169164
if (firstOverMax && LOGICAL(allowOverMax)[0]==FALSE) {
170165
error(_("i[%d] is %d which is out of range [1,nrow=%d]"), firstOverMax, idxp[firstOverMax-1], max);
@@ -174,19 +169,17 @@ SEXP convertNegAndZeroIdx(SEXP idx, SEXP maxArg, SEXP allowOverMax, SEXP allowNA
174169
if (countPos && countNeg) {
175170
int i=0, firstNeg=0, firstPos=0;
176171
while (i<n && (firstNeg==0 || firstPos==0)) {
177-
int elem = idxp[i];
178-
if (firstPos==0 && elem>0) firstPos=i+1;
179-
if (firstNeg==0 && elem<0 && elem!=NA_INTEGER) firstNeg=i+1;
172+
if (firstPos==0 && idxp[i]>0) firstPos=i+1;
173+
if (firstNeg==0 && idxp[i]<0 && idxp[i]!=NA_INTEGER) firstNeg=i+1;
180174
i++;
181175
}
182176
error(_("Item %d of i is %d and item %d is %d. Cannot mix positives and negatives."), firstNeg, idxp[firstNeg-1], firstPos, idxp[firstPos-1]);
183177
}
184178
if (countNeg && countNA) {
185179
int i=0, firstNeg=0, firstNA=0;
186180
while (i<n && (firstNeg==0 || firstNA==0)) {
187-
int elem = idxp[i];
188-
if (firstNeg==0 && elem<0 && elem!=NA_INTEGER) firstNeg=i+1;
189-
if (firstNA==0 && elem==NA_INTEGER) firstNA=i+1;
181+
if (firstNeg==0 && idxp[i]<0 && idxp[i]!=NA_INTEGER) firstNeg=i+1;
182+
if (firstNA==0 && idxp[i]==NA_INTEGER) firstNA=i+1;
190183
i++;
191184
}
192185
error(_("Item %d of i is %d and item %d is NA. Cannot mix negatives and NA."), firstNeg, idxp[firstNeg-1], firstNA);
@@ -199,18 +192,16 @@ SEXP convertNegAndZeroIdx(SEXP idx, SEXP maxArg, SEXP allowOverMax, SEXP allowNA
199192
ans = PROTECT(allocVector(INTSXP, n-countZero));
200193
int *ansp = INTEGER(ans);
201194
for (int i=0, ansi=0; i<n; ++i) {
202-
int elem = idxp[i];
203-
if (elem==0) continue;
204-
ansp[ansi++] = elem>max ? NA_INTEGER : elem;
195+
if (idxp[i]==0) continue;
196+
ansp[ansi++] = idxp[i]>max ? NA_INTEGER : idxp[i];
205197
}
206198
} else {
207199
// remove zeros, NA and >max
208200
ans = PROTECT(allocVector(INTSXP, n-countZero-countNA-countOverMax));
209201
int *ansp = INTEGER(ans);
210202
for (int i=0, ansi=0; i<n; ++i) {
211-
int elem = idxp[i];
212-
if (elem<1 || elem>max) continue;
213-
ansp[ansi++] = elem;
203+
if (idxp[i]<1 || idxp[i]>max) continue;
204+
ansp[ansi++] = idxp[i];
214205
}
215206
}
216207
} else {
@@ -220,18 +211,17 @@ SEXP convertNegAndZeroIdx(SEXP idx, SEXP maxArg, SEXP allowOverMax, SEXP allowNA
220211
int countRemoved=0, countDup=0, countBeyond=0; // idx=c(-10,-5,-10) removing row 10 twice
221212
int firstBeyond=0, firstDup=0;
222213
for (int i=0; i<n; i++) {
223-
int elem = -idxp[i];
224-
if (elem==0) continue;
225-
if (elem>max) {
214+
if (!idxp[i]) continue;
215+
if (-idxp[i]>max) {
226216
countBeyond++;
227217
if (firstBeyond==0) firstBeyond=i+1;
228218
continue;
229219
}
230-
if (!keep[elem-1]) {
220+
if (!keep[-idxp[i]-1]) {
231221
countDup++;
232222
if (firstDup==0) firstDup=i+1;
233223
} else {
234-
keep[elem-1] = false;
224+
keep[-idxp[i]-1] = false;
235225
countRemoved++;
236226
}
237227
}

0 commit comments

Comments
 (0)