38 auto size =
region.openFile(filename, read_only);
39 bool empty = (size == 0);
50 table->magic = magic_value;
52 table->elem_size =
static_cast<uint16_t
>(
sizeof(
value_t));
55 table->nb_elements = 0;
56 table->next_value = 0;
57 for(
unsigned long i=0; i<
table->capacity(); ++i) {
61 if(
table->magic != magic_value)
62 throw std::runtime_error(
"ProvSQL mmap: wrong file type (magic mismatch)");
63 if(
table->version != 1)
64 throw std::runtime_error(
"ProvSQL mmap: unsupported format version "
65 + std::to_string(
table->version));
67 throw std::runtime_error(
"ProvSQL mmap: element size mismatch (recompile required)");
88 const unsigned new_log_size =
table->log_size + 1;
90 const unsigned long new_capacity = 1ul << new_log_size;
92 std::vector<char> buf(new_size);
101 for(
unsigned long i=0; i<new_capacity; ++i)
104 for(
unsigned long i=0; i<
table->capacity(); ++i) {
109 (*
reinterpret_cast<const unsigned long *
>(&e.
uuid)) % new_capacity;
111 k = (k + 1) % new_capacity;
115 region.replaceContents(
path_.c_str(), buf.data(), new_size);
131 k = (k+1) %
table->capacity();
141 return table->t[k].value;
148 return std::make_pair(
table->t[k].value,
false);
158 return std::make_pair(
table->t[k].value,
false);
164 ++
table->nb_elements;
165 table->t[k].uuid = u;
166 if(value + 1 >
table->next_value)
167 table->next_value = value + 1;
170 table->t[k].value = value;
171 return std::make_pair(value,
true);
Open-addressing hash table mapping UUIDs to integers, backed by an mmap file.
bool read_only_
Mapped read-only: the header must not be written.
unsigned long hash(pg_uuid_t u) const
Compute the starting slot index for UUID u.
std::pair< unsigned long, bool > publish(pg_uuid_t u, unsigned long value)
Insert UUID u with a caller-chosen value.
static constexpr uint32_t FLAG_DIRTY
Bit of table_t::flags set while the file is open for writing.
void grow()
Double the table capacity and rehash all existing entries.
std::pair< unsigned long, bool > add(pg_uuid_t u)
Insert UUID u, assigning it the next available integer.
MMappedUUIDHashTable(const char *filename, bool read_only, uint64_t magic)
Open (or create) the mmap-backed hash table.
bool unclean_
The previous run left the dirty bit set.
static constexpr unsigned STARTING_LOG_SIZE
Initial log2 capacity (65 536 slots).
unsigned long find(pg_uuid_t u) const
Find the slot index of u, or NOTHING if absent.
unsigned long operator[](pg_uuid_t u) const
Look up the integer index for UUID u.
std::string path_
Backing file, for the atomic rehash in grow().
~MMappedUUIDHashTable()
Sync and unmap the file.
MappedRegion region
Backing storage (shared mmap, or heap buffer).
void sync()
Flush the backing region to its file (MappedRegion::sync()).
static constexpr unsigned long NOTHING
Sentinel returned by operator[]() when the UUID is not present.
void flush()
Force the backing file to stable storage (MappedRegion::flush()).
static constexpr double MAXIMUM_LOAD_FACTOR
Rehash when this fraction of slots is occupied.
table_t * table
Typed view of region.base().
On-disk layout of the hash table stored in the mmap file.
static constexpr unsigned logSizeForSize(std::size_t size)
Compute the log2 of the slot count from the file size.
value_t t[]
Flexible array of hash-table slots.
uint32_t flags
Bit 0: opened for writing and not closed since.
static constexpr std::size_t sizeForLogSize(unsigned ls)
Compute the file size required for a table with 2^ls slots.
uint64_t magic
File-type identifier.
unsigned log_size
log2 of the number of slots
uint16_t elem_size
sizeof(value_t) at write time
unsigned long nb_elements
Current number of stored key-value pairs.
unsigned long next_value
Next integer value to assign to a new UUID.
uint16_t version
Format version (currently 1).
One slot in the hash table: a UUID key and its associated integer value.
unsigned long value
Associated integer (gate index), or 0 if slot is empty.