Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
file_b_map_test.cc
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7*/
8
9#include <gtest/gtest.h>
10
11#include <atomic>
12#include <chrono>
13#include <filesystem>
14#include <optional>
15#include <random>
16#include <string>
17#include <utility>
18#include <vector>
19
20#include <tpl_file_b_map.H>
21
22using namespace Aleph;
23
24namespace
25{
26 namespace fs = std::filesystem;
27
28 fs::path make_temp_path()
29 {
30 static std::atomic<unsigned long long> counter{0};
31 // Use a per-process random generator to avoid filename collisions
32 // across parallel processes.
33 static std::mt19937_64 rng{[] {
34 std::random_device rd;
35 const auto now_seed =
36 static_cast<unsigned long long>
37 (std::chrono::steady_clock::now().time_since_epoch().count());
38 return std::mt19937_64{now_seed ^
39 (static_cast<unsigned long long>(rd()) << 1u)};
40 }()};
41
42 const auto now = std::chrono::steady_clock::now().time_since_epoch().count();
43 std::uniform_int_distribution<unsigned long long> dist;
44 const auto random_value = dist(rng);
45
46 const auto id = std::to_string(now) + "_" +
47 std::to_string(random_value) + "_" +
48 std::to_string(counter++);
49
50 const fs::path dir = fs::temp_directory_path() / "aleph_file_bmap_tests";
51 fs::create_directories(dir);
52 return dir / (id + ".idx");
53 }
54
55 struct TempFile
56 {
57 fs::path path;
58
59 explicit TempFile(fs::path p) : path(std::move(p)) {}
60
61 ~TempFile()
62 {
63 std::error_code ec;
64 fs::remove(path, ec);
65 fs::remove(path.string() + ".wal", ec);
66 fs::remove(path.string() + ".wal.tmp", ec);
67 fs::remove(path.string() + ".journal", ec);
68 fs::remove(path.string() + ".journal.tmp", ec);
69 fs::remove(path.string() + ".lock", ec);
70 }
71 };
72
73 template <typename T>
74 std::vector<T> to_vector(const Array<T> & arr)
75 {
76 std::vector<T> out;
77 out.reserve(arr.size());
78 for (size_t i = 0; i < arr.size(); ++i)
79 out.push_back(arr[i]);
80 return out;
81 }
82} // namespace
83
85{
86 TempFile tmp(make_temp_path());
87
88 {
89 File_B_Map<int, long, Aleph::less<int>, 3> map(tmp.path.string(), false);
90 EXPECT_TRUE(map.insert(10, 100));
91 EXPECT_TRUE(map.insert(20, 200));
92 EXPECT_FALSE(map.insert(10, 999));
93 ASSERT_TRUE(map.find(10).has_value());
94 EXPECT_EQ(*map.find(10), 100);
95 EXPECT_FALSE(map.insert_or_assign(10, 150));
96 EXPECT_EQ(map.at(10), 150);
97 EXPECT_TRUE(map.verify());
98 map.sync();
99 }
100
102 tmp.path.string(),
104 EXPECT_TRUE(reopened.is_read_only());
105 ASSERT_TRUE(reopened.find(20).has_value());
106 EXPECT_EQ(*reopened.find(20), 200);
108 (std::vector<std::pair<int, long>>{{10, 150}, {20, 200}}));
109}
110
112{
113 TempFile tmp(make_temp_path());
114
115 File_B_Map<int, int, Aleph::less<int>, 3> map(tmp.path.string(), false);
116 EXPECT_TRUE(map.insert(30, 300));
117 EXPECT_TRUE(map.insert(10, 100));
118 EXPECT_TRUE(map.insert(50, 500));
119 EXPECT_TRUE(map.insert(40, 400));
120
121 EXPECT_EQ(map.min_item(), (std::optional<std::pair<int, int>>{{10, 100}}));
122 EXPECT_EQ(map.max_item(), (std::optional<std::pair<int, int>>{{50, 500}}));
123 EXPECT_EQ(map.lower_bound(35), (std::optional<std::pair<int, int>>{{40, 400}}));
124 EXPECT_EQ(map.upper_bound(40), (std::optional<std::pair<int, int>>{{50, 500}}));
125 EXPECT_EQ(to_vector(map.keys()), (std::vector<int>{10, 30, 40, 50}));
126 EXPECT_EQ(to_vector(map.values()), (std::vector<int>{100, 300, 400, 500}));
127
128 EXPECT_TRUE(map.remove(30));
129 EXPECT_FALSE(map.contains(30));
130 EXPECT_EQ(to_vector(map.items()),
131 (std::vector<std::pair<int, int>>{{10, 100}, {40, 400}, {50, 500}}));
132 EXPECT_TRUE(map.verify());
133}
134
136{
137 TempFile tmp(make_temp_path());
140
141 {
143 key_codec, value_codec> map(tmp.path.string(), false);
144 EXPECT_TRUE(map.insert("apple", "green"));
145 EXPECT_TRUE(map.insert("banana", "yellow"));
146 EXPECT_TRUE(map.insert("kiwi", "brown fuzz"));
147 EXPECT_FALSE(map.insert_or_assign("banana", "ripe yellow"));
148 EXPECT_EQ(map.at("banana"), "ripe yellow");
149 EXPECT_EQ(map.lower_bound(std::string("banana")),
150 (std::optional<std::pair<std::string, std::string>>{
151 {"banana", "ripe yellow"}}));
152 EXPECT_TRUE(map.verify());
153 map.sync();
154 }
155
157 key_codec, value_codec> reopened(
158 tmp.path.string(),
159 File_B_Map<std::string, std::string, Aleph::less<std::string>, 3,
160 key_codec, value_codec>::Read_Only);
161 EXPECT_TRUE(reopened.verify());
163 (std::vector<std::pair<std::string, std::string>>{
164 {"apple", "green"},
165 {"banana", "ripe yellow"},
166 {"kiwi", "brown fuzz"}}));
167}
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:139
constexpr size_t size() const noexcept
Return the number of elements stored in the stack.
Definition tpl_array.H:351
Persistent ordered map backed by a paged File_B_Tree.
Value at(const Key &key) const
Return the mapped value associated with a key.
bool verify() const
Verify the structural invariants of the backing tree.
std::optional< value_type > lower_bound(const Key &key) const
Return the first key/value pair whose key is not less than key.
std::optional< Value > find(const Key &key) const
Return the mapped value associated with a key, if any.
void sync() const
Flush pending changes to the backing file.
bool insert(const Key &key, const Value &value)
Insert a new key/value pair if the key is not present.
std::optional< value_type > min_item() const
Return the smallest stored key/value pair.
bool insert_or_assign(const Key &key, const Value &value)
Insert or overwrite a key/value pair.
#define TEST(name)
static mt19937 rng
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
std::vector< typename C::Item_Type > to_vector(const C &c)
Convert a container to a std::vector.
Definition ah-convert.H:238
STL namespace.
static long counter
Definition test-splice.C:35
Persistent key/value map built on top of Aleph::File_B_Tree.