Skip to content

Commit 511d8ad

Browse files
committed
Add VFS support for tiledb:// URIs.
1 parent 5b3c5ce commit 511d8ad

File tree

4 files changed

+216
-2
lines changed

4 files changed

+216
-2
lines changed

tiledb/api/c_api/filesystem/filesystem_api_enum.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,6 @@
4040
TILEDB_FILESYSTEM_ENUM(GCS) = 3,
4141
/** In-memory filesystem */
4242
TILEDB_FILESYSTEM_ENUM(MEMFS) = 4,
43+
/** TileDB filesystem */
44+
TILEDB_FILESYSTEM_ENUM(TILEDBFS) = 5,
4345
#endif

tiledb/sm/filesystem/failing_fs.h

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/**
2+
* @file failing_fs.h
3+
*
4+
* @section LICENSE
5+
*
6+
* The MIT License
7+
*
8+
* @copyright Copyright (c) 2025 TileDB, Inc.
9+
*
10+
* Permission is hereby granted, free of charge, to any person obtaining a copy
11+
* of this software and associated documentation files (the "Software"), to deal
12+
* in the Software without restriction, including without limitation the rights
13+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14+
* copies of the Software, and to permit persons to whom the Software is
15+
* furnished to do so, subject to the following conditions:
16+
*
17+
* The above copyright notice and this permission notice shall be included in
18+
* all copies or substantial portions of the Software.
19+
*
20+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26+
* THE SOFTWARE.
27+
*
28+
* @section DESCRIPTION
29+
*
30+
* This file defines the FailingFS class.
31+
*/
32+
33+
#ifndef TILEDB_FAILINGFS_H
34+
#define TILEDB_FAILINGFS_h
35+
36+
#include "tiledb/common/assert.h"
37+
#include "tiledb/sm/filesystem/filesystem_base.h"
38+
39+
namespace tiledb::sm {
40+
/**
41+
* Implements FilesystemBase by always throwing FilesystemException.
42+
*/
43+
class FailingFS : public FilesystemBase {
44+
public:
45+
/**
46+
* Constructor.
47+
*
48+
* @param uri_scheme The URI scheme this object will claim to support.
49+
* @param message The message of the exceptions this object's operations will throw.
50+
*/
51+
FailingFS(const std::string& uri_scheme, const std::string& message = "")
52+
: uri_scheme_(uri_scheme)
53+
, message_(message) {
54+
iassert(!uri_scheme.empty());
55+
}
56+
57+
bool supports_uri(const URI& uri) const override {
58+
return uri.backend_name() == uri_scheme_;
59+
}
60+
61+
virtual void create_dir(const URI&) const override {
62+
throw get_exception();
63+
}
64+
65+
virtual void touch(const URI&) const override {
66+
throw get_exception();
67+
}
68+
69+
virtual bool is_dir(const URI&) const override {
70+
throw get_exception();
71+
}
72+
73+
virtual bool is_file(const URI&) const override {
74+
throw get_exception();
75+
}
76+
77+
virtual void remove_dir(const URI&) const override {
78+
throw get_exception();
79+
}
80+
81+
virtual void remove_file(const URI&) const override {
82+
throw get_exception();
83+
}
84+
85+
virtual uint64_t file_size(const URI&) const override {
86+
throw get_exception();
87+
}
88+
89+
virtual std::vector<tiledb::common::filesystem::directory_entry>
90+
ls_with_sizes(const URI&) const override {
91+
throw get_exception();
92+
}
93+
94+
virtual LsObjects ls_filtered(const URI&, ResultFilter, bool) const override {
95+
throw get_exception();
96+
}
97+
98+
virtual LsObjects ls_filtered_v2(
99+
const URI&, ResultFilterV2, bool) const override {
100+
throw get_exception();
101+
}
102+
103+
virtual void move_file(const URI&, const URI&) const override {
104+
throw get_exception();
105+
}
106+
107+
virtual void move_dir(const URI&, const URI&) const override {
108+
throw get_exception();
109+
}
110+
111+
virtual void copy_file(const URI&, const URI&) const override {
112+
throw get_exception();
113+
}
114+
115+
virtual void copy_dir(const URI&, const URI&) const override {
116+
throw get_exception();
117+
}
118+
119+
virtual uint64_t read(const URI&, uint64_t, void*, uint64_t) override {
120+
throw get_exception();
121+
}
122+
123+
virtual void flush(const URI&, bool) override {
124+
throw get_exception();
125+
}
126+
127+
void sync(const URI&) const override {
128+
throw get_exception();
129+
}
130+
131+
virtual void write(const URI&, const void*, uint64_t, bool) override {
132+
throw get_exception();
133+
}
134+
135+
virtual bool is_bucket(const URI&) const override {
136+
throw get_exception();
137+
}
138+
139+
virtual bool is_empty_bucket(const URI&) const override {
140+
throw get_exception();
141+
}
142+
143+
virtual void create_bucket(const URI&) const override {
144+
throw get_exception();
145+
}
146+
147+
virtual void remove_bucket(const URI&) const override {
148+
throw get_exception();
149+
}
150+
151+
virtual void empty_bucket(const URI&) const override {
152+
throw get_exception();
153+
}
154+
155+
private:
156+
const std::string uri_scheme_, message_;
157+
158+
FilesystemException get_exception() const {
159+
return FilesystemException(message_);
160+
}
161+
};
162+
} // namespace tiledb::sm
163+
#endif // TILEDB_FAILINGFS_H

tiledb/sm/filesystem/vfs.cc

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "tiledb/sm/buffer/buffer.h"
3939
#include "tiledb/sm/enums/filesystem.h"
4040
#include "tiledb/sm/enums/vfs_mode.h"
41+
#include "tiledb/sm/filesystem/failing_fs.h"
4142
#include "tiledb/sm/misc/parallel_functions.h"
4243
#include "tiledb/sm/misc/tdb_math.h"
4344
#include "tiledb/sm/stats/global_stats.h"
@@ -54,6 +55,39 @@ using namespace tiledb::sm::filesystem;
5455

5556
namespace tiledb::sm {
5657

58+
namespace {
59+
#ifdef HAVE_S3
60+
tdb_unique_ptr<FilesystemBase> make_tiledb_fs_failing(
61+
const std::string& detail = "") {
62+
return tdb_unique_ptr<FilesystemBase>(tdb_new(
63+
FailingFS, "tiledb", "TileDB FS VFS not configured; " + detail));
64+
}
65+
66+
tdb_unique_ptr<FilesystemBase> make_tiledbfs(
67+
stats::Stats* parent_stats, ThreadPool* tp, const Config& config) {
68+
auto rest_server =
69+
config.get<std::string>("rest.server_address", Config::must_find);
70+
if (rest_server.ends_with('/')) {
71+
size_t pos = rest_server.find_last_not_of('/');
72+
rest_server.resize(pos + 1);
73+
}
74+
if (rest_server.empty()) {
75+
return make_tiledb_fs_failing("missing rest.server_address config option");
76+
}
77+
Config new_config{config};
78+
throw_if_not_ok(new_config.set("vfs.s3.endpoint_override", rest_server + "/v4/files"));
79+
auto token = config.get<std::string>("rest.token", Config::must_find);
80+
if (!token.empty()) {
81+
throw_if_not_ok(new_config.set("vfs.s3.aws_access_key_id", token));
82+
throw_if_not_ok(new_config.set("vfs.s3.aws_secret_access_key", "unused"));
83+
}
84+
throw_if_not_ok(new_config.set("vfs.s3.use_virtual_addressing", "false"));
85+
return tdb_unique_ptr<FilesystemBase>(
86+
tdb_new(S3, parent_stats, tp, new_config));
87+
}
88+
#endif
89+
} // namespace
90+
5791
/* ********************************* */
5892
/* CONSTRUCTORS & DESTRUCTORS */
5993
/* ********************************* */
@@ -68,6 +102,10 @@ VFS::VFS(
68102
, Azure_within_VFS(io_tp, config)
69103
, GCS_within_VFS(io_tp, config)
70104
, S3_within_VFS(stats_, io_tp, config)
105+
, local_(config)
106+
#ifdef HAVE_S3
107+
, tiledbfs_(make_tiledbfs(parent_stats, io_tp, config))
108+
#endif
71109
, config_(config)
72110
, logger_(logger)
73111
, compute_tp_(compute_tp)
@@ -83,6 +121,7 @@ VFS::VFS(
83121

84122
if constexpr (s3_enabled) {
85123
supported_fs_.insert(Filesystem::S3);
124+
supported_fs_.insert(Filesystem::TILEDBFS);
86125
}
87126

88127
#ifdef HAVE_AZURE
@@ -93,8 +132,6 @@ VFS::VFS(
93132
supported_fs_.insert(Filesystem::GCS);
94133
#endif
95134

96-
local_ = LocalFS(config_);
97-
98135
supported_fs_.insert(Filesystem::MEMFS);
99136
}
100137

@@ -130,6 +167,14 @@ const FilesystemBase& VFS::get_fs(const URI& uri) const {
130167
if (uri.is_memfs()) {
131168
return memfs_;
132169
}
170+
if (uri.is_tiledb()) {
171+
#ifdef HAVE_S3
172+
return *tiledbfs_;
173+
#else
174+
throw VFSException(
175+
"TileDB was built without S3 support, which is required for TileDB FS");
176+
#endif
177+
}
133178
throw UnsupportedURI(uri.to_string());
134179
}
135180

tiledb/sm/filesystem/vfs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,10 @@ class VFS : FilesystemBase,
10021002

10031003
LocalFS local_;
10041004

1005+
#if HAVE_S3
1006+
tdb_unique_ptr<FilesystemBase> tiledbfs_;
1007+
#endif
1008+
10051009
/** The in-memory filesystem which is always supported */
10061010
MemFilesystem memfs_;
10071011

0 commit comments

Comments
 (0)