Skip to content

Commit 5b10dd1

Browse files
R -> bit64::integer64
1 parent 3e6bc9a commit 5b10dd1

3 files changed

Lines changed: 65 additions & 6 deletions

File tree

r/DESCRIPTION

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,15 @@ Imports:
2727
crayon,
2828
withr
2929
Remotes:
30-
r-lib/vctrs,
30+
romainfrancois/vctrs@bit64,
3131
RcppCore/Rcpp,
32-
romainfrancois/withr@bug-79/defer
32+
r-lib/withr
3333
Roxygen: list(markdown = TRUE)
3434
RoxygenNote: 6.1.0.9000
3535
Suggests:
3636
testthat,
37-
lubridate
37+
lubridate,
38+
bit64
3839
Collate:
3940
'enums.R'
4041
'R6.R'

r/src/array.cpp

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ using namespace arrow;
2323
namespace arrow {
2424
namespace r {
2525

26+
// the integer64 sentinel
27+
static const int64_t NA_INT64 = std::numeric_limits<int64_t>::min();
28+
2629
template <int RTYPE, typename Type>
2730
std::shared_ptr<Array> SimpleArray(SEXP x) {
2831
Rcpp::Vector<RTYPE> vec(x);
@@ -329,6 +332,47 @@ std::shared_ptr<Array> Date64Array_From_POSIXct(SEXP x) {
329332
return std::make_shared<Date64Array>(data);
330333
}
331334

335+
std::shared_ptr<arrow::Array> Int64Array(SEXP x) {
336+
auto p_vec_start = reinterpret_cast<int64_t*>(REAL(x));
337+
auto n = Rf_xlength(x);
338+
int64_t null_count = 0;
339+
340+
std::vector<std::shared_ptr<Buffer>> buffers{nullptr,
341+
std::make_shared<RBuffer<REALSXP>>(x)};
342+
343+
auto p_vec = std::find(p_vec_start, p_vec_start + n, NA_INT64);
344+
auto first_na = p_vec - p_vec_start;
345+
if (first_na < n) {
346+
R_ERROR_NOT_OK(AllocateBuffer(BitUtil::BytesForBits(n), &buffers[0]));
347+
internal::FirstTimeBitmapWriter bitmap_writer(buffers[0]->mutable_data(), 0, n);
348+
349+
// first loop to clear all the bits before the first NA
350+
int i = 0;
351+
for (; i < first_na; i++, bitmap_writer.Next()) {
352+
bitmap_writer.Set();
353+
}
354+
355+
// then finish
356+
for (; i < n; i++, bitmap_writer.Next(), ++p_vec) {
357+
if (*p_vec == NA_INT64) {
358+
bitmap_writer.Clear();
359+
null_count++;
360+
} else {
361+
bitmap_writer.Set();
362+
}
363+
}
364+
365+
bitmap_writer.Finish();
366+
}
367+
368+
auto data = ArrayData::Make(
369+
std::make_shared<Int64Type>(), n, std::move(buffers), null_count, 0 /*offset*/
370+
);
371+
372+
// return the right Array class
373+
return std::make_shared<typename TypeTraits<Int64Type>::ArrayType>(data);
374+
}
375+
332376
} // namespace r
333377
} // namespace arrow
334378

@@ -355,6 +399,9 @@ std::shared_ptr<arrow::Array> Array__from_vector(SEXP x) {
355399
if (Rf_inherits(x, "POSIXct")) {
356400
return arrow::r::Date64Array_From_POSIXct<REALSXP>(x);
357401
}
402+
if (Rf_inherits(x, "integer64")) {
403+
return arrow::r::Int64Array(x);
404+
}
358405
return arrow::r::SimpleArray<REALSXP, arrow::DoubleType>(x);
359406
case RAWSXP:
360407
return arrow::r::SimpleArray<RAWSXP, arrow::Int8Type>(x);
@@ -624,9 +671,6 @@ SEXP promotion_Array_to_Vector(const std::shared_ptr<Array>& array) {
624671
}
625672

626673
SEXP Int64Array(const std::shared_ptr<Array>& array) {
627-
// the integer64 sentinel
628-
static int64_t NA_INT64 = std::numeric_limits<int64_t>::min();
629-
630674
auto n = array->length();
631675
NumericVector vec(n);
632676
vec.attr("class") = "integer64";

r/tests/testthat/test-Array.R

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,3 +242,17 @@ test_that("array supports POSIXct (ARROW-3340)", {
242242
expect_true(a$IsNull(4))
243243
})
244244

245+
test_that("array supports integer64", {
246+
x <- bit64::as.integer64(1:10)
247+
a <- array(x)
248+
expect_equal(a$type(), int64())
249+
expect_equal(a$length(), 10L)
250+
expect_equal(a$as_vector(), x)
251+
252+
x[4] <- NA
253+
a <- array(x)
254+
expect_equal(a$type(), int64())
255+
expect_equal(a$length(), 10L)
256+
expect_equal(a$as_vector(), x)
257+
expect_true(a$IsNull(3L))
258+
})

0 commit comments

Comments
 (0)