Ptex: PtexHashMap.h Source File

Ptex

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

PtexHashMap.h
Go to the documentation of this file.
1 /*
2 PTEX SOFTWARE
3 Copyright 2009 Disney Enterprises, Inc. All rights reserved
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the
15 distribution.
16
17 * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation
18 Studios" or the names of its contributors may NOT be used to
19 endorse or promote products derived from this software without
20 specific prior written permission from Walt Disney Pictures.
21
22 Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND
23 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
24 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
25 FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED.
26 IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY
31 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
34 */
40 #ifndef PtexHashMap_h
41 #define PtexHashMap_h
42
84 template<typename KeyType, typename DataType, typename HashFn>
85 class PtexHashMap
86 {
87 struct Entry; // forward decl
88
89 public:
90 typedef KeyType key_type;
91 typedef DataType data_type;
92 typedef HashFn hash_fn;
93
94 struct value_type {
95 key_type first;
96 data_type second;
97 value_type() : first(), second() {}
98 value_type(const KeyType& first, const DataType& second)
99 : first(first), second(second) {}
100 };
101
102 class iterator {
103 public:
105 iterator() : e(0), h(0), b(0) {}
106
108 iterator(const iterator& iter) : e(iter.e), h(iter.h), b(iter.b) {}
109
111 value_type operator*() const {
112 if (e) return value_type((*e)->key, (*e)->val);
113 return value_type();
114 }
115
117 iterator& operator=(const iterator& iter) {
118 e = iter.e; h = iter.h; b = iter.b; return *this;
119 }
120
122 bool operator==(const iterator& iter) const { return iter.e == e; }
124 bool operator!=(const iterator& iter) const { return iter.e != e; }
126 iterator& operator++(int);
127
128 private:
129 friend class PtexHashMap;
130 Entry** e; // pointer to prev entry or hash entry
131 const PtexHashMap* h;
132 int b; // bucket number
133 };
134
136 iterator begin() const
137 {
138 iterator iter;
139 iter.h = this;
140 for (iter.b = 0; iter.b < _numBuckets; iter.b++) {
141 iter.e = &_buckets[iter.b];
142 if (*iter.e) return iter;
143 }
144 iter.e = 0;
145 return iter;
146 }
147
149 iterator end() const
150 {
151 iterator iter;
152 iter.h = this; iter.b = 0; iter.e = 0;
153 return iter;
154 }
155
156
158 PtexHashMap() : _numEntries(0), _numBuckets(0), _bucketMask(0), _buckets(0) {}
160 ~PtexHashMap() { clear(); }
161
163
166 DataType& operator[](const KeyType& key);
167
169
175 iterator find(const KeyType& key) const;
176
178 bool erase(const KeyType& key);
180 iterator erase(iterator iter);
181
183 void clear();
184
186 int size() const { return _numEntries; }
187
188 private:
190 PtexHashMap(const PtexHashMap&); // disallow
192 bool operator=(const PtexHashMap&); // disallow
193
194 friend class iterator;
195
196 struct Entry {
197 Entry() : val() {}
198 Entry* next;
199 KeyType key;
200 DataType val;
201 };
202
204 Entry** locate(const KeyType& key) const
205 {
206 if (!_buckets) return 0;
207 for (Entry** e = &_buckets[hash(key) & _bucketMask]; *e; e = &(*e)->next)
208 if ((*e)->key == key)
209 return e;
210 return 0;
211 }
212
214 void grow();
215
216 int _numEntries;
217 int _numBuckets;
218 int _bucketMask;
219 Entry** _buckets;
220 HashFn hash;
221 };
222
223
224 template<class KeyType, class DataType, class HashFn>
225 typename PtexHashMap<KeyType, DataType, HashFn>::iterator&
226 PtexHashMap<KeyType, DataType, HashFn>::iterator::operator++(int)
227 {
228 if (e) {
229 // move to next entry
230 e = &(*e)->next;
231 if (!*e) {
232 // move to next non-empty bucket
233 for (b++; b < h->_numBuckets; b++) {
234 e = &h->_buckets[b];
235 if (*e) return *this;
236 }
237 e = 0;
238 }
239 }
240 return *this;
241 }
242
243
244 template<class KeyType, class DataType, class HashFn>
245 typename PtexHashMap<KeyType, DataType, HashFn>::iterator
246 PtexHashMap<KeyType, DataType, HashFn>::find(const KeyType& key) const
247 {
248 iterator iter;
249 Entry** e = locate(key);
250 if (e) {
251 iter.h = this;
252 iter.e = e;
253 iter.b = hash(key) & _bucketMask;
254 } else iter = end();
255 return iter;
256 }
257
258 template<class KeyType, class DataType, class HashFn>
259 DataType& PtexHashMap<KeyType, DataType, HashFn>::operator[](const KeyType& key)
260 {
261 Entry** e = locate(key);
262 if (e) return (*e)->val;
263
264 // create a new entry
265 _numEntries++;
266 if (_numEntries*2 >= _numBuckets) grow();
267 void* ebuf = malloc(sizeof(Entry));
268 Entry* ne = new(ebuf) Entry; // note: placement new
269 Entry** slot = &_buckets[hash(key) & _bucketMask];
270 ne->next = *slot; *slot = ne;
271 ne->key = key;
272 return ne->val;
273 }
274
275
276 template<class KeyType, class DataType, class HashFn>
277 void PtexHashMap<KeyType, DataType, HashFn>::grow()
278 {
279 if (!_buckets) {
280 _numBuckets = 16;
281 _bucketMask = _numBuckets - 1;
282 _buckets = (Entry**) calloc(_numBuckets, sizeof(Entry*));
283 } else {
284 int newsize = _numBuckets * 2;
285 _bucketMask = newsize - 1;
286 Entry** newbuckets = (Entry**) calloc(newsize, sizeof(Entry*));
287 for (int i = 0; i < _numBuckets; i++) {
288 for (Entry* e = _buckets[i]; e;) {
289 Entry* next = e->next;
290 Entry** slot = &newbuckets[hash(e->key) & _bucketMask];
291 e->next = *slot; *slot = e;
292 e = next;
293 }
294 }
295 free(_buckets);
296 _buckets = newbuckets;
297 _numBuckets = newsize;
298 }
299 }
300
301
302 template<class KeyType, class DataType, class HashFn>
303 bool PtexHashMap<KeyType, DataType, HashFn>::erase(const KeyType& key)
304 {
305 iterator iter = find(key);
306 if (iter == end()) return 0;
307 erase(iter);
308 return 1;
309 }
310
311
312 template<class KeyType, class DataType, class HashFn>
313 typename PtexHashMap<KeyType, DataType, HashFn>::iterator
314 PtexHashMap<KeyType, DataType, HashFn>::erase(iterator iter)
315 {
316 Entry** eptr = iter.e;
317 if (!eptr) return iter;
318
319 // patch around deleted entry
320 Entry* e = *eptr;
321 Entry* next = e->next;
322 if (!next) iter++; // advance iterator if at end of chain
323 *eptr = next;
324
325
326 // destroy entry
327 e->~Entry(); // note: explicit dtor call
328 free(e);
329 _numEntries--;
330
331 return iter;
332 }
333
334
335 template<class KeyType, class DataType, class HashFn>
336 void PtexHashMap<KeyType, DataType, HashFn>::clear()
337 {
338 for (iterator i = begin(); i != end(); )
339 i = erase(i);
340 free(_buckets);
341 _buckets = 0;
342 _numEntries = 0;
343 _numBuckets = 0;
344 }
345
346 #endif
PtexHashMap::find
iterator find(const KeyType &key) const
Locates an entry, without creating a new one.
Definition: PtexHashMap.h:246
PtexHashMap::hash_fn
HashFn hash_fn
Definition: PtexHashMap.h:92
PtexHashMap::_buckets
Entry ** _buckets
Definition: PtexHashMap.h:219
PtexHashMap::operator=
bool operator=(const PtexHashMap &)
Assignment operator prohibited by design.
PtexHashMap::iterator::h
const PtexHashMap * h
Definition: PtexHashMap.h:131
PtexHashMap::iterator::operator++
iterator & operator++(int)
For advancing the iterator to the next element.
Definition: PtexHashMap.h:226
PtexHashMap::hash
HashFn hash
Definition: PtexHashMap.h:220
PtexHashMap::locate
Entry ** locate(const KeyType &key) const
Returns a pointer to the desired entry, based on the key.
Definition: PtexHashMap.h:204
PtexHashMap::value_type::value_type
value_type(const KeyType &first, const DataType &second)
Definition: PtexHashMap.h:98
PtexHashMap::~PtexHashMap
~PtexHashMap()
Non-Virtual destructor by design, clears the entries in the hash table.
Definition: PtexHashMap.h:160
PtexHashMap::grow
void grow()
Used to increase the size of the table if necessary.
Definition: PtexHashMap.h:277
PtexHashMap::size
int size() const
number of entries in the hash
Definition: PtexHashMap.h:186
PtexHashMap::operator[]
DataType & operator[](const KeyType &key)
Locates an entry, creating a new one if necessary.
Definition: PtexHashMap.h:259
PtexHashMap::Entry::val
DataType val
Definition: PtexHashMap.h:200
PtexHashMap::PtexHashMap
PtexHashMap()
Default contructor initializes the hash table.
Definition: PtexHashMap.h:158
PtexHashMap::erase
bool erase(const KeyType &key)
Will remove an entry. It will return TRUE if an entry was found.
Definition: PtexHashMap.h:303
PtexHashMap::iterator::iterator
iterator(const iterator &iter)
Proper copy constructor implementation.
Definition: PtexHashMap.h:108
PtexHashMap::value_type::second
data_type second
Definition: PtexHashMap.h:96
PtexHashMap::iterator::operator!=
bool operator!=(const iterator &iter) const
For comparing inequality of iterators.
Definition: PtexHashMap.h:124
PtexHashMap::_numBuckets
int _numBuckets
Definition: PtexHashMap.h:217
PtexHashMap::iterator::iterator
iterator()
Default Constructor.
Definition: PtexHashMap.h:105
PtexHashMap::value_type::first
key_type first
Definition: PtexHashMap.h:95
if
if(WIN32) add_definitions(/DPTEX_EXPORTS) endif(WIN32) set(SRCS PtexCache.cpp PtexFilters.cpp PtexHalf.cpp PtexReader.cpp PtexSeparableFilter.cpp PtexSeparableKernel.cpp PtexTriangleFilter.cpp PtexTriangleKernel.cpp PtexUtils.cpp PtexWriter.cpp) add_library(Ptex_static STATIC $
Definition: ptex/CMakeLists.txt:1
DataType
DataType
Type of data stored in texture file.
Definition: Ptexture.h:196
PtexHashMap::iterator::operator=
iterator & operator=(const iterator &iter)
Proper assignment operator.
Definition: PtexHashMap.h:117
PtexHashMap::iterator::operator*
value_type operator*() const
Operator for obtaining the value that the iterator references.
Definition: PtexHashMap.h:111
PtexHashMap::end
iterator end() const
Returns an iteraot referencing the location just beyond the table.
Definition: PtexHashMap.h:149
PtexHashMap::value_type
Definition: PtexHashMap.h:94
PtexHashMap::_bucketMask
int _bucketMask
Definition: PtexHashMap.h:218
PtexHashMap::Entry
Definition: PtexHashMap.h:196
PtexHashMap::iterator
friend class iterator
Definition: PtexHashMap.h:194
PtexHashMap::value_type::value_type
value_type()
Definition: PtexHashMap.h:97
PtexHashMap::data_type
DataType data_type
Definition: PtexHashMap.h:91
PtexHashMap::iterator::b
int b
Definition: PtexHashMap.h:132
PtexHashMap::iterator
Internal class used to provide iteration through the hash table.
Definition: PtexHashMap.h:102
PtexHashMap::Entry::key
KeyType key
Definition: PtexHashMap.h:199
PtexHashMap::key_type
KeyType key_type
Definition: PtexHashMap.h:87
PtexHashMap::iterator::e
Entry ** e
Definition: PtexHashMap.h:130
PtexHashMap::begin
iterator begin() const
Returns an iterator referencing the beginning of the table.
Definition: PtexHashMap.h:136
PtexHashMap::clear
void clear()
clear will remove all entries and free the table
Definition: PtexHashMap.h:336
PtexHashMap::Entry::next
Entry * next
Definition: PtexHashMap.h:198
PtexHashMap::_numEntries
int _numEntries
Definition: PtexHashMap.h:216
PtexHashMap::iterator::operator==
bool operator==(const iterator &iter) const
For comparing equality of iterators.
Definition: PtexHashMap.h:122
PtexHashMap
A lightweight hash table.
Definition: PtexHashMap.h:85
PtexHashMap::Entry::Entry
Entry()
Definition: PtexHashMap.h:197