Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ah-map-arena.H
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
44#ifndef AH_MAP_ARENA_H
45#define AH_MAP_ARENA_H
46
47#include <unistd.h>
48#include <cstdlib>
49#include <cstdint>
50#include <cassert>
51#include <filesystem>
52#include <fcntl.h>
53#include <sys/mman.h>
54#include <string>
55
56#include <ah-errors.H>
57
58namespace fs = std::filesystem;
59
60namespace Aleph
61{
62
128{
129public:
130
132 static constexpr size_t initial_rgn_size = 4 * 1024;
133
134private:
135
136 char * rgn_ptr = nullptr;
137 size_t end_ = 0;
139 int fd = -1;
140
148 bool remap(const size_t sz)
149 {
150 assert(sz > avail());
151
152 // Determine new region size according to requested sz
153 size_t new_size = 2 * rgn_size;
154 while (new_size - end_ < sz)
155 new_size *= 2;
156
158 if (ptr == MAP_FAILED)
159 return false;
160
161 const auto status = ftruncate(fd, static_cast<off_t>(new_size));
162 ah_runtime_error_unless(status == 0)
163 << "cannot truncate the file to " << new_size << " error = " << errno;
164
165 rgn_ptr = static_cast<char*>(ptr);
167
168 return true;
169 }
170
171public:
172
174 using iterator = char *;
175
177 using const_iterator = const char *;
178
181
192 void init(const std::string & file_path_name, void * addr = nullptr)
193 {
194 end_ = 0;
195 if (fs::exists(fs::path(file_path_name)))
196 {
197 fd = open(file_path_name.c_str(), O_RDWR, static_cast<mode_t>(0600));
198 ah_runtime_error_unless(fd >= 0) << "cannot open " << file_path_name;
199
200 // Read end_ value stored at the beginning of file
201 const auto status = ::read(fd, &end_, sizeof(end_));
202 ah_runtime_error_unless(status != -1)
203 << "Cannot read file length of " << file_path_name;
204
205 // Determine file size
206 const auto file_size = lseek(fd, 0, SEEK_END);
207 ah_runtime_error_unless(file_size != static_cast<off_t>(-1))
208 << "Cannot determine file length of " << file_path_name;
209 rgn_size = static_cast<size_t>(file_size);
210 }
211 else
212 {
213 fd = open(file_path_name.c_str(), O_RDWR | O_CREAT, static_cast<mode_t>(0600));
214 ah_runtime_error_unless(fd >= 0) << "cannot open " << file_path_name;
215 const auto status = ftruncate(fd, static_cast<off_t>(rgn_size));
216 ah_runtime_error_unless(status == 0)
217 << "cannot truncate the file to " << rgn_size << " error = " << errno;
218 }
219
220 void *ptr = mmap(addr, rgn_size, PROT_READ | PROT_WRITE,
223 << "Cannot mmap. Error = " << errno;
224
225 rgn_ptr = static_cast<char*>(ptr);
226 }
227
236 void init_and_erase(const std::string & file_path_name)
237 {
238 fs::remove(file_path_name);
240 }
241
252 explicit MapArena(const std::string & file_path_name)
253 {
255 }
256
262
265
268
278 {
279 other.rgn_ptr = nullptr;
280 other.end_ = 0;
281 other.rgn_size = initial_rgn_size;
282 other.fd = -1;
283 }
284
291 {
292 if (this != &other)
293 {
294 // Clean up current resources
295 if (rgn_ptr)
297 if (fd != -1)
298 close(fd);
299
300 // Transfer ownership
301 rgn_ptr = other.rgn_ptr;
302 end_ = other.end_;
303 rgn_size = other.rgn_size;
304 fd = other.fd;
305
306 // Invalidate other
307 other.rgn_ptr = nullptr;
308 other.end_ = 0;
309 other.rgn_size = initial_rgn_size;
310 other.fd = -1;
311 }
312 return *this;
313 }
314
318 {
319 if (rgn_ptr)
321 if (fd != -1)
322 close(fd);
323 }
324
330
336
342
348
356 [[nodiscard]] char * base() const noexcept { return rgn_ptr; }
357
365 {
366 return rgn_size - end_;
367 }
368
383 [[nodiscard]] char * reserve(const size_type sz)
384 {
385 if (sz > avail() && !remap(sz))
386 return nullptr;
387
388 return rgn_ptr + end_;
389 }
390
403 void commit(const size_type sz) noexcept
404 {
405 end_ += sz;
406 }
407
414 {
416 }
417
423 {
424 return end_;
425 }
426
432 {
433 return rgn_size;
434 }
435
441 {
442 return end_ == 0;
443 }
444
450 {
451 return rgn_ptr != nullptr;
452 }
453
459 {
460 return rgn_ptr;
461 }
462
468 {
469 return fd;
470 }
471
478 friend std::ostream & operator<<(std::ostream & o, const MapArena & s)
479 {
480 return o << "MapArena:\n"
481 << " rgn_ptr = " << static_cast<void*>(s.rgn_ptr) << '\n'
482 << " end_ = " << s.end_ << '\n'
483 << " rgn_size = " << s.rgn_size << '\n'
484 << " size = " << s.size() << '\n'
485 << " capacity = " << s.capacity() << '\n'
486 << " avail = " << s.avail();
487 }
488};
489
490} // end namespace Aleph
491
492#endif // AH_MAP_ARENA_H
Exception handling system with formatted messages for Aleph-w.
#define ah_runtime_error_unless(C)
Throws std::runtime_error if condition does NOT hold.
Definition ah-errors.H:250
Memory-mapped file arena allocator.
size_type size() const noexcept
Get the total committed (allocated) size.
char * iterator
Iterator type for traversing allocated memory.
MapArena() noexcept=default
Default constructor - creates an uninitialized arena.
size_type capacity() const noexcept
Get the current capacity (mapped region size).
char * base() const noexcept
Get the base address of the mapped region.
MapArena & operator=(MapArena &&other) noexcept
Move assignment operator.
void init_and_erase(const std::string &file_path_name)
Initialize and erase any existing data.
void init(const std::string &file_path_name, void *addr=nullptr)
Initialize the arena with a backing file.
int file_descriptor() const noexcept
Get the file descriptor.
bool remap(const size_t sz)
Remap the memory region to accommodate more allocations.
friend std::ostream & operator<<(std::ostream &o, const MapArena &s)
Output operator for debugging.
void commit(const size_type sz) noexcept
Commit a previous reservation.
char * reserve(const size_type sz)
Reserve memory for allocation.
bool empty() const noexcept
Check if the arena is empty.
iterator end() noexcept
Get iterator past the last allocated byte.
const_iterator begin() const noexcept
Get const iterator to the beginning.
const_iterator end() const noexcept
Get const iterator past the last allocated byte.
MapArena(const std::string &file_path_name)
Construct an arena with a backing file.
bool is_initialized() const noexcept
Check if the arena has been initialized.
int fd
File descriptor for the backing file.
~MapArena()
Destructor - unmaps memory and closes file.
size_t end_
Allocation offset from rgn_ptr.
size_t size_type
Size type for memory sizes.
static constexpr size_t initial_rgn_size
Initial region size in bytes (4 KB).
size_type avail() const noexcept
Get the available memory in the current mapping.
void * mapped_addr() const noexcept
Get the mapped memory address.
iterator begin() noexcept
Get iterator to the beginning of allocated memory.
const char * const_iterator
Const iterator type.
void sync() noexcept
Ensure data is persisted to disk.
size_t rgn_size
Current mapped region size.
char * rgn_ptr
Pointer to the mapped memory region.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
static bool init
Definition hash-fct.C:47
DynList< T > maps(const C &c, Op op)
Classic map operation.