42#define TEST_CONSISTENCY
48#define CONSTANT 0x1B0CA37ABA9
63#if defined(TEST_CONSISTENCY)
64extern volatile int consistency_result;
65volatile int consistency_result = 0;
71 LOG(
INFO,
"idmap size != aliasmap size.");
78 LOG(
INFO,
"Found freelist entry when map is full.");
86 LOG(
INFO,
"No freelist entry although map is not full.");
92 LOG(
INFO,
"LRU head/tail elements should be null when map is empty.");
95 std::set<void *> free_entries;
96 for (PoolIdx p =
freeList; !p.
empty(); p = p.deref(
this)->older_)
98 Metadata *m = p.deref(
this);
99 if (free_entries.count(m))
101 LOG(
INFO,
"Duplicate entry on freelist.");
104 free_entries.insert(m);
108 LOG(
INFO,
"Lost some metadata entries.");
113 if (free_entries.count(kv.deref(
this)))
115 LOG(
INFO,
"Found an aliasmap entry in the freelist.");
119 for (
auto kv :
idMap)
121 if (free_entries.count(kv.deref(
this)))
123 LOG(
INFO,
"Found an id entry in the freelist.");
131 LOG(
INFO,
"Oldest should be empty when map is empty.");
136 LOG(
INFO,
"Newest should be empty when map is empty.");
144 LOG(
INFO,
"Oldest should be nonempty when map is nonempty.");
149 LOG(
INFO,
"Newest should be nonempty when map is nonempty.");
154 LOG(
INFO,
"Oldest is on the freelist.");
159 LOG(
INFO,
"Newest is on the freelist.");
171 if (!prev.deref(
this)->older_.empty())
173 LOG(
INFO,
"Prev link points to empty.");
176 while (!prev.deref(
this)->newer_.empty())
178 auto next = prev.deref(
this)->newer_;
180 if (free_entries.count(next.deref(
this)))
182 LOG(
INFO,
"Next link points to the freelist.");
185 if (next.deref(
this)->older_.idx_ != prev.idx_)
187 LOG(
INFO,
"Next link broken.");
194 LOG(
INFO,
"Prev link points to newest.");
199 LOG(
INFO,
"LRU link list length is incorrect.");
205 if (!next.deref(
this)->newer_.empty())
207 LOG(
INFO,
"Newest has a newer link.");
210 while (!next.deref(
this)->older_.empty())
212 auto prev = next.deref(
this)->older_;
213 if (free_entries.count(prev.deref(
this)))
215 LOG(
INFO,
"Prev link points to the freelist.");
218 if (prev.deref(
this)->newer_.idx_ != next.idx_)
220 LOG(
INFO,
"Prev link broken.");
227 LOG(
INFO,
"Next link points to oldest.");
231 for (
unsigned i = 0; i <
entries; ++i)
233 if (free_entries.count(
pool + i))
240 LOG(
INFO,
"Metadata ID is not in the id map.");
243 if (
idMap.
find(e->get_node_id())->idx_ != i)
246 "Id map entry does not point back to the expected index.");
251 LOG(
INFO,
"Metadata alias is not in the alias map.");
257 "Alis map entry does not point back to the expected index.");
274 for (
size_t i = 0; i <
entries; ++i)
284 LOG(
INFO,
"[%012" PRIx64
"]: %03X",
id, alias);
287void debug_print_cache(AliasCache *c)
290 c->for_each(&debug_print_entry,
nullptr);
313 insert = it->deref(
this);
327 insert = nit->deref(
this);
350 auto second = insert->
newer_;
374 unsigned ofs = insert -
pool;
405#if defined(TEST_CONSISTENCY)
407 HASSERT(0 == consistency_result);
422 Metadata *metadata = it->deref(
this);
451#if defined(TEST_CONSISTENCY)
453 HASSERT(0 == consistency_result);
483 Metadata *metadata = it->deref(
this);
507 Metadata *metadata = it->deref(
this);
533 Metadata *metadata = it->deref(
this);
555 Metadata *metadata = idx.deref(
this);
575 }
while (alias == 0 ||
lookup(alias) != 0);
604#if defined(TEST_CONSISTENCY)
606 HASSERT(0 == consistency_result);
#define CONSTANT
constant for random number generation
iterator find(key_type key)
Searches for a single entry.
void erase(const iterator &it)
Removes an entry from the vector, pointed by an iterator.
iterator upper_bound(key_type key)
void insert(data_type &&d)
Adds new entry to the vector.
void clear()
Removes all entries.
Encapsulation of a pointer into the pool array.
Metadata * deref(AliasCache *parent)
Dereferences a pool index as if it was a pointer.
uint16_t idx_
Indexes the pool of the AliasCache.
PoolIdx freeList
list of unused mapping entries (index into pool)
bool next_entry(NodeID bound, NodeID *node, NodeAlias *alias)
Retrieves the next entry by increasing node ID.
Metadata * pool
pointer to allocated Metadata pool
NodeAlias generate()
Generate a 12-bit pseudo-random alias for a given alias cache.
void remove(NodeAlias alias)
Remove an alias from an alias cache.
AliasMap aliasMap
Map of alias to corresponding Metadata.
void touch(Metadata *metadata)
Update the time stamp for a given entry.
size_t entries
How many metadata entries have we allocated.
NodeAlias lookup(NodeID id)
Lookup a node's alias based on its Node ID.
void * context
context pointer to pass in with remove_callback
static constexpr uint16_t NONE_ENTRY
Sentinel entry for empty lists.
void for_each(void(*callback)(void *, NodeID, NodeAlias), void *context)
Call the given callback function once for each alias tracked.
PoolIdx newest
newest, most recently touched entry (index into pool)
IdMap idMap
Map of Node ID to corresponding Metadata.
void clear()
Reinitializes the entire map.
void(* removeCallback)(NodeID id, NodeAlias alias, void *)
callback function to be used when we remove an entry from the cache
PoolIdx oldest
oldest untouched entry (index into pool)
bool retrieve(unsigned entry, NodeID *node, NodeAlias *alias)
Retrieves an entry by index.
size_t size()
Returns the total number of aliases that can be cached.
NodeID seed
Seed for the generation of the next alias.
int check_consistency()
Visible for testing.
void add(NodeID id, NodeAlias alias)
Add an alias to an alias cache.
#define LOG(level, message...)
Conditionally write a message to the logging output.
static const int INFO
Loglevel that is printed by default, reporting some status information.
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
static NodeAlias resolve_notresponding(NodeAlias stored)
This code removes the unique bits in the stored node alias in case this is a NOT_RESPONDING entry.
uint64_t NodeID
48-bit NMRAnet Node ID type
static const NodeAlias NOT_RESPONDING
Guard value put into the the internal node alias maps when a node ID could not be translated to a val...
uint16_t NodeAlias
Alias to a 48-bit NMRAnet Node ID type.