Skip to content

Commit 1e76fa4

Browse files
fix orderfin segfault
1 parent 62d7bd8 commit 1e76fa4

3 files changed

Lines changed: 23 additions & 33 deletions

File tree

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
1. `as.integer64.integer64` is consistent with `as.integer.integer` in terms or returning a plain integer64 vector (i.e., stripped of attributes; #188). Thanks @hcirellu.
5252
1. `log(integer64(), base=integer64(1))` no longer warns, consistent with `log(integer(), base=integer())` (#93).
5353
1. `sortfin(integer64(), 1:10)` no longer segfaults (#164).
54+
1. `orderfin(as.integer64(10:1), 1:3, 8:11)` no longer segfaults (#166).
5455

5556
## NOTES
5657

src/sortuse64.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ SEXP r_ram_integer64_orderfin_asc(
257257
)
258258
{
259259
int i,n = LENGTH(x_);
260-
int pos,nt = LENGTH(table_);
260+
int pos,nt = LENGTH(order_);
261261
int n1 = nt-1;
262262
int method = asInteger(method_);
263263

@@ -336,7 +336,7 @@ SEXP r_ram_integer64_orderpos_asc(
336336
)
337337
{
338338
int i,n = LENGTH(x_);
339-
int pos,nt = LENGTH(table_);
339+
int pos,nt = LENGTH(order_);
340340
int n1 = nt-1;
341341
int method = asInteger(method_);
342342
int nomatch = asInteger(nomatch_);

tests/testthat/test-sortuse64.R

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,26 @@
1-
with_parameters_test_that("sortfin works", method=1:3, {
2-
x = as.integer64(1:10)
3-
r = sample(x) # NB: default method assumes 'sorted' is, well, sorted, so this requires method!=1
4-
expect_identical(sortfin(integer64(), 1:10, method=method), rep(FALSE, 10L))
5-
expect_identical(sortfin(x, integer64(), method=method), logical())
1+
test_that("orderfin and orderpos work with partial order", {
2+
# These were segfaulting due to length(order) < length(table)
3+
table = as.integer64(c(10, 20, 30, 5, 15, 25))
4+
order = c(4, 1, 5, 2, 6, 3) # order of table is 5, 10, 15, 20, 25, 30
65

7-
expect_true(all(sortfin(x, r)))
6+
partial_order = c(4, 1, 5, 2) # order of subset of table is 5, 10, 15, 20
87

9-
expect_true(sortfin(x, 1L, method=method))
10-
expect_true(all(sortfin(x, c(1.0, 4.0), method=method)))
11-
expect_identical(sortfin(x, as.integer64(0:1), method=method), c(FALSE, TRUE))
12-
# only 'x' need be sorted
13-
expect_identical(sortfin(x, as.integer64(1:0), method=method), c(TRUE, FALSE))
14-
})
15-
16-
test_that("orderfin and orderpos work", {
17-
x = as.integer64(1:10)
18-
idx = seq_along(x)
8+
x = as.integer64(c(5, 10, 15, 20, 25, 30, 99))
199

20-
expect_identical(orderfin(x, idx, 0:1), c(FALSE, TRUE))
21-
expect_identical(orderfin(x, idx, as.integer64(0:1), method=2L), c(FALSE, TRUE))
22-
expect_identical(orderfin(x, idx, as.integer64(0:1), method=3L), c(FALSE, TRUE))
23-
24-
expect_identical(orderpos(x, idx, 0:1), c(NA_integer_, 1L))
25-
expect_identical(orderpos(x, idx, as.integer64(0:1), method=2L), c(NA_integer_, 1L))
26-
expect_identical(orderpos(x, idx, as.integer64(0:1), method=3L), c(NA_integer_, 1L))
27-
})
10+
# reference with full order
11+
full_fin = c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE)
12+
full_pos = c(4L, 1L, 5L, 2L, 6L, 3L, NA_integer_)
13+
expect_identical(orderfin(table, order, x), full_fin)
14+
expect_identical(orderpos(table, order, x), full_pos)
2815

29-
test_that("ordertab and orderdup work", {
30-
x = as.integer64(1:10)
31-
x = c(x, x[1:8], x[1:6])
32-
idx = order(x)
16+
# with partial order, we search in a subset
17+
partial_fin = c(TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE)
18+
partial_pos = c(4L, 1L, 5L, 2L, NA_integer_, NA_integer_, NA_integer_)
19+
expect_identical(orderfin(table, partial_order, x), partial_fin)
20+
expect_identical(orderpos(table, partial_order, x), partial_pos)
3321

34-
expect_identical(ordertab(x, idx, 10L), rep(3:1, c(6L, 2L, 2L)))
35-
expect_identical(orderdup(x, idx), rep(c(FALSE, TRUE), c(10L, 14L)))
36-
expect_identical(orderdup(x, idx, method=2L), rep(c(FALSE, TRUE), c(10L, 14L)))
22+
# user's example, table is not sorted ascending with order
23+
# just check for no error
24+
expect_identical(orderfin(as.integer64(10:1), 1:3, 8:11, method=1L), c(TRUE, TRUE, TRUE, FALSE))
25+
expect_identical(orderpos(as.integer64(10:1), 1:3, 8:11, method=1L), c(1L, 2L, 3L, NA_integer_))
3726
})

0 commit comments

Comments
 (0)