15 #ifndef _DATAT_BITS_INCLUDE_TAG
16 #error Must only be included from sag_connectivity_cpp.hpp, use that instead
36 class map_t:
protected sag_underlying_map_t
41 static size_t MIN_CAPACITY() {
return 8; }
43 typedef sag_underlying_map_table_entry_t item_t;
44 typedef int64_t hash_t;
47 template<
typename DATA>
61 template<
typename DATA,
typename UNDERLYING,
typename PAIR>
62 struct _iterator:
public std::iterator<std::bidirectional_iterator_tag, DATA>
66 typedef PAIR element_t;
68 _iterator(): tabledata(
nullptr), capacity(0), offs(0) {}
69 _iterator(
const UNDERLYING &tabledata,
size_t capacity, int64_t offs,
bool stepToItem=
false)
70 : tabledata(tabledata), capacity(capacity), offs(offs)
72 if (!valid() && stepToItem) {
77 iterator &operator--()
86 iterator operator--(
int)
92 iterator &operator++()
94 if (offs < capacity) {
101 iterator operator++(
int)
108 DATA &key()
const {
return static_cast<DATA&
>(tabledata[offs].key); }
109 DATA &value()
const {
return static_cast<DATA&
>(tabledata[offs].value); }
113 bool b = offs == other.offs;
121 element_t &operator*()
const
123 return reinterpret_cast<element_t &
>(tabledata[offs]);
125 element_t *operator->()
const
127 return reinterpret_cast<element_t *
>(tabledata + offs);
133 return offs >= capacity || offs < 0 || tabledata[offs].hash > 1 ||
SAG_DATA_EMPTY != tabledata[offs].key.tag;
135 UNDERLYING tabledata;
154 explicit map_t(
size_t n,
const char* name =
nullptr);
171 swap(std::move(tmp));
173 swap(std::move(other));
180 swap(std::move(other));
184 map_t(std::initializer_list<std::pair<data_t,data_t>> l)
187 for (
auto it = l.begin(); it != l.end(); ++it) {
188 insert(std::make_pair(it->first.copy(), it->second.copy()));
195 std::swap(table, other.table);
201 if (other.table && other.table->name) {
203 if (!table) resize(0);
204 std::swap(table->name, other.table->name);
212 for (const_iterator it =
begin(); it !=
end(); ++it) {
213 newmap.
insert(std::make_pair(it->first.copy(), it->second.copy()));
222 if (table && table->name) {
223 sag_free_string(table->name);
224 table->name =
nullptr;
229 if (!table) resize(0);
230 table->name = sag_copy_string(name);
237 if (!table)
return nullptr;
251 if (
size() != other.
size())
return false;
252 if ((table && table->name) || (other.table && other.table->name)) {
253 if (!(table && table->name) || !(other.table && other.table->name))
return false;
254 if (0 != strcmp(table->name, other.table->name))
return false;
256 for (const_iterator it =
begin(); it !=
end(); ++it) {
257 const_iterator jt = other.
find(it.key());
258 if (jt == other.
end())
return false;
259 if (it.value() != jt.value())
return false;
272 iterator
begin() {
return iterator(table?table->table:0, table?table->capacity:0, 0,
true); }
274 iterator
end() {
return iterator(table?table->table:0, table?table->capacity:0, table?table->capacity:0,
false); }
276 const_iterator
begin()
const {
return const_iterator(table?table->table:0, table?table->capacity:0, 0,
true); }
278 const_iterator
end()
const {
return const_iterator(table?table->table:0, table?table->capacity:0, table?table->capacity:0,
false); }
280 const_iterator
cbegin()
const {
return const_iterator(table?table->table:0, table?table->capacity:0, 0,
true); }
282 const_iterator
cend()
const {
return const_iterator(table?table->table:0, table?table->capacity:0, table?table->capacity:0,
false); }
285 size_t size()
const {
return table?table->count:0; }
294 return maybe_insert(std::pair<data_t&&,data_t&&>(std::move(k),
data_t())).first->second;
301 return maybe_insert(std::pair<const data_t&,const data_t&>(k,
data_t())).first->second;
307 const_iterator it =
find(k);
309 throw std::runtime_error(
"Element not in map");
333 std::pair<iterator, bool>
insert(
const std::pair<data_t&&, data_t&&> &v);
347 return insert(std::make_pair(std::move(k), std::move(v)));
352 std::pair<iterator, bool>
insert(
const std::pair<data_t&&, data_t&&> &v, hash_t hash);
363 void erase(iterator it);
376 void resize(
size_t newsize);
379 void really_insert(item_t &item,
const std::pair<data_t&&, data_t&&> &v, hash_t hash);
381 std::pair<iterator, bool> maybe_insert(
const std::pair<const data_t&, const data_t&> &v);
383 std::pair<iterator, bool> maybe_insert(
const std::pair<data_t&&, data_t&&> &v);
385 std::pair<map_t::const_iterator, map_t::const_iterator> find_for_insert(
const data_t &k, hash_t hash)
const;
388 bool empty(
const item_t &item)
const {
return 0 == item.hash &&
SAG_DATA_EMPTY == item.key.tag; }
390 bool empty(
const const_iterator::element_t &item)
const {
return 0 == item.hash &&
SAG_DATA_EMPTY == item.first.tag; }
392 bool hole(
const item_t &item)
const {
return 1 == item.hash &&
SAG_DATA_EMPTY == item.key.tag; }
394 bool hole(
const const_iterator::element_t &item)
const {
return 1 == item.hash &&
SAG_DATA_EMPTY == item.first.tag; }
396 bool live(
const item_t &item)
const {
return SAG_DATA_EMPTY != item.key.tag || item.hash > 1; }
398 bool live(
const const_iterator::element_t &item)
const {
return SAG_DATA_EMPTY != item.first.tag || item.hash > 1; }
401 size_t index(hash_t hash)
const
403 if (!table)
return 0;
404 return table->capacity ? hash % table->capacity : 0;
407 #ifdef _SAG_INTERNAL_UNSUPPORTED_DEBUG
409 SAG_CONNECTIVITY_API
static size_t clashes;
410 SAG_CONNECTIVITY_API
static size_t inserts;
411 SAG_CONNECTIVITY_API
static double resizeUsage;
412 SAG_CONNECTIVITY_API
static size_t resizes;
413 SAG_CONNECTIVITY_API
static size_t max_lookup_clash;
414 SAG_CONNECTIVITY_API
static size_t lookups;
415 SAG_CONNECTIVITY_API
static size_t lookup_clashes;
416 static double getInsertClashRatio() {
return (
double)clashes/(double)inserts; }
417 static double getAverageResizeRatio() {
return resizeUsage/(double)resizes; }
418 static void resetCounters() { clashes = inserts = resizeUsage = resizes = 0; }
419 static double getAverageLookupProbes() {
return 1.0+(double)lookup_clashes/(
double)lookups; }
420 static size_t getMaxLookupProbes() {
return 1+max_lookup_clash; }
iterator find(const data_t &k)
Searches the map for an item with the given key and returns an iterator to that position in the map...
std::pair< iterator, bool > insert(const std::pair< data_t &&, data_t && > &v)
Insert a new key/value pair into the map.
const data_t & operator[](const data_t &k) const
Return a reference to the item with the given key.
Definition: map_t.hpp:305
~map_t()
Free the underlying map contents.
Definition: map_t.hpp:160
A container for an payload and associated metadata.
Definition: message.hpp:27
A map class which implements many of the functions on std::map.
Definition: map_t.hpp:36
map_t(std::initializer_list< std::pair< data_t, data_t >> l)
Initialiser list construction.
Definition: map_t.hpp:184
iterator end()
Forward iterator end.
Definition: map_t.hpp:274
pair< const data_t > const_element
The type of an element in a const map.
Definition: map_t.hpp:146
data_t & operator[](data_t &&k)
Return a reference to the item with the given key.
Definition: map_t.hpp:292
void swapName(map_t &&other)
Swap the name of this map and other.
Definition: map_t.hpp:199
const char * getName() const
Get the optional name of this map.
Definition: map_t.hpp:235
const_iterator end() const
Forward const_iterator end.
Definition: map_t.hpp:278
_iterator< const data_t, sag_underlying_map_table_entry_t const *, const pair< const data_t > > const_iterator
The type of iterators on const maps.
Definition: map_t.hpp:142
std::pair< iterator, bool > insert(data_t &&k, data_t &&v)
Insert a new key/value pair into the map.
Definition: map_t.hpp:346
size_t size() const
Returns the number of key/value pairs in the map.
Definition: map_t.hpp:285
void swap(map_t &&other)
Swap the contents of this map and other.
Definition: map_t.hpp:193
const_iterator cbegin() const
Forward const_iterator begin.
Definition: map_t.hpp:280
map_t(const char *name)
Construct an empty map with a name.
Definition: map_t.hpp:156
map_t(map_t &&other)
Move constructor.
Definition: map_t.hpp:177
bool operator!=(const map_t &other) const
Returns false if this map deep-equals other.
Definition: map_t.hpp:265
Forward/reverse and const/non-const iterators are implemented using this class.
Definition: map_t.hpp:62
_iterator< data_t, sag_underlying_map_table_entry_t *, pair< data_t > > iterator
The type of iterators on mutable maps.
Definition: map_t.hpp:140
map_t copy() const
Return a deep copy of this map.
Definition: map_t.hpp:209
void clear()
Empty the map, clean the name and free the underlying data.
iterator begin()
Forward iterator begin.
Definition: map_t.hpp:272
const_iterator cend() const
Forward const_iterator end.
Definition: map_t.hpp:282
pair< data_t > element
The type of an element in a mutable map.
Definition: map_t.hpp:144
bool empty() const
Returns true if the map is empty (size() == 0)
Definition: map_t.hpp:288
size_t erase(const data_t &k)
Remove the item with the specified key.
bool operator==(const map_t &other) const
Returns true if this map deep-equals other.
Definition: map_t.hpp:249
A variant type which can be one of the following:
Definition: data_t.hpp:42
const_iterator begin() const
Forward const_iterator begin.
Definition: map_t.hpp:276
map_t()
Construct an empty map.
Definition: map_t.hpp:149
data_t & operator[](const data_t &k)
Return a reference to the item with the given key.
Definition: map_t.hpp:299
void setName(const char *name)
Set the optional name of this map.
Definition: map_t.hpp:220
Empty.
Definition: sag_connectivity_c.h:36
map_t & operator=(map_t &&other)
Move assignment.
Definition: map_t.hpp:167