From afebd9421efd11f5e4ca1c011275a846acccb655 Mon Sep 17 00:00:00 2001 From: Beka Davis <31743465+bekadavis9@users.noreply.github.com> Date: Wed, 12 Apr 2023 16:23:32 -0400 Subject: [PATCH] Add MemFS context isolation test, and use memfs in quickstart dense example. (#3438) TYPE: EXAMPLE DESC: Add MemFS context isolation test, and use memfs in quickstart dense example. --- examples/cpp_api/quickstart_dense.cc | 46 +++++++++++------------- test/src/unit-cppapi-array.cc | 51 +++++++++++++++++++++++++++ tiledb/sm/filesystem/mem_filesystem.h | 6 ++++ 3 files changed, 78 insertions(+), 25 deletions(-) diff --git a/examples/cpp_api/quickstart_dense.cc b/examples/cpp_api/quickstart_dense.cc index f6b94a31371..fe6bc8384d7 100644 --- a/examples/cpp_api/quickstart_dense.cc +++ b/examples/cpp_api/quickstart_dense.cc @@ -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 @@ -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 @@ -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(ctx, "rows", {{1, 4}}, 4)) - .add_dimension(Dimension::create(ctx, "cols", {{1, 4}}, 4)); + Domain domain(ctx_); + domain.add_dimension(Dimension::create(ctx_, "rows", {{1, 4}}, 4)) + .add_dimension(Dimension::create(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(ctx, "a")); + schema.add_attribute(Attribute::create(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 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. @@ -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 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); @@ -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(); } diff --git a/test/src/unit-cppapi-array.cc b/test/src/unit-cppapi-array.cc index dc8186679a4..904b280f106 100644 --- a/test/src/unit-cppapi-array.cc +++ b/test/src/unit-cppapi-array.cc @@ -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(ctx, "rows", {{1, 4}}, 4)) + .add_dimension(Dimension::create(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(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 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 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 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]") { diff --git a/tiledb/sm/filesystem/mem_filesystem.h b/tiledb/sm/filesystem/mem_filesystem.h index e8bb8b610ed..dec513176f8 100644 --- a/tiledb/sm/filesystem/mem_filesystem.h +++ b/tiledb/sm/filesystem/mem_filesystem.h @@ -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: /* ********************************* */