author | Jens Alfke <jens@mooseyard.com> |
Sun Sep 20 15:14:12 2009 -0700 (2009-09-20) | |
changeset 0 | 31a43d94cc26 |
permissions | -rw-r--r-- |
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@0 | 41 |
/** Removes the value with the given key. */ |
jens@0 | 42 |
bool 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_ |