Skip to content

Commit

Permalink
Add MemFS context isolation test, and use memfs in quickstart dense e…
Browse files Browse the repository at this point in the history
…xample. (#3438)

TYPE: EXAMPLE
DESC: Add MemFS context isolation test, and use memfs in quickstart dense example.
  • Loading branch information
bekadavis9 authored Apr 12, 2023
1 parent 13b352a commit afebd94
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 25 deletions.
46 changes: 21 additions & 25 deletions examples/cpp_api/quickstart_dense.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* The MIT License
*
* @copyright Copyright (c) 2018-2022 TileDB, Inc.
* @copyright Copyright (c) 2018-2023 TileDB, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand All @@ -27,8 +27,10 @@
*
* @section DESCRIPTION
*
* When run, this program will create a simple 2D dense array, write some data
* to it, and read a slice of the data back.
* When run, this program will create a simple 2D dense array on memfs,
* write some data to it, and read a slice of the data back.
*
* Note: MemFS lives on a single VFS instance on a global Context object
*/

#include <iostream>
Expand All @@ -37,38 +39,36 @@
using namespace tiledb;

// Name of array.
std::string array_name("quickstart_dense_array");
std::string array_name_("mem://quickstart_dense_array");

void create_array() {
// Create a TileDB context.
Context ctx;
// Example-global Context object.
Context ctx_;

void create_array() {
// The array will be 4x4 with dimensions "rows" and "cols", with domain [1,4].
Domain domain(ctx);
domain.add_dimension(Dimension::create<int>(ctx, "rows", {{1, 4}}, 4))
.add_dimension(Dimension::create<int>(ctx, "cols", {{1, 4}}, 4));
Domain domain(ctx_);
domain.add_dimension(Dimension::create<int>(ctx_, "rows", {{1, 4}}, 4))
.add_dimension(Dimension::create<int>(ctx_, "cols", {{1, 4}}, 4));

// The array will be dense.
ArraySchema schema(ctx, TILEDB_DENSE);
ArraySchema schema(ctx_, TILEDB_DENSE);
schema.set_domain(domain).set_order({{TILEDB_ROW_MAJOR, TILEDB_ROW_MAJOR}});

// Add a single attribute "a" so each (i,j) cell can store an integer.
schema.add_attribute(Attribute::create<int>(ctx, "a"));
schema.add_attribute(Attribute::create<int>(ctx_, "a"));

// Create the (empty) array on disk.
Array::create(array_name, schema);
Array::create(array_name_, schema);
}

void write_array() {
Context ctx;

// Prepare some data for the array
std::vector<int> data = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};

// Open the array for writing and create the query.
Array array(ctx, array_name, TILEDB_WRITE);
Query query(ctx, array, TILEDB_WRITE);
Array array(ctx_, array_name_, TILEDB_WRITE);
Query query(ctx_, array, TILEDB_WRITE);
query.set_layout(TILEDB_ROW_MAJOR).set_data_buffer("a", data);

// Perform the write and close the array.
Expand All @@ -77,20 +77,18 @@ void write_array() {
}

void read_array() {
Context ctx;

// Prepare the array for reading
Array array(ctx, array_name, TILEDB_READ);
Array array(ctx_, array_name_, TILEDB_READ);

// Slice only rows 1, 2 and cols 2, 3, 4
Subarray subarray(ctx, array);
Subarray subarray(ctx_, array);
subarray.add_range(0, 1, 2).add_range(1, 2, 4);

// Prepare the vector that will hold the result (of size 6 elements)
std::vector<int> data(6);

// Prepare the query
Query query(ctx, array, TILEDB_READ);
Query query(ctx_, array, TILEDB_READ);
query.set_subarray(subarray)
.set_layout(TILEDB_ROW_MAJOR)
.set_data_buffer("a", data);
Expand All @@ -106,9 +104,7 @@ void read_array() {
}

int main() {
Context ctx;

if (Object::object(ctx, array_name).type() != Object::Type::Array) {
if (Object::object(ctx_, array_name_).type() != Object::Type::Array) {
create_array();
write_array();
}
Expand Down
51 changes: 51 additions & 0 deletions test/src/unit-cppapi-array.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1825,6 +1825,57 @@ TEST_CASE(
std::string::npos);
}

TEST_CASE("C++ API: Array write and read from MemFS", "[cppapi][memfs]") {
const std::string array_name = "mem://cpp_unit_array";
Context ctx;

// Create
Domain domain(ctx);
domain.add_dimension(Dimension::create<int>(ctx, "rows", {{1, 4}}, 4))
.add_dimension(Dimension::create<int>(ctx, "cols", {{1, 4}}, 4));
ArraySchema schema(ctx, TILEDB_DENSE);
schema.set_domain(domain).set_order({{TILEDB_ROW_MAJOR, TILEDB_ROW_MAJOR}});
schema.add_attribute(Attribute::create<int>(ctx, "a"));
Array::create(array_name, schema);

// Try writing on a non-process-global Context
Context ctx_non_global;
REQUIRE_THROWS_WITH(
Array(ctx_non_global, array_name, TILEDB_WRITE),
Catch::Matchers::ContainsSubstring(
"Cannot open array; Array does not exist"));

// Write
std::vector<int> data_w = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
Array array_w(ctx, array_name, TILEDB_WRITE);
Query query_w(ctx, array_w);
query_w.set_layout(TILEDB_ROW_MAJOR).set_data_buffer("a", data_w);
query_w.submit();
array_w.close();

// Read
Array array(ctx, array_name, TILEDB_READ);
Query query(ctx, array, TILEDB_READ);
std::vector<int> data(6);
query.add_range(0, 1, 2)
.add_range(1, 2, 4)
.set_layout(TILEDB_ROW_MAJOR)
.set_data_buffer("a", data);
query.submit();
array.close();
std::vector<int> data_expected = {2, 3, 4, 6, 7, 8};
for (int i = 0; i < 6; i++) {
REQUIRE(data[i] == data_expected[i]);
}

// Try removing on a different VFS instance
VFS vfs(ctx);
REQUIRE_THROWS_WITH(
vfs.remove_dir(array_name),
Catch::Matchers::ContainsSubstring("File not found, remove failed"));
}

TEST_CASE(
"C++ API: Write and read to an array with experimental build enabled",
"[cppapi][array][experimental]") {
Expand Down
6 changes: 6 additions & 0 deletions tiledb/sm/filesystem/mem_filesystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ namespace sm {

class URI;

/**
* The in-memory filesystem.
*
* @invariant The MemFilesystem is associated with a single VFS instance.
* @invariant The MemFilesystem exists on a single, global Context.
*/
class MemFilesystem {
public:
/* ********************************* */
Expand Down

0 comments on commit afebd94

Please sign in to comment.