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
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: tiledb
Type: Package
Version: 0.13.0
Version: 0.13.0.1
Title: Universal Storage Engine for Sparse and Dense Multidimensional Arrays
Authors@R: c(person("TileDB, Inc.", role = c("aut", "cph")),
person("Dirk", "Eddelbuettel", email = "dirk@tiledb.com", role = "cre"))
Expand Down
2 changes: 2 additions & 0 deletions R/DataFrame.R
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ fromDataFrame <- function(obj, uri, col_index=NULL, sparse=TRUE, allows_dups=spa
tp <- "DATETIME_NS"
else if (cl == "integer64")
tp <- "INT64"
else if (cl == "logical")
tp <- if (tiledb_version(TRUE) >= "2.10.0") "BOOL" else "INT32"
else
stop("Currently unsupported type: ", cl)
if (debug) {
Expand Down
9 changes: 8 additions & 1 deletion R/Query.R
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,14 @@ tiledb_query_set_buffer <- function(query, attr, buffer) {
stopifnot(`Argument 'query' must be a tiledb_query object` = is(query, "tiledb_query"),
`Argument 'attr' must be character_variable` = is.character(attr),
`Argument 'buffer' must be integer, numeric or logical` = is.numeric(buffer) || is.logical(buffer))
libtiledb_query_set_buffer(query@ptr, attr, buffer)
if (is.numeric(buffer) || tiledb_version(TRUE) < "2.10.0") {
libtiledb_query_set_buffer(query@ptr, attr, buffer)
} else { # logical now maps to BOOL which is a uint8_t, we need a different approach
nr <- NROW(buffer)
bufptr <- libtiledb_query_buffer_alloc_ptr("BOOL", nr, FALSE)
bufptr <- libtiledb_query_buffer_assign_ptr(bufptr, "BOOL", buffer, FALSE)
query@ptr <- libtiledb_query_set_buffer_ptr(query@ptr, attr, bufptr)
}
invisible(query)
}

Expand Down
37 changes: 37 additions & 0 deletions inst/tinytest/test_attr.R
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,40 @@ newarr <- tiledb_array(uri, as.data.frame=TRUE)
chk <- newarr[]
expect_equal(df[,1:10], chk[,1:10])
expect_equivalent(as.numeric(df[,11]), chk[,11]) # we currently return uint64_t as numeric


## BOOL support added in 2.10.0
if (tiledb_version(TRUE) < "2.10.0") exit_file("Remainder needs 2.10.* or later")

uri <- tempfile()
if (dir.exists(uri)) unlink(uri, recursive=TRUE)

## high-level
D <- data.frame(key=c(2L,4L,6L,8L), val=c(TRUE,FALSE,NA,TRUE))
fromDataFrame(D, uri, col_index=1)
arr <- tiledb_array(uri, return_as="data.frame")
res <- arr[]
attr(res, "query_status") <- NULL
expect_equal(D, res)


## lower-level testing tiledb_query_set_buffer
if (dir.exists(uri)) unlink(uri, recursive=TRUE)
v <- D[, "val"]
v[3] <- TRUE # without nullable for simplicity
dim <- tiledb_dim(name = "dim", domain = c(0L, 3L), type = "INT32")
sch <- tiledb_array_schema(domain = tiledb_domain(dim),
attrs = tiledb_attr("val", type = "BOOL"))
tiledb_array_create(uri, sch)
arr <- tiledb_array(uri)
qry <- tiledb_query(arr, "WRITE")
qry <- tiledb_query_set_buffer(qry, "val", v)
qry <- tiledb_query_submit(qry)
qry <- tiledb_query_finalize(qry)
expect_equal(tiledb_query_status(qry), "COMPLETE")

arr2 <- tiledb_array(uri, return_as="data.frame")
res2 <- arr2[0:3]
print(res2)
attr(res2, "query_status") <- NULL
expect_equal(v, res2[,"val"])
56 changes: 52 additions & 4 deletions src/libtiledb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ const char* _tiledb_datatype_to_string(tiledb_datatype_t dtype) {
#if TILEDB_VERSION >= TileDB_Version(2,7,0)
case TILEDB_BLOB:
return "BLOB";
#endif
#if TILEDB_VERSION >= TileDB_Version(2,10,0)
case TILEDB_BOOL:
return "BOOL";
#endif
default:
Rcpp::stop("unknown tiledb_datatype_t (%d)", dtype);
Expand Down Expand Up @@ -157,6 +161,10 @@ tiledb_datatype_t _string_to_tiledb_datatype(std::string typestr) {
#if TILEDB_VERSION >= TileDB_Version(2,7,0)
} else if (typestr == "BLOB") {
return TILEDB_BLOB;
#endif
#if TILEDB_VERSION >= TileDB_Version(2,10,0)
} else if (typestr == "BOOL") {
return TILEDB_BOOL;
#endif
} else {
Rcpp::stop("Unknown TileDB type '%s'", typestr.c_str());
Expand Down Expand Up @@ -216,6 +224,10 @@ std::string tiledb_datatype_R_type(std::string datatype) {
return "DATETIME_US";
case TILEDB_DATETIME_NS:
return "DATETIME_NS";
#if TILEDB_VERSION >= TileDB_Version(2,10,0)
case TILEDB_BOOL:
return "BOOL";
#endif
default:
Rcpp::stop("unknown tiledb_datatype_t (%d)", dtype);
}
Expand Down Expand Up @@ -1364,11 +1376,18 @@ XPtr<tiledb::Attribute> libtiledb_attribute(XPtr<tiledb::Context> ctx,
attr_dtype == TILEDB_INT8 ||
attr_dtype == TILEDB_UINT8 ) {
attr = make_xptr<tiledb::Attribute>(new tiledb::Attribute(*ctx.get(), name, attr_dtype));
#if TILEDB_VERSION >= TileDB_Version(2,10,0)
} else if (attr_dtype == TILEDB_BOOL) {
attr = make_xptr<tiledb::Attribute>(new tiledb::Attribute(*ctx.get(), name, attr_dtype));
#endif
} else {
Rcpp::stop("Only integer ((U)INT{8,16,32,64}), logical (INT32), real (FLOAT{32,64}), "
"Date (DATEIME_DAY), Datetime (DATETIME_{SEC,MS,US}), "
"nanotime (DATETIME_NS) and character (CHAR,ASCII) attributes "
"are supported -- seeting %s which is not", type.c_str());
"Date (DATEIME_DAY), Datetime (DATETIME_{SEC,MS,US}), nanotime (DATETIME_NS), "
#if TILEDB_VERSION >= TileDB_Version(2,10,0)
"logical (BOOL), "
#endif
"and character (CHAR,ASCII) attributes are supported "
"-- seeing %s which is not", type.c_str());
}
attr->set_filter_list(*fltrlst);
#if TILEDB_VERSION >= TileDB_Version(2,2,0)
Expand Down Expand Up @@ -2560,7 +2579,7 @@ XPtr<tiledb::Query> libtiledb_query_set_buffer(XPtr<tiledb::Query> query,
#endif
return query;
} else if (TYPEOF(buffer) == LGLSXP) {
LogicalVector vec(buffer);
LogicalVector vec(buffer); // note that it is really an int at the element storage
#if TILEDB_VERSION >= TileDB_Version(2,4,0)
query->set_data_buffer(attr, vec.begin(), vec.length());
#else
Expand Down Expand Up @@ -2775,6 +2794,10 @@ XPtr<query_buf_t> libtiledb_query_buffer_alloc_ptr(std::string domaintype,
#if TILEDB_VERSION >= TileDB_Version(2,7,0)
} else if (domaintype == "BLOB") {
buf->size = sizeof(int8_t);
#endif
#if TILEDB_VERSION >= TileDB_Version(2,10,0)
} else if (domaintype == "BOOL") {
buf->size = sizeof(uint8_t);
#endif
} else if (domaintype == "INT64" ||
domaintype == "UINT64" ||
Expand Down Expand Up @@ -2928,6 +2951,18 @@ XPtr<query_buf_t> libtiledb_query_buffer_assign_ptr(XPtr<query_buf_t> buf, std::
x[i] = static_cast<float>(v[i]);
}
std::memcpy(buf->vec.data(), &(x[0]), buf->ncells*buf->size);
#if TILEDB_VERSION >= TileDB_Version(2,10,0)
} else if (dtype == "BOOL") {
LogicalVector v(vec);
auto n = v.length();
std::vector<uint8_t> x(n);
for (auto i=0; i<n; i++) {
x[i] = static_cast<uint8_t>(v[i]);
}
std::memcpy(buf->vec.data(), &(x[0]), buf->ncells*buf->size);
if (buf->nullable)
getValidityMapFromLogical(v, buf->validity_map);
#endif
} else {
Rcpp::stop("Assignment to '%s' currently unsupported.", dtype.c_str());
}
Expand Down Expand Up @@ -3100,6 +3135,19 @@ RObject libtiledb_query_get_buffer_ptr(XPtr<query_buf_t> buf, bool asint64 = fal
// if (buf->nullable)
// setValidityMapForRaw(out, buf->validity_map);
return out;
#endif
#if TILEDB_VERSION >= TileDB_Version(2,10,0)
} else if (dtype == "BOOL") {
size_t n = buf->ncells;
std::vector<uint8_t> uintvec(n);
std::memcpy(uintvec.data(), buf->vec.data(), n*buf->size);
Rcpp::LogicalVector out(buf->ncells);
for (size_t i=0; i<n; i++) {
out[i] = static_cast<int32_t>(uintvec[i]); // logical is int32_t internally
}
if (buf->nullable)
setValidityMapForLogical(out, buf->validity_map);
return out;
#endif
} else {
Rcpp::stop("Unsupported type '%s'", dtype.c_str());
Expand Down
2 changes: 2 additions & 0 deletions src/libtiledb.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ void getValidityMapFromNumeric(Rcpp::NumericVector & vec, std::vector<uint8_t> &
void setValidityMapForNumeric(Rcpp::NumericVector & vec, const std::vector<uint8_t> & map);
void getValidityMapFromInt64(Rcpp::NumericVector & vec, std::vector<uint8_t> & map);
void setValidityMapForInt64(std::vector<int64_t> & vec, const std::vector<uint8_t> & map);
void getValidityMapFromLogical(Rcpp::LogicalVector & vec, std::vector<uint8_t> & map);
void setValidityMapForLogical(Rcpp::LogicalVector & vec, const std::vector<uint8_t> & map);

// type and size helper
tiledb_datatype_t _string_to_tiledb_datatype(std::string typestr);
Expand Down
17 changes: 17 additions & 0 deletions src/nullable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,20 @@ void setValidityMapForInt64(std::vector<int64_t> & vec, const std::vector<uint8_
if (map[i] == 0)
vec[i] = NA_INTEGER64;
}

void getValidityMapFromLogical(Rcpp::LogicalVector & vec, std::vector<uint8_t> & map) {
if (static_cast<size_t>(vec.size()) != map.size())
Rcpp::stop("Unequal length between vector (%d) and map (%d) in int getter.", vec.size(), map.size());

for (auto i=0; i < vec.size(); i++)
map[i] = (vec[i] == NA_LOGICAL) ? 0 : 1;
}

void setValidityMapForLogical(Rcpp::LogicalVector & vec, const std::vector<uint8_t> & map) {
if (static_cast<size_t>(vec.size()) != map.size())
Rcpp::stop("Unequal length between vector (%d) and map (%d) in int setter.", vec.size(), map.size());

for (auto i=0; i < vec.size(); i++)
if (map[i] == 0)
vec[i] = NA_LOGICAL;
}