Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
1. `log(integer64(), base=integer64(1))` no longer warns, consistent with `log(integer(), base=integer())` (#93).
1. `sortfin(integer64(), 1:10)` no longer segfaults (#164).
1. `orderfin(as.integer64(10:1), 1:3, 8:11)` enforces that `table` be sorted by `order` instead of segfaulting (#166).
1. `ordertab()` no longer segfaults when `nunique` is smaller than the actual number of unique values (#168).

## NOTES

Expand Down
4 changes: 4 additions & 0 deletions src/sortuse64.c
Original file line number Diff line number Diff line change
Expand Up @@ -775,17 +775,21 @@ SEXP r_ram_integer64_ordertab_asc(
ret[pos++] = ret[i];
SET_LENGTH(ret_, pos); /* re-allocates ret_ */
}else{
int n_ret = LENGTH(ret_); // allow bailing if user mis-specified nunique (#168)
if (n_ret > 0) {
j = 0;
ret[j] = 1;
pos = index[j]-1;
for(i=1;i<n;i++){
if (table[index[i]-1]!=table[pos]){
pos = index[i]-1;
if (j + 1 >= n_ret) break;
ret[++j] = 1;
}else{
ret[j]++;
}
}
}
}
PROTECT(ret_); /* Thanks to Tomas Kalibera */
R_Busy(0);
Expand Down
14 changes: 14 additions & 0 deletions tests/testthat/test-sortuse64.R
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,17 @@ test_that("ordertab and orderdup work", {
expect_identical(orderdup(x, idx, method=2L), rep(c(FALSE, TRUE), c(10L, 14L)))
})

test_that("ordertab handles nunique smaller than actual", {
x = as.integer64(1:10)
x = c(x, x[1:8], x[1:6])
o = order(x)

# makes operation quite slow, but in my test, this segfaulted on the first invocation every time.
# do this inside 'local' because doing so inside 'expect_identical' causes gctorture to apply
# to _every_ allocation induced by testthat as well as rep(). This isolated form is much faster.
res = local({
on.exit(gctorture(FALSE)); gctorture(TRUE)
ordertab(x, o, 4L)
})
expect_identical(res, rep(3L, 4L))
})
Loading