Ptex: PtexDict.h Source File

Ptex

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

- File List
- File Members

PtexDict.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 PtexDict_h
41 #define PtexDict_h
42
110 template<class T>
111 class PtexDict
112 {
113 class Entry;
114
115 public: // Public Types
116 class iterator;
117 class const_iterator;
118 friend class iterator;
119 friend class const_iterator;
120
121 typedef const char* key_type;
122 typedef T mapped_type;
123
124 struct value_type {
125 public:
127 value_type(): first(0), second() {}
129 value_type(key_type f, const T& s): first(f), second(s) {}
130
131 const key_type first;
132 T second;
133 };
134
135 public: // Public Member Interfce
136
138 PtexDict() : _numEntries(0), _numBuckets(0), _bucketMask(0), _buckets(0) {}
140 virtual ~PtexDict() { clear(); }
141
143
146 T& operator[](const char* key);
147
149 iterator begin()
150 {
151 iterator iter;
152 iter._d = this;
153 for (iter._b = 0; iter._b < _numBuckets; iter._b++) {
154 iter._e = &_buckets[iter._b];
155 if (*iter._e) return iter;
156 }
157 iter._e = 0;
158 return iter;
159 }
160
162 inline iterator end() { return iterator( 0, this, 0 ); }
163
165 const_iterator begin() const
166 {
167 const_iterator iter;
168 iter._d = this;
169 for (iter._b = 0; iter._b < _numBuckets; iter._b++) {
170 iter._e = &_buckets[iter._b];
171 if (*iter._e) return iter;
172 }
173 iter._e = 0;
174 return iter;
175 }
176
178 inline const_iterator end() const { return const_iterator( 0, this, 0 ); }
179
181
187 iterator find(const char* key);
189 const_iterator find(const char* key) const;
190
192 bool erase(const char* key);
194
196 iterator erase(iterator iter);
197
199 void clear();
200
202 int size() const { return _numEntries; }
203
204 private: // Private Member Interface
205
207 class Entry {
208 public: // Public Member Interface
210 Entry() : _next(0), _hashval(0), _keylen(0),
211 _val(_u._key,T())
212 { _u._pad = 0; }
213 ~Entry() {}
214 private: // Private Member Interface
216 Entry(const Entry&);
218 Entry& operator=(const Entry&);
219
220 public:
221 Entry* _next;
222 int _hashval;
223 int _keylen;
224 value_type _val;
225 union {
226 int _pad;
227 char _key[1];
228 } _u;
229 };
230
232 PtexDict(const PtexDict&);
234 PtexDict& operator=(const PtexDict&);
235
237 int hash(const char* key, int& keylen) const
238 {
239 // this is similar to perl's hash function
240 int hashval = 0;
241 const char* cp = key;
242 char c;
243 while ((c = *cp++)) hashval = hashval * 33 + c;
244 keylen = int(cp-key)-1;
245 return hashval;
246 }
247
249 Entry** locate(const char* key, int& keylen, int& hashval) const
250 {
251 hashval = hash(key, keylen);
252 if (!_buckets) return 0;
253 for (Entry** e = &_buckets[hashval & _bucketMask]; *e; e=&(*e)->_next)
254 if ((*e)->_hashval == hashval && (*e)->_keylen == keylen &&
255 streq(key, (*e)->_u._key, keylen))
256 return e;
257 return 0;
258 }
259
261
264 static inline bool streq(const char* s1, const char* s2, int len)
265 {
266 // first make sure s1 is quad-aligned (s2 is always aligned)
267 if (((intptr_t)s1 & 3) == 0) {
268 int len4 = len >> 2;
269 while (len4--) {
270 if (*(int*)s1 != *(int*)s2) return 0;
271 s1 += 4; s2 += 4;
272 }
273 len &= 3;
274 }
275 while (len--) if (*s1++ != *s2++) return 0;
276 return 1;
277 }
278
280 void grow();
281
282 private: // Private Member data
283
284 int _numEntries;
285 int _numBuckets;
286 int _bucketMask;
287 Entry** _buckets;
288 };
289
290
305 template<class T>
306 class PtexDict<T>::iterator {
307 public:
309 iterator() : _d(0), _e(0), _b(0) {}
310
312 iterator(const iterator& iter) :
313 _d(iter._d), _e(iter._e), _b(iter._b) {}
315 inline iterator& operator=(const iterator& iter)
316 { _e = iter._e; _d = iter._d; _b = iter._b; return *this; }
317
319 inline value_type& operator*() const { return getValue(); }
321 inline value_type* operator->() const { return &getValue(); }
322
324 inline operator bool() { return _e != 0; }
325
327 inline bool operator==(const iterator& iter) const
328 { return iter._e == _e; }
330 inline bool operator!=(const iterator& iter) const
331 { return iter._e != _e; }
333 inline bool operator==(const const_iterator& iter) const
334 { return iter._e == _e; }
336 inline bool operator!=(const const_iterator& iter) const
337 { return iter._e != _e; }
339 iterator& operator++(int);
340
341 private: // Private interface
342
344 iterator( Entry** e, const PtexDict* d, int b): _d(d), _e(e), _b(b) {}
345
347 inline value_type& getValue() const{
348 if (_e) return (*_e)->_val;
349 else return _defaultVal;
350 }
351
352 friend class PtexDict;
353 friend class const_iterator;
354 const PtexDict* _d;
355 Entry** _e;
356 int _b;
357
358 static value_type _defaultVal;
359 };
360
361 // define the static type for the iterator
362 template<class T> typename PtexDict<T>::value_type PtexDict<T>::iterator::_defaultVal;
363
376 template<class T>
377 class PtexDict<T>::const_iterator {
378 public:
380 const_iterator() : _d(0), _e(0), _b(0) {}
381
383 const_iterator(const const_iterator& iter) :
384 _d(iter._d), _e(iter._e), _b(iter._b) {}
386 const_iterator(const iterator& iter) :
387 _d(iter._d), _e(iter._e), _b(iter._b) {}
389 inline const_iterator& operator=(const const_iterator& iter)
390 { _e = iter._e; _d = iter._d; _b = iter._b; return *this; }
392 inline const_iterator& operator=(iterator& iter)
393 { _e = iter._e; _d = iter._d; _b = iter._b; return *this; }
394
396 inline const value_type& operator*() const { return getValue(); }
398 inline const value_type* operator->() const { return &getValue(); }
399
401 inline operator bool() { return _e != 0; }
402
404 inline bool operator==(const iterator& iter) const
405 { return iter._e == _e; }
407 inline bool operator!=(const iterator& iter) const
408 { return iter._e != _e; }
410 inline bool operator==(const const_iterator& iter) const
411 { return iter._e == _e; }
413 inline bool operator!=(const const_iterator& iter) const
414 { return iter._e != _e; }
416 const_iterator& operator++(int);
417
418 private: // Private interface
419
421 const_iterator( Entry** e, const PtexDict* d, int b): _d(d),_e(e),_b(b) {}
422
424 inline const value_type& getValue() const{
425 if (_e) return (*_e)->_val;
426 else return _defaultVal;
427 }
428
429 friend class PtexDict;
430 friend class iterator;
431 const PtexDict* _d;
432 Entry** _e;
433 int _b;
434
435 static value_type _defaultVal;
436 };
437
438 // define the static type for the iterator
439 template<class T> typename PtexDict<T>::value_type PtexDict<T>::const_iterator::_defaultVal;
440
441 template<class T>
442 typename PtexDict<T>::iterator& PtexDict<T>::iterator::operator++(int)
443 {
444 if (_e) {
445 // move to next entry
446 _e = &(*_e)->_next;
447 if (!*_e) {
448 // move to next non-empty bucket
449 for (_b++; _b < _d->_numBuckets; _b++) {
450 _e = &_d->_buckets[_b];
451 if (*_e) return *this;
452 }
453 _e = 0;
454 }
455 }
456 return *this;
457 }
458
459 template<class T>
460 typename PtexDict<T>::const_iterator& PtexDict<T>::const_iterator::operator++(int)
461 {
462 if (_e) {
463 // move to next entry
464 _e = &(*_e)->_next;
465 if (!*_e) {
466 // move to next non-empty bucket
467 for (_b++; _b < _d->_numBuckets; _b++) {
468 _e = &_d->_buckets[_b];
469 if (*_e) return *this;
470 }
471 _e = 0;
472 }
473 }
474 return *this;
475 }
476
477 template<class T>
478 typename PtexDict<T>::iterator PtexDict<T>::find(const char* key)
479 {
480 int keylen, hashval;
481 Entry** e = locate(key, keylen, hashval);
482
484 if (e) return iterator( e, this, hashval & _bucketMask );
485 else return end();
486 }
487
488 template<class T>
489 typename PtexDict<T>::const_iterator PtexDict<T>::find(const char* key) const
490 {
491 int keylen, hashval;
492 Entry** e = locate(key, keylen, hashval);
493
495 if (e) return const_iterator( e, this, hashval & _bucketMask );
496 else return end();
497 }
498
499 template<class T>
500 T& PtexDict<T>::operator[](const char* key)
501 {
502 int keylen, hashval;
503 Entry** e = locate(key, keylen, hashval);
504 if (e) return (*e)->_val.second;
505
506 // create a new entry
507 _numEntries++;
508 if (_numEntries*2 >= _numBuckets) grow();
509
510 // allocate a buffer big enough to hold Entry + (the key length )
511 // Note: the NULL character is already accounted for by Entry::_key's size
512 void* ebuf = malloc( sizeof(Entry) + (keylen) * sizeof(char) );
513 Entry* ne = new(ebuf) Entry; // note: placement new
514
515 // Store the values in the Entry structure
516 Entry** slot = &_buckets[hashval & _bucketMask];
517 ne->_next = *slot; *slot = ne;
518 ne->_hashval = hashval;
519 ne->_keylen = keylen;
520
521 // copy the string given into the new location
522 memcpy(ne->_u._key, key, keylen);
523 ne->_u._key[keylen] = '\0';
524 return ne->_val.second;
525 }
526
527
528 template<class T>
529 void PtexDict<T>::grow()
530 {
531 if (!_buckets) {
532 _numBuckets = 16;
533 _bucketMask = _numBuckets - 1;
534 _buckets = (Entry**) calloc(_numBuckets, sizeof(Entry*));
535 } else {
536 int newsize = _numBuckets * 2;
537 _bucketMask = newsize - 1;
538 Entry** newbuckets = (Entry**) calloc(newsize, sizeof(Entry*));
539 for (int i = 0; i < _numBuckets; i++) {
540 for (Entry* e = _buckets[i]; e;) {
541 Entry* _next = e->_next;
542 Entry** slot = &newbuckets[e->_hashval & _bucketMask];
543 e->_next = *slot; *slot = e;
544 e = _next;
545 }
546 }
547 free(_buckets);
548 _buckets = newbuckets;
549 _numBuckets = newsize;
550 }
551 }
552
553
554 template<class T>
555 bool PtexDict<T>::erase(const char* key)
556 {
557 iterator iter = find(key);
558 if (!iter) return false;
559
560 erase(iter);
561 return true; // valid entry to remove
562 }
563
564
565 template<class T>
566 typename PtexDict<T>::iterator PtexDict<T>::erase(iterator iter)
567 {
568 Entry** eptr = iter._e;
569 if (!eptr) return iter;
570
571 // patch around deleted entry
572 Entry* e = *eptr;
573 Entry* next = e->_next;
574 if (!next) iter++; // advance iterator if at end of chain
575 *eptr = next;
576
577 // destroy entry. This is a strange destroy but is necessary because of
578 // the way Entry() is allocated by using malloc above.
579 e->~Entry(); // note: explicit dtor call
580 free(e); // free memory allocated.
581 _numEntries--;
582
583 return iter;
584 }
585
586
587 template<class T>
588 void PtexDict<T>::clear()
589 {
590 for (iterator i=begin(); i != end(); )
591 i = erase(i);
592 free(_buckets);
593 _buckets = 0;
594 _numEntries = 0;
595 _numBuckets = 0;
596 }
597
598 #endif //PtexDict_h
PtexDict::_numEntries
int _numEntries
The number of entries in the dictionary.
Definition: PtexDict.h:284
PtexDict::streq
static bool streq(const char *s1, const char *s2, int len)
Used for string compares, much faster then strcmp.
Definition: PtexDict.h:264
PtexDict::iterator::iterator
iterator(Entry **e, const PtexDict *d, int b)
Constructor Helper for inline creation.
Definition: PtexDict.h:344
PtexDict::value_type::second
T second
Reference to the data.
Definition: PtexDict.h:132
PtexDict::PtexDict
PtexDict()
Default contructor initializes the dictionary.
Definition: PtexDict.h:138
PtexDict::const_iterator::_e
Entry ** _e
pointer to entry in table this iterator refs
Definition: PtexDict.h:432
PtexDict::end
const_iterator end() const
Const access to the end of the list.
Definition: PtexDict.h:178
PtexDict::const_iterator::operator==
bool operator==(const const_iterator &iter) const
For comparing equality of const_iterators.
Definition: PtexDict.h:410
PtexDict::iterator::operator==
bool operator==(const iterator &iter) const
For comparing equality of iterators.
Definition: PtexDict.h:327
PtexDict::erase
bool erase(const char *key)
Will remove an entry. It will return TRUE if an entry was found.
Definition: PtexDict.h:555
PtexDict::Entry::_next
Entry * _next
Pointer to the next element in the structure.
Definition: PtexDict.h:221
PtexDict::end
iterator end()
Returns an iterator referencing the end of the table.
Definition: PtexDict.h:162
PtexDict::begin
const_iterator begin() const
Const access to the beginning of the list.
Definition: PtexDict.h:165
PtexDict::~PtexDict
virtual ~PtexDict()
clears the entries in the dictionary
Definition: PtexDict.h:140
PtexDict::iterator::iterator
iterator(const iterator &iter)
Proper copy constructor implementation.
Definition: PtexDict.h:312
PtexDict::iterator::operator*
value_type & operator*() const
Operator for obtaining the value that the iterator references.
Definition: PtexDict.h:319
PtexDict::const_iterator::const_iterator
const_iterator()
Default Constructor.
Definition: PtexDict.h:380
PtexDict::Entry::_u
union PtexDict::Entry::@0 _u
PtexDict::const_iterator::operator->
const value_type * operator->() const
Pointer reference operator.
Definition: PtexDict.h:398
PtexDict::clear
void clear()
clear will remove all entries from the dictionary. O(n)
Definition: PtexDict.h:588
PtexDict::iterator::operator->
value_type * operator->() const
Pointer reference operator.
Definition: PtexDict.h:321
PtexDict::begin
iterator begin()
Returns an iterator referencing the beginning of the table.
Definition: PtexDict.h:149
PtexDict::const_iterator::operator!=
bool operator!=(const iterator &iter) const
For comparing inequality of iterators.
Definition: PtexDict.h:407
PtexDict::Entry::_key
char _key[1]
1 is dummy length - actual size will be allocated
Definition: PtexDict.h:227
PtexDict::value_type::value_type
value_type(key_type f, const T &s)
Creation constructor.
Definition: PtexDict.h:129
PtexDict::iterator::operator==
bool operator==(const const_iterator &iter) const
For comparing equality of iterators.
Definition: PtexDict.h:333
PtexDict::iterator::getValue
value_type & getValue() const
simple helper function for retrieving the value from the Entry
Definition: PtexDict.h:347
PtexDict::_numBuckets
int _numBuckets
The number of buckets in use.
Definition: PtexDict.h:285
PtexDict::Entry::Entry
Entry()
Default constructor initiaizes val with the defaul value.
Definition: PtexDict.h:210
PtexDict::hash
int hash(const char *key, int &keylen) const
Returns the integer hash index for the key and length of the key.
Definition: PtexDict.h:237
PtexDict::Entry::~Entry
~Entry()
Definition: PtexDict.h:213
PtexDict::iterator::_defaultVal
static value_type _defaultVal
Default value.
Definition: PtexDict.h:358
PtexDict::Entry
This internal structure is used to store the dictionary elements.
Definition: PtexDict.h:207
PtexDict::Entry::_val
value_type _val
The stored value of the hash table.
Definition: PtexDict.h:224
PtexDict::size
int size() const
Returns the number of entries in the dictionary. O(1) time to call.
Definition: PtexDict.h:202
PtexDict::iterator::_b
int _b
bucket number this references
Definition: PtexDict.h:356
PtexDict::key_type
const char * key_type
This is the lookup type.
Definition: PtexDict.h:121
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
PtexDict::Entry::_pad
int _pad
for integer align of _key, for fast compares
Definition: PtexDict.h:226
PtexDict::iterator::iterator
iterator()
Default Constructor.
Definition: PtexDict.h:309
PtexDict::const_iterator::operator=
const_iterator & operator=(iterator &iter)
Proper assignment operator for iterator.
Definition: PtexDict.h:392
PtexDict::const_iterator::operator*
const value_type & operator*() const
Operator for obtaining the value that the const_iterator references.
Definition: PtexDict.h:396
PtexDict::find
iterator find(const char *key)
Locates an entry, without creating a new one.
Definition: PtexDict.h:478
PtexDict::iterator::operator++
iterator & operator++(int)
For advancing the iterator to the next element.
Definition: PtexDict.h:442
PtexDict::iterator::operator!=
bool operator!=(const iterator &iter) const
For comparing inequality of iterators.
Definition: PtexDict.h:330
PtexDict::value_type::value_type
value_type()
Default constructor references default_value, with a 0 for first.
Definition: PtexDict.h:127
PtexDict::const_iterator::operator!=
bool operator!=(const const_iterator &iter) const
For comparing inequality of iterators.
Definition: PtexDict.h:413
PtexDict::iterator::operator!=
bool operator!=(const const_iterator &iter) const
For comparing inequality of iterators.
Definition: PtexDict.h:336
PtexDict::iterator::operator=
iterator & operator=(const iterator &iter)
Proper assignment operator.
Definition: PtexDict.h:315
PtexDict::const_iterator::const_iterator
const_iterator(const const_iterator &iter)
Proper copy constructor implementation for const_iterator.
Definition: PtexDict.h:383
PtexDict::value_type
Internal class used to provide a return value for the value type.
Definition: PtexDict.h:124
PtexDict::Entry::_keylen
int _keylen
cached length of key
Definition: PtexDict.h:223
PtexDict::mapped_type
T mapped_type
The data type stored.
Definition: PtexDict.h:122
PtexDict
A string-keyed dictionary template, using a hash table.
Definition: PtexDict.h:111
PtexDict::const_iterator::operator++
const_iterator & operator++(int)
For advancing the iterator to the next element.
Definition: PtexDict.h:460
PtexDict::Entry::operator=
Entry & operator=(const Entry &)
Assignment operator prohibited by design.
PtexDict::grow
void grow()
Used to increase the size of the table if necessary.
Definition: PtexDict.h:529
PtexDict::Entry::_hashval
int _hashval
cached hashval of key
Definition: PtexDict.h:222
PtexDict::const_iterator
friend class const_iterator
Definition: PtexDict.h:119
PtexDict::const_iterator::const_iterator
const_iterator(const iterator &iter)
Conversion constructor for iterator.
Definition: PtexDict.h:386
PtexDict::const_iterator::_b
int _b
bucket number this references
Definition: PtexDict.h:433
PtexDict::const_iterator::_d
const PtexDict * _d
dictionary back reference
Definition: PtexDict.h:431
PtexDict::const_iterator::operator=
const_iterator & operator=(const const_iterator &iter)
Proper assignment operator for const_iterator.
Definition: PtexDict.h:389
PtexDict::operator=
PtexDict & operator=(const PtexDict &)
Assignment operator prohibited by design.
PtexDict::_buckets
Entry ** _buckets
The pointer to the bucket structure.
Definition: PtexDict.h:287
PtexDict::iterator
Internal class used to provide iteration through the dictionary.
Definition: PtexDict.h:306
PtexDict::iterator::_e
Entry ** _e
pointer to entry in table this iterator refs
Definition: PtexDict.h:355
PtexDict::const_iterator::operator==
bool operator==(const iterator &iter) const
For comparing equality of iterators.
Definition: PtexDict.h:404
PtexDict::const_iterator::getValue
const value_type & getValue() const
simple helper function for retrieving the value from the Entry
Definition: PtexDict.h:424
PtexDict::operator[]
T & operator[](const char *key)
Locates an entry, creating a new one if necessary.
Definition: PtexDict.h:500
PtexDict::iterator
friend class iterator
forward declared class
Definition: PtexDict.h:117
PtexDict::locate
Entry ** locate(const char *key, int &keylen, int &hashval) const
Returns a pointer to the desired entry, based on the key.
Definition: PtexDict.h:249
PtexDict::value_type::first
const key_type first
Reference to the key type.
Definition: PtexDict.h:131
PtexDict::const_iterator::_defaultVal
static value_type _defaultVal
Default value.
Definition: PtexDict.h:435
PtexDict::iterator::_d
const PtexDict * _d
dictionary back reference
Definition: PtexDict.h:354
PtexDict::const_iterator
Internal class used to provide iteration through the dictionary.
Definition: PtexDict.h:377
PtexDict::const_iterator::const_iterator
const_iterator(Entry **e, const PtexDict *d, int b)
Constructor Helper for inline creation.
Definition: PtexDict.h:421
PtexDict::_bucketMask
int _bucketMask
The mask for the buckets.
Definition: PtexDict.h:286