ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
MMappedVector.h
Go to the documentation of this file.
1/**
2 * @file MMappedVector.h
3 * @brief Append-only vector template backed by a memory-mapped file.
4 *
5 * @c MMappedVector<T> provides a @c std::vector-like interface over a
6 * memory-mapped file, enabling the provenance circuit data structures
7 * (@c GateInformation, child UUID lists, extra string data) to survive
8 * PostgreSQL restarts and be shared across processes.
9 *
10 * Design constraints:
11 * - **Append-only**: elements are added with @c add(); existing elements
12 * can be updated in-place via @c operator[]() but cannot be removed.
13 * - **Automatic growth**: when capacity is exhausted the backing file is
14 * grown by a factor of two and remapped.
15 * - @c T must be a trivially copyable type so that it can be stored
16 * directly in the memory-mapped region.
17 *
18 * The implementation is in @c MMappedVector.hpp (included from this header).
19 */
20#ifndef MMAPPED_VECTOR_H
21#define MMAPPED_VECTOR_H
22
23#include <cstddef>
24#include <cstdint>
25#include <vector>
26
27#include "MappedRegion.h"
28
29extern "C" {
30#include "provsql_utils.h"
31}
32
33/**
34 * @brief Append-only, mmap-backed vector of elements of type @c T.
35 *
36 * @tparam T The element type. Must be trivially copyable.
37 */
38template <typename T>
40/**
41 * @brief On-disk layout stored at the start of the backing file.
42 *
43 * @c d is a flexible array member holding the actual elements.
44 */
45struct data_t {
46 uint64_t magic; ///< File-type identifier
47 uint16_t version; ///< Format version of this file
48 uint16_t elem_size; ///< sizeof(T) at write time
49 uint32_t flags; ///< Bit 0: opened for writing and not closed since
50 unsigned long nb_elements; ///< Number of elements currently stored
51 unsigned long capacity; ///< Maximum elements before the next grow
52 T d[]; ///< Flexible array of elements
53};
54
55MappedRegion region; ///< Backing storage (shared mmap, or heap buffer)
56data_t *data; ///< Typed view of @c region.base()
57bool read_only_ = false;///< Mapped read-only: the header must not be written
58bool unclean_ = false;///< The previous run left the dirty bit set
59
60/** @brief Initial number of element slots allocated. */
61static constexpr unsigned STARTING_CAPACITY=(1u << 16);
62
63/** @brief Double the backing region and refresh @c data. */
64void grow();
65/**
66 * @brief Unused overload kept for interface compatibility.
67 * @param u Ignored UUID parameter.
68 * @param i Ignored integer parameter.
69 */
70void set(pg_uuid_t u, unsigned long i);
71
72public:
73/**
74 * @brief Open (or create) the mmap-backed vector.
75 *
76 * A file created here is stamped with @p version; an existing file is
77 * accepted when its stamp is at most @p version, so a build that
78 * understands version @em n keeps reading the files an older one wrote.
79 * The caller reads the stamp back with @c version() to decide how to
80 * interpret fields whose meaning changed.
81 *
82 * @param filename Path to the backing file (created with
83 * @c STARTING_CAPACITY slots if absent).
84 * @param read_only If @c true, map the file read-only.
85 * @param magic Expected magic value for format validation.
86 * @param version Highest format version this build writes and reads.
87 */
88MMappedVector(const char *filename, bool read_only, uint64_t magic,
89 uint16_t version = 1);
90/** @brief Sync and unmap the file. */
92
93/**
94 * @brief Read-only element access by index.
95 * @param k Zero-based element index.
96 * @return Const reference to element @p k.
97 */
98const T &operator[](unsigned long k) const;
99
100/**
101 * @brief Read-write element access by index.
102 * @param k Zero-based element index.
103 * @return Reference to element @p k.
104 */
105T &operator[](unsigned long k);
106
107/**
108 * @brief Append an element to the end of the vector.
109 *
110 * Grows the backing file if the current capacity is exhausted.
111 *
112 * @param value Element to append.
113 */
114void add(const T& value);
115
116/**
117 * @brief Return the number of elements currently stored.
118 * @return Element count.
119 */
120inline unsigned long nbElements() const {
121 return data->nb_elements;
122}
123
124/** @brief Return the format version stamped in the file's header. */
125inline uint16_t version() const {
126 return data->version;
127}
128
129/** @brief Stamp @p v into the header, declaring the file upgraded.
130 *
131 * Only a pass that has rewritten every record to the new version's
132 * conventions may call this. */
133inline void setVersion(uint16_t v) {
134 data->version = v;
135}
136
137/** @brief Flush the backing region to its file (@c MappedRegion::sync()). */
138void sync();
139
140/** @brief Force the backing file to stable storage
141 * (@c MappedRegion::flush()). */
142void flush();
143
144/**
145 * @brief Bit of @c data_t::flags set while the file is open for writing.
146 *
147 * Cleared on a clean close, so a file found with it still set was left
148 * behind by a process that died (or by an immediate shutdown). The
149 * header layout is unchanged: the bit lives in what used to be reserved
150 * padding, which older builds neither read nor write.
151 */
152static constexpr uint32_t FLAG_DIRTY = 1u;
153
154/** @brief Whether this file still had @c FLAG_DIRTY set when it was
155 * opened, i.e. whoever wrote it last did not close it. */
156inline bool uncleanShutdown() const {
157 return unclean_;
158}
159};
160
161 #endif /* MMAPPED_VECTOR_H */
File-backed memory region with two interchangeable backends.
void set(pg_uuid_t u, unsigned long i)
Unused overload kept for interface compatibility.
uint16_t version() const
Return the format version stamped in the file's header.
~MMappedVector()
Sync and unmap the file.
bool unclean_
The previous run left the dirty bit set.
data_t * data
Typed view of region.base().
void flush()
Force the backing file to stable storage (MappedRegion::flush()).
unsigned long nbElements() const
Return the number of elements currently stored.
static constexpr unsigned STARTING_CAPACITY
Initial number of element slots allocated.
bool read_only_
Mapped read-only: the header must not be written.
void add(const T &value)
Append an element to the end of the vector.
static constexpr uint32_t FLAG_DIRTY
Bit of data_t::flags set while the file is open for writing.
MMappedVector(const char *filename, bool read_only, uint64_t magic, uint16_t version=1)
Open (or create) the mmap-backed vector.
void grow()
Double the backing region and refresh data.
MappedRegion region
Backing storage (shared mmap, or heap buffer).
const T & operator[](unsigned long k) const
Read-only element access by index.
void sync()
Flush the backing region to its file (MappedRegion::sync()).
void setVersion(uint16_t v)
Stamp v into the header, declaring the file upgraded.
bool uncleanShutdown() const
Whether this file still had FLAG_DIRTY set when it was opened, i.e.
Core types, constants, and utilities shared across ProvSQL.
On-disk layout stored at the start of the backing file.
unsigned long nb_elements
Number of elements currently stored.
uint32_t flags
Bit 0: opened for writing and not closed since.
T d[]
Flexible array of elements.
uint16_t elem_size
sizeof(T) at write time
uint16_t version
Format version of this file.
uint64_t magic
File-type identifier.
unsigned long capacity
Maximum elements before the next grow.