jens@0
|
1 |
/*
|
jens@0
|
2 |
* Hash.h
|
jens@0
|
3 |
* Ottoman
|
jens@0
|
4 |
*
|
jens@0
|
5 |
* Created by Jens Alfke on 8/20/09.
|
jens@0
|
6 |
* Copyright 2009 Jens Alfke. All rights reserved.
|
jens@0
|
7 |
* BSD-Licensed: See the file "LICENSE.txt" for details.
|
jens@0
|
8 |
*/
|
jens@0
|
9 |
|
jens@0
|
10 |
#ifndef _MOOSEYARD_HASH_
|
jens@0
|
11 |
#define _MOOSEYARD_HASH_
|
jens@0
|
12 |
#include "Base.h"
|
jens@0
|
13 |
#include "Dictionary.h"
|
jens@0
|
14 |
|
jens@0
|
15 |
namespace Mooseyard {
|
jens@0
|
16 |
|
jens@0
|
17 |
/** A fairly low-level hash-table class whose keys and values are arbitrary data blobs.
|
jens@0
|
18 |
This class does no memory management of the keys and values: the memory ranges
|
jens@0
|
19 |
pointed to by the key and value parameters to put() must remain valid as long as
|
jens@0
|
20 |
that key or value remains in the hash-table. */
|
jens@0
|
21 |
class Hash {
|
jens@0
|
22 |
|
jens@0
|
23 |
public:
|
jens@0
|
24 |
typedef void* Value;
|
jens@0
|
25 |
|
jens@0
|
26 |
/** Creates a new, empty Hash. */
|
jens@0
|
27 |
explicit Hash (int capacity = 50);
|
jens@0
|
28 |
|
jens@0
|
29 |
~Hash();
|
jens@0
|
30 |
|
jens@0
|
31 |
/** Gets the value associated with the given key. */
|
jens@0
|
32 |
Value get(Key) const;
|
jens@0
|
33 |
Value operator[] (Key key) const {return get(key);}
|
jens@0
|
34 |
|
jens@0
|
35 |
/** Returns the number of values in the Hash. */
|
jens@0
|
36 |
int count() const {return _count;}
|
jens@0
|
37 |
|
jens@0
|
38 |
/** Sets the given value for the given key, replacing any existing value. */
|
jens@0
|
39 |
void put(Key, Value);
|
jens@0
|
40 |
|
jens@3
|
41 |
/** Removes the value with the given key. Returns the former value, or NULL if not found. */
|
jens@3
|
42 |
Value remove(Key);
|
jens@0
|
43 |
|
jens@0
|
44 |
/** Removes all values. */
|
jens@0
|
45 |
void removeAll();
|
jens@0
|
46 |
|
jens@0
|
47 |
void dump() const;
|
jens@0
|
48 |
|
jens@0
|
49 |
class IndexEntry;
|
jens@0
|
50 |
|
jens@0
|
51 |
class Iterator {
|
jens@0
|
52 |
public:
|
jens@0
|
53 |
Iterator (const Hash *h);
|
jens@0
|
54 |
Iterator (const Hash &h);
|
jens@0
|
55 |
operator bool() const {return hasValue();}
|
jens@0
|
56 |
Value operator*() const {return value();}
|
jens@0
|
57 |
Iterator& operator++() {next(); return *this;}
|
jens@0
|
58 |
|
jens@0
|
59 |
Key key() const;
|
jens@0
|
60 |
Value value() const;
|
jens@0
|
61 |
bool hasValue() const {return _entry < _end;}
|
jens@0
|
62 |
bool next();
|
jens@0
|
63 |
private:
|
jens@0
|
64 |
Iterator (IndexEntry *start, IndexEntry*end);
|
jens@0
|
65 |
IndexEntry* _entry;
|
jens@0
|
66 |
IndexEntry* const _end;
|
jens@0
|
67 |
UNCOPYABLE(Iterator);
|
jens@0
|
68 |
};
|
jens@0
|
69 |
|
jens@0
|
70 |
private:
|
jens@0
|
71 |
IndexEntry& _find (Key key) const;
|
jens@0
|
72 |
IndexEntry& _findForPut (const IndexEntry &newEntry);
|
jens@0
|
73 |
void _resize(int newSize);
|
jens@0
|
74 |
void _read();
|
jens@0
|
75 |
UNCOPYABLE(Hash);
|
jens@0
|
76 |
|
jens@0
|
77 |
int _count;
|
jens@0
|
78 |
int _tableSize;
|
jens@0
|
79 |
IndexEntry *_table;
|
jens@0
|
80 |
|
jens@0
|
81 |
friend class Iterator;
|
jens@0
|
82 |
};
|
jens@0
|
83 |
|
jens@0
|
84 |
|
jens@0
|
85 |
|
jens@0
|
86 |
/** A concrete Dictionary implemented with a Hash. */
|
jens@0
|
87 |
class HashDictionary :public MutableDictionary {
|
jens@0
|
88 |
public:
|
jens@0
|
89 |
explicit HashDictionary (int capacity =50) :_hash(capacity) { }
|
jens@0
|
90 |
virtual ~HashDictionary();
|
jens@0
|
91 |
virtual int count() const {return _hash.count();}
|
jens@0
|
92 |
virtual bool contains (Key) const;
|
jens@0
|
93 |
virtual Blob get (Key key) const {return _convertValue(_hash.get(key));}
|
jens@0
|
94 |
virtual void put (Key, Blob value);
|
jens@0
|
95 |
virtual bool remove (Key);
|
jens@0
|
96 |
virtual void removeAll();
|
jens@0
|
97 |
virtual Iterator* iterate() const {return new Iterator(*this);}
|
jens@0
|
98 |
|
jens@0
|
99 |
class Iterator :public Dictionary::Iterator {
|
jens@0
|
100 |
public:
|
jens@0
|
101 |
explicit Iterator (const HashDictionary &d) :_it(d._hash) { }
|
jens@0
|
102 |
virtual Key key() const {return _it.key();}
|
jens@0
|
103 |
virtual Blob value() const {return _convertValue(_it.value());}
|
jens@0
|
104 |
virtual bool hasValue() const {return _it.hasValue();}
|
jens@0
|
105 |
virtual bool next() {return _it.next();}
|
jens@0
|
106 |
private:
|
jens@0
|
107 |
Hash::Iterator _it;
|
jens@0
|
108 |
};
|
jens@0
|
109 |
|
jens@0
|
110 |
private:
|
jens@0
|
111 |
static Blob _convertValue (void*);
|
jens@0
|
112 |
Hash _hash;
|
jens@0
|
113 |
friend class Iterator;
|
jens@0
|
114 |
};
|
jens@0
|
115 |
|
jens@0
|
116 |
|
jens@0
|
117 |
}
|
jens@0
|
118 |
|
jens@0
|
119 |
#endif _MOOSEYARD_HASH_
|