-
Notifications
You must be signed in to change notification settings - Fork 3
/
hashtable.cc
103 lines (88 loc) · 2.49 KB
/
hashtable.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/* File: hashtable.cc
* ------------------
* Implementation of Hashtable class.
*/
/* Hashtable::Enter
* ----------------
* Stores new value for given identifier. If the key already
* has an entry and flag is to overwrite, will remove previous entry first,
* otherwise it just adds another entry under same key. Copies the
* key, so you don't have to worry about its allocation.
*/
template <class Value>
void Hashtable<Value>::Enter(const char *key, Value val, bool overwrite)
{
Value prev;
if (overwrite && (prev = Lookup(key)))
Remove(key, prev);
mmap.insert(make_pair(strdup(key), val));
}
/* Hashtable::Remove
* -----------------
* Removes a given key-value pair from table. If no such pair, no
* changes are made. Does not affect any other entries under that key.
*/
template <class Value> void Hashtable<Value>::Remove(const char *key, Value val)
{
if (mmap.count(key) == 0) // no matches at all
return;
typename multimap<const char *, Value>::iterator itr;
itr = mmap.find(key); // start at first occurrence
while (itr != mmap.upper_bound(key)) {
if (itr->second == val) { // iterate to find matching pair
mmap.erase(itr);
break;
}
++itr;
}
}
/* Hashtable::Lookup
* -----------------
* Returns the value earlier stored under key or NULL
*if there is no matching entry
*/
template <class Value>
Value Hashtable<Value>::Lookup(const char *key)
{
Value found = NULL;
if (mmap.count(key) > 0) {
typename multimap<const char *, Value>::iterator cur, last, prev;
cur = mmap.find(key); // start at first occurrence
last = mmap.upper_bound(key);
while (cur != last) { // iterate to find last entered
prev = cur;
if (++cur == mmap.upper_bound(key)) { // have to go one too far
found = prev->second; // one before last was it
break;
}
}
}
return found;
}
/* Hashtable::NumEntries
* ---------------------
*/
template <class Value>
int Hashtable<Value>::NumEntries() const
{
return mmap.size();
}
/* Hashtable:GetIterator
* ---------------------
* Returns iterator which can be used to walk through all values in table.
*/
template <class Value>
Iterator<Value> Hashtable<Value>::GetIterator()
{
return Iterator<Value>(mmap);
}
/* Iterator::GetNextValue
* ----------------------
* Iterator method used to return current value and advance iterator
* to next entry. Returns null if no more values exist.
*/
template <class Value>
Value Iterator<Value>::GetNextValue()
{
return (cur == end ? NULL : (*cur++).second);
}