Skip to content

Commit f89fd12

Browse files
maxim-morozovMaxim Morozov
and
Maxim Morozov
authored
Enhancement: Implement for NFS and Azure storages (#2172)
#### Reference Issues/PRs Expose `Library.get_key_path` for NFS and Azure storages. #### What does this implement or fix? get_key_path will be used to determine where each key is located. This can help to set hard quotas for the platforms that support path based quotas, like VAST. #### Any other comments? #### Checklist <details> <summary> Checklist for code changes... </summary> - [ ] Have you updated the relevant docstrings, documentation and copyright notice? - [ ] Is this contribution tested against [all ArcticDB's features](../docs/mkdocs/docs/technical/contributing.md)? - [ ] Do all exceptions introduced raise appropriate [error messages](https://docs.arcticdb.io/error_messages/)? - [x] Are API changes highlighted in the PR description? - [x] Is the PR labelled as enhancement or bug so it appears in autogenerated release notes? </details> <!-- Thanks for contributing a Pull Request to ArcticDB! Please ensure you have taken a look at: - ArcticDB's Code of Conduct: https://github.com/man-group/ArcticDB/blob/master/CODE_OF_CONDUCT.md - ArcticDB's Contribution Licensing: https://github.com/man-group/ArcticDB/blob/master/docs/mkdocs/docs/technical/contributing.md#contribution-licensing --> --------- Co-authored-by: Maxim Morozov <[email protected]>
1 parent 79ec8d7 commit f89fd12

File tree

7 files changed

+84
-4
lines changed

7 files changed

+84
-4
lines changed

cpp/arcticdb/storage/azure/azure_storage.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,12 @@ bool AzureStorage::do_key_exists(const VariantKey& key) {
391391
return detail::do_key_exists_impl(key, root_folder_, *azure_client_);
392392
}
393393

394+
std::string AzureStorage::do_key_path(const VariantKey& key) const {
395+
auto b = FlatBucketizer{};
396+
auto key_type_dir = key_type_folder(root_folder_, variant_key_type(key));
397+
return object_path(b.bucketize(key_type_dir, key), key);
398+
}
399+
394400
} // namespace azure
395401

396402
} // namespace arcticdb::storage

cpp/arcticdb/storage/azure/azure_storage.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class AzureStorage final : public Storage {
6767
return false;
6868
}
6969

70-
std::string do_key_path(const VariantKey&) const final { return {}; };
70+
std::string do_key_path(const VariantKey&) const final;
7171

7272
private:
7373
std::unique_ptr<AzureClientWrapper> azure_client_;

cpp/arcticdb/storage/s3/nfs_backed_storage.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,12 @@ std::string NfsBackedStorage::name() const {
154154
return fmt::format("nfs_backed_storage-{}/{}/{}", region_, bucket_name_, root_folder_);
155155
}
156156

157+
std::string NfsBackedStorage::do_key_path(const VariantKey& key) const {
158+
auto b = NfsBucketizer{};
159+
auto key_type_dir = key_type_folder(root_folder_, variant_key_type(key));
160+
return object_path(b.bucketize(key_type_dir, key), key);
161+
}
162+
157163
void NfsBackedStorage::do_write(KeySegmentPair& key_seg) {
158164
auto enc = KeySegmentPair{encode_object_id(key_seg.variant_key()), key_seg.segment_ptr()};
159165
s3::detail::do_write_impl(enc, root_folder_, bucket_name_, *s3_client_, NfsBucketizer{});

cpp/arcticdb/storage/s3/nfs_backed_storage.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class NfsBackedStorage final : public Storage {
6565
return false;
6666
}
6767

68-
std::string do_key_path(const VariantKey&) const final { return {}; };
68+
std::string do_key_path(const VariantKey&) const final;
6969

7070
auto& client() { return s3_client_; }
7171
const std::string& bucket_name() const { return bucket_name_; }

cpp/arcticdb/storage/test/test_azure_storage.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,17 @@ TEST_F(AzureMockStorageFixture, test_matching_key_type_prefix_list) {
8484

8585
ASSERT_EQ(list_in_store(store, entity::KeyType::LOG), log_symbols);
8686
}
87+
88+
TEST_F(AzureMockStorageFixture, test_key_path) {
89+
std::vector<VariantKey> res;
90+
91+
store.iterate_type(KeyType::TABLE_DATA, [&](VariantKey &&found_key) {
92+
res.emplace_back(found_key);
93+
}, "");
94+
95+
for(auto vk: res) {
96+
auto key_path = store.key_path(vk);
97+
ASSERT_TRUE(key_path.size() > 0);
98+
ASSERT_TRUE(key_path.starts_with(store.library_path().to_delim_path('/')));
99+
}
100+
}

cpp/arcticdb/storage/test/test_s3_storage.cpp

+18-2
Original file line numberDiff line numberDiff line change
@@ -300,8 +300,24 @@ TEST_F(S3StorageFixture, test_key_exists) {
300300
ASSERT_TRUE(exists_in_store(store, "symbol"));
301301
ASSERT_FALSE(exists_in_store(store, "symbol-not-present"));
302302
ASSERT_THROW(
303-
exists_in_store(store, MockS3Client::get_failure_trigger("symbol", StorageOperation::EXISTS, Aws::S3::S3Errors::NETWORK_CONNECTION, false)),
304-
UnexpectedS3ErrorException);
303+
exists_in_store(store, MockS3Client::get_failure_trigger("symbol", StorageOperation::EXISTS,
304+
Aws::S3::S3Errors::NETWORK_CONNECTION, false)),
305+
UnexpectedS3ErrorException);
306+
}
307+
308+
TEST_P(S3AndNfsStorageFixture, test_key_path) {
309+
std::vector<VariantKey> res;
310+
311+
auto store = get_storage();
312+
store->iterate_type(KeyType::TABLE_DATA, [&](VariantKey &&found_key) {
313+
res.emplace_back(found_key);
314+
}, "");
315+
316+
for(auto vk : res) {
317+
auto key_path = store->key_path(vk);
318+
ASSERT_TRUE(key_path.size() > 0);
319+
ASSERT_TRUE(key_path.starts_with(get_root_folder(store->library_path())));
320+
}
305321
}
306322

307323
TEST_F(S3StorageFixture, test_read){

python/tests/integration/arcticdb/test_s3.py

+38
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from arcticdb_ext.storage import NoDataFoundException
1919

2020
from arcticdb_ext import set_config_string
21+
from arcticdb_ext.storage import KeyType
2122
from arcticdb.util.test import create_df, assert_frame_equal
2223

2324
from arcticdb.storage_fixtures.s3 import MotoNfsBackedS3StorageFixtureFactory
@@ -190,3 +191,40 @@ def test_wrapped_s3_storage(lib_name, wrapped_s3_storage_bucket):
190191
# There should be no problems after the failure simulation has been turned off
191192
lib.read("s")
192193
lib.write("s", data=create_df())
194+
195+
196+
@pytest.fixture(scope="session")
197+
def test_prefix():
198+
return "test_bucket_prefix"
199+
200+
201+
@pytest.fixture(scope="function",
202+
params=[MotoNfsBackedS3StorageFixtureFactory,
203+
MotoS3StorageFixtureFactory])
204+
def storage_bucket(test_prefix, request):
205+
with request.param(
206+
use_ssl=False,
207+
ssl_test_support=False,
208+
bucket_versioning=False,
209+
default_prefix=test_prefix
210+
) as factory:
211+
with factory.create_fixture() as bucket:
212+
yield bucket
213+
214+
215+
def test_library_get_key_path(lib_name, storage_bucket, test_prefix):
216+
lib = storage_bucket.create_version_store_factory(lib_name)()
217+
lib.write("s", data=create_df())
218+
lib_tool = lib.library_tool()
219+
220+
keys_count = 0
221+
for key_type in KeyType.__members__.values():
222+
keys = lib_tool.find_keys(key_type)
223+
keys_count += len(keys)
224+
for key in keys:
225+
path = lib_tool.get_key_path(key)
226+
assert path != ""
227+
assert path.startswith(test_prefix)
228+
229+
assert keys_count > 0
230+

0 commit comments

Comments
 (0)