-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Keita Iwabuchi
committed
Mar 1, 2024
1 parent
16b09d3
commit 0aa7883
Showing
11 changed files
with
739 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
if (Boost_VERSION_STRING VERSION_GREATER_EQUAL "1.75") | ||
add_metall_executable(string_key_store string_key_store.cpp) | ||
endif() | ||
endif() | ||
|
||
add_subdirectory(string_container) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
add_metall_executable(string_container string_container.cpp) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// Copyright 2024 Lawrence Livermore National Security, LLC and other Metall | ||
// Project Developers. See the top-level COPYRIGHT file for details. | ||
// | ||
// SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||
|
||
#include <iostream> | ||
#include <string> | ||
|
||
#include <metall/metall.hpp> | ||
#include <metall/container/experimental/string_container/deque.hpp> | ||
#include <metall/container/experimental/string_container/map_from_string.hpp> | ||
#include <metall/container/experimental/string_container/map_to_string.hpp> | ||
|
||
using namespace metall::container::experimental::string_container; | ||
|
||
int main() { | ||
// Create a new datastore | ||
{ | ||
metall::manager manager(metall::create_only, "/tmp/datastore"); | ||
|
||
// ----------------------------------------------------- | ||
// Main string table | ||
auto *main_table = manager.construct<string_table<>>( | ||
metall::unique_instance)(manager.get_allocator<>()); | ||
|
||
// ----------------------------------------------------- | ||
// map from string (map<string, int>) | ||
auto *map_from_str_1 = | ||
manager.construct<map_from_string<int>>("map1")(main_table); | ||
|
||
// map operations | ||
(*map_from_str_1)["hello"] = 0; | ||
(*map_from_str_1)["world"] = 1; | ||
|
||
// another map that shares the same string table | ||
auto *map_from_str_2 = | ||
manager.construct<map_from_string<int>>("map2")(main_table); | ||
|
||
(*map_from_str_2)[std::string("hello")] = 10; | ||
(*map_from_str_2)["universe"] = 11; | ||
|
||
// ----------------------------------------------------- | ||
// map to string (map<int, string>) | ||
auto *map_to_str = | ||
manager.construct<map_to_string<int>>("map3")(main_table); | ||
|
||
(*map_to_str)[0] = "hello"; | ||
(*map_to_str)[1] = "virtual world"; | ||
|
||
// ----------------------------------------------------- | ||
// Deque | ||
auto *dq = manager.construct<deque<>>("dq")(main_table); | ||
dq->push_back("hello"); | ||
dq->resize(2); // 2nd element is empty | ||
} | ||
|
||
// open the existing containers | ||
{ | ||
metall::manager manager(metall::open_read_only, "/tmp/datastore"); | ||
|
||
auto *main_table = | ||
manager.find<string_table<>>(metall::unique_instance).first; | ||
auto *map_from_str_1 = manager.find<map_from_string<int>>("map1").first; | ||
auto *map_from_str_2 = manager.find<map_from_string<int>>("map2").first; | ||
auto *map_to_str = manager.find<map_to_string<int>>("map3").first; | ||
auto *dq = manager.find<deque<>>("dq").first; | ||
|
||
std::cout << "\nmap_from_str_1" << std::endl; | ||
std::cout << "hello: " << (*map_from_str_1)["hello"] << std::endl; | ||
std::cout << "world: " << (*map_from_str_1)["world"] << std::endl; | ||
|
||
std::cout << "\nmap_from_str_2" << std::endl; | ||
for (const auto &[k, v] : *map_from_str_2) { | ||
std::cout << k << ": " << v << std::endl; | ||
} | ||
|
||
std::cout << "\nmap_to_str" << std::endl; | ||
for (const auto &[k, v] : *map_to_str) { | ||
std::cout << k << ": " << v << std::endl; | ||
} | ||
|
||
std::cout << "\ndeque" << std::endl; | ||
for (std::size_t i = 0; i < dq->size(); ++i) { | ||
std::cout << i << ": " << (*dq)[i] << std::endl; | ||
} | ||
|
||
// NOTE: empty string ("") is also stored in the string table | ||
std::cout << "\n#of unique strings: " << main_table->size() << std::endl; | ||
} | ||
|
||
return 0; | ||
} |
73 changes: 73 additions & 0 deletions
73
include/metall/container/experimental/string_container/deque.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// Copyright 2024 Lawrence Livermore National Security, LLC and other Metall | ||
// Project Developers. See the top-level COPYRIGHT file for details. | ||
// | ||
// SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||
|
||
#ifndef METALL_CONTAINER_EXPERIMENT_STRING_CONTAINER_DEQUE_HPP | ||
#define METALL_CONTAINER_EXPERIMENT_STRING_CONTAINER_DEQUE_HPP | ||
|
||
#include <memory> | ||
|
||
#include <metall/container/deque.hpp> | ||
|
||
#include <metall/container/experimental/string_container/string_table.hpp> | ||
#include <metall/container/experimental/string_container/string.hpp> | ||
|
||
namespace metall::container::experimental::string_container { | ||
|
||
/// \brief A deque container that stores string using the string_table. | ||
template <typename StringTable = string_table<>> | ||
class deque { | ||
public: | ||
using allocator_type = typename StringTable::allocator_type; | ||
|
||
private: | ||
using string_table_type = StringTable; | ||
using string_type = string<string_table_type>; | ||
using deque_type = metall::container::deque< | ||
string_type, std::scoped_allocator_adaptor<typename std::allocator_traits< | ||
allocator_type>::template rebind_alloc<string_type>>>; | ||
|
||
public: | ||
explicit deque(string_table_type *string_table) | ||
: m_string_table(string_table), m_deque(string_table->get_allocator()) {} | ||
|
||
string_type &operator[](const std::size_t i) { return m_deque[i]; } | ||
|
||
template <typename Str> | ||
void push_back(const Str &str) { | ||
m_deque.emplace_back(metall::to_raw_pointer(m_string_table)); | ||
m_deque.back() = str; | ||
} | ||
|
||
void pop_back() { m_deque.pop_back(); } | ||
|
||
void resize(const std::size_t n) { | ||
m_deque.resize(n, string_type(metall::to_raw_pointer(m_string_table))); | ||
} | ||
|
||
void clear() { m_deque.clear(); } | ||
|
||
std::size_t size() const { return m_deque.size(); } | ||
|
||
bool empty() const { return m_deque.empty(); } | ||
|
||
void reserve(const std::size_t n) { m_deque.reserve(n); } | ||
|
||
auto begin() { return m_deque.begin(); } | ||
auto end() { return m_deque.end(); } | ||
auto begin() const { return m_deque.begin(); } | ||
auto end() const { return m_deque.end(); } | ||
|
||
allocator_type get_allocator() const { return m_deque.get_allocator(); } | ||
|
||
private: | ||
using string_table_ptr_type = | ||
typename std::pointer_traits<typename std::allocator_traits< | ||
allocator_type>::pointer>::template rebind<string_table_type>; | ||
|
||
string_table_ptr_type m_string_table; | ||
deque_type m_deque; | ||
}; | ||
} // namespace metall::container::experimental::string_container | ||
#endif |
106 changes: 106 additions & 0 deletions
106
include/metall/container/experimental/string_container/map_from_string.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
// Copyright 2024 Lawrence Livermore National Security, LLC and other Metall | ||
// Project Developers. See the top-level COPYRIGHT file for details. | ||
// | ||
// SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||
|
||
#ifndef METALL_CONTAINER_EXPERIMENT_STRING_CONTAINER_MAP_FROM_STRING_HPP | ||
#define METALL_CONTAINER_EXPERIMENT_STRING_CONTAINER_MAP_FROM_STRING_HPP | ||
|
||
#include <memory> | ||
|
||
#include <metall/container/scoped_allocator.hpp> | ||
#include <metall/container/map.hpp> | ||
|
||
#include <metall/container/experimental/string_container/string_table.hpp> | ||
#include <metall/container/experimental/string_container/string.hpp> | ||
|
||
namespace metall::container::experimental::string_container { | ||
|
||
/// \brief A map container that string as keys. Internally, it uses | ||
/// string_container::string_table to store the keys. | ||
/// \tparam T Type of the value. | ||
/// \tparam StringTable Type of the string table. | ||
template <class T, typename StringTable = string_table<>> | ||
class map_from_string { | ||
public: | ||
using key_type = string<StringTable>; | ||
using mapped_type = T; | ||
using allocator_type = typename StringTable::allocator_type; | ||
|
||
private: | ||
using string_table_type = StringTable; | ||
using key_locator_type = typename string_table_type::locator_type; | ||
using map_type = metall::container::map< | ||
key_type, mapped_type, std::less<key_type>, | ||
std::scoped_allocator_adaptor< | ||
typename std::allocator_traits<allocator_type>::template rebind_alloc< | ||
std::pair<const key_type, mapped_type>>>>; | ||
|
||
public: | ||
explicit map_from_string(string_table_type *const string_table) | ||
: m_string_table(string_table), m_map(string_table->get_allocator()) {} | ||
|
||
map_from_string(const map_from_string &) = default; | ||
map_from_string(map_from_string &&) noexcept = default; | ||
map_from_string &operator=(const map_from_string &) = default; | ||
map_from_string &operator=(map_from_string &&) noexcept = default; | ||
|
||
~map_from_string() noexcept = default; | ||
|
||
template <typename K> | ||
mapped_type &operator[](const K &key) { | ||
return m_map[get_key(key)]; | ||
} | ||
|
||
template <typename K> | ||
const mapped_type &at(const K &key) const { | ||
assert(m_string_table->contains(key) && | ||
"The key does not exist in the string table"); | ||
return m_map.at(get_key(key)); | ||
} | ||
|
||
template <typename K> | ||
bool contains(const K &key) const { | ||
return m_string_table->contains(key) && m_map.contains(get_key(key)); | ||
} | ||
|
||
void clear() { m_map.clear(); } | ||
|
||
std::size_t size() const { return m_map.size(); } | ||
|
||
bool empty() const { return m_map.empty(); } | ||
|
||
void reserve(const std::size_t n) { m_map.reserve(n); } | ||
|
||
auto begin() { return m_map.begin(); } | ||
auto end() { return m_map.end(); } | ||
auto begin() const { return m_map.begin(); } | ||
auto end() const { return m_map.end(); } | ||
|
||
allocator_type get_allocator() const { return m_map.get_allocator(); } | ||
|
||
private: | ||
using string_table_ptr_type = | ||
typename std::pointer_traits<typename std::allocator_traits< | ||
allocator_type>::pointer>::template rebind<string_table_type>; | ||
|
||
template <typename K> | ||
key_type get_key(const K &key) { | ||
const auto loc = m_string_table->insert(key); | ||
key_type new_key(metall::to_raw_pointer(m_string_table), loc); | ||
return new_key; | ||
} | ||
|
||
template <typename K> | ||
key_type get_key(const K &key) const { | ||
const auto loc = m_string_table->to_locator(key); | ||
key_type new_key(metall::to_raw_pointer(m_string_table), loc); | ||
return new_key; | ||
} | ||
|
||
string_table_ptr_type m_string_table; | ||
map_type m_map; | ||
}; | ||
|
||
} // namespace metall::container::experimental::string_container | ||
#endif |
101 changes: 101 additions & 0 deletions
101
include/metall/container/experimental/string_container/map_to_string.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
// Copyright 2024 Lawrence Livermore National Security, LLC and other Metall | ||
// Project Developers. See the top-level COPYRIGHT file for details. | ||
// | ||
// SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||
|
||
#ifndef METALL_CONTAINER_EXPERIMENT_STRING_CONTAINER_MAP_TO_STRING_HPP | ||
#define METALL_CONTAINER_EXPERIMENT_STRING_CONTAINER_MAP_TO_STRING_HPP | ||
|
||
#include <memory> | ||
|
||
#include <metall/container/scoped_allocator.hpp> | ||
#include <metall/container/map.hpp> | ||
|
||
#include <metall/container/experimental/string_container/string_table.hpp> | ||
#include <metall/container/experimental/string_container/string.hpp> | ||
|
||
namespace metall::container::experimental::string_container { | ||
|
||
/// \brief A map container that uses string as value and Metall as its default | ||
/// allocator. Internally, it uses string_container::string_table to store the | ||
/// strings. The value is immutable. | ||
/// \tparam Key Type of the key. | ||
/// \tparam Allocator Type of the allocator. | ||
template <class Key, typename StringTable = string_table<>> | ||
class map_to_string { | ||
public: | ||
using key_type = Key; | ||
using mapped_type = string<StringTable>; | ||
using allocator_type = typename StringTable::allocator_type; | ||
|
||
private: | ||
using string_table_type = StringTable; | ||
using string_type = string<string_table_type>; | ||
|
||
public: | ||
using map_type = metall::container::map< | ||
key_type, string_type, std::less<key_type>, | ||
std::scoped_allocator_adaptor< | ||
typename std::allocator_traits<allocator_type>::template rebind_alloc< | ||
std::pair<const key_type, string_type>>>>; | ||
|
||
explicit map_to_string(string_table_type *const string_table) | ||
: m_string_table(string_table), m_map(string_table->get_allocator()) {} | ||
|
||
map_to_string(const map_to_string &) = default; | ||
map_to_string(map_to_string &&) noexcept = default; | ||
map_to_string &operator=(const map_to_string &) = default; | ||
map_to_string &operator=(map_to_string &&) noexcept = default; | ||
|
||
~map_to_string() noexcept = default; | ||
|
||
template <typename K> | ||
mapped_type &operator[](const K &key) { | ||
if (m_map.count(key) == 0) { | ||
m_map.emplace(key_type(key), | ||
mapped_type(metall::to_raw_pointer(m_string_table))); | ||
} | ||
return m_map.at(key_type(key)); | ||
} | ||
|
||
template <typename K> | ||
const mapped_type &at(const K &key) const { | ||
return m_map.at(key_type(key)); | ||
} | ||
|
||
template <typename K> | ||
mapped_type &at(const K &key) { | ||
return m_map.at(key_type(key)); | ||
} | ||
|
||
template <typename K> | ||
bool contains(const K &key) const { | ||
return m_map.count(key) > 0; | ||
} | ||
|
||
void clear() { m_map.clear(); } | ||
|
||
std::size_t size() const { return m_map.size(); } | ||
|
||
bool empty() const { return m_map.empty(); } | ||
|
||
void reserve(const std::size_t n) { m_map.reserve(n); } | ||
|
||
auto begin() { return m_map.begin(); } | ||
auto end() { return m_map.end(); } | ||
auto begin() const { return m_map.begin(); } | ||
auto end() const { return m_map.end(); } | ||
|
||
allocator_type get_allocator() const { return m_map.get_allocator(); } | ||
|
||
private: | ||
using string_table_ptr_type = | ||
typename std::pointer_traits<typename std::allocator_traits< | ||
allocator_type>::pointer>::template rebind<string_table_type>; | ||
|
||
string_table_ptr_type m_string_table; | ||
map_type m_map; | ||
}; | ||
|
||
} // namespace metall::container::experimental::string_container | ||
#endif |
Oops, something went wrong.