lix/src/libutil/aterm-map.hh

131 lines
2.6 KiB
C++
Raw Normal View History

2006-05-04 12:21:08 +00:00
#ifndef __ATERM_MAP_H
#define __ATERM_MAP_H
typedef union _ATerm * ATerm;
2006-05-04 12:21:08 +00:00
#include <assert.h>
namespace nix {
2006-05-04 12:21:08 +00:00
class ATermMap
{
public:
struct KeyValue
{
ATerm key;
ATerm value;
};
private:
/* Hash table for the map. We use open addressing, i.e., all
key/value pairs are stored directly in the table, and there are
no pointers. Collisions are resolved through probing. */
KeyValue * hashTable;
/* Current size of the hash table. */
unsigned int capacity;
/* Number of elements in the hash table. */
unsigned int count;
/* Maximum number of elements in the hash table. If `count'
exceeds this number, the hash table is expanded. */
unsigned int maxCount;
public:
/* Create a map. `expectedCount' is the number of elements the
map is expected to hold. */
2007-01-13 14:21:49 +00:00
ATermMap(unsigned int expectedCount = 16);
2006-05-04 12:21:08 +00:00
ATermMap(const ATermMap & map);
~ATermMap();
ATermMap & operator = (const ATermMap & map);
void set(ATerm key, ATerm value);
ATerm get(ATerm key) const;
ATerm operator [](ATerm key) const
{
return get(key);
}
2006-05-04 12:21:08 +00:00
void remove(ATerm key);
unsigned int size();
struct const_iterator
{
const ATermMap & map;
unsigned int pos;
const_iterator(const ATermMap & map, int pos) : map(map)
{
this->pos = pos;
}
bool operator !=(const const_iterator & i)
{
return pos != i.pos;
}
void operator ++()
{
if (pos == map.capacity) return;
do { ++pos;
} while (pos < map.capacity && map.hashTable[pos].value == 0);
}
const KeyValue & operator *()
{
assert(pos < map.capacity);
return map.hashTable[pos];
}
const KeyValue * operator ->()
{
assert(pos < map.capacity);
return &map.hashTable[pos];
}
};
2006-05-08 15:15:13 +00:00
friend class ATermMap::const_iterator;
2006-05-04 12:21:08 +00:00
const_iterator begin() const
{
unsigned int i = 0;
while (i < capacity && hashTable[i].value == 0) ++i;
return const_iterator(*this, i);
}
const_iterator end() const
{
return const_iterator(*this, capacity);
}
private:
void init(unsigned int expectedCount);
void free();
void resizeTable(unsigned int expectedCount);
void copy(KeyValue * elements, unsigned int capacity);
inline unsigned long hash1(ATerm key) const;
inline unsigned long hash2(ATerm key) const;
2006-05-04 12:21:08 +00:00
};
/* Hack. */
void printATermMapStats();
}
2006-05-04 12:21:08 +00:00
#endif /* !__ATERM_MAP_H */