#include <avmplusHashtable.h>
Inheritance diagram for avmplus::Hashtable:

Public Types | |
| enum | { kDontEnumBit = 1 } |
Public Member Functions | |
| int | getSize () const |
| int | getNumAtoms () const |
| bool | hasDontEnumSupport () const |
| void | setDontEnumSupport (bool flag) |
| int | dontEnumMask () const |
| bool | getAtomPropertyIsEnumerable (Atom name) const |
| void | setAtomPropertyIsEnumerable (Atom name, bool enumerable) |
| Atom * | getAtoms () |
| Hashtable (MMgc::GC *gc, int capacity=kDefaultCapacity) | |
| void | destroy () |
| void | reset () |
| void | initialize (MMgc::GC *gc, int capacity=kDefaultCapacity) |
| virtual | ~Hashtable () |
| bool | isFull () const |
| int | find (Atom x, const Atom *t, unsigned tLen) const |
| int | find (Stringp x, const Atom *t, unsigned tLen) const |
| int | find (Atom x) const |
| void | add (Atom name, Atom value) |
| void | grow () |
| int | next (int index) |
| Atom | keyAt (int index) |
| Atom | valueAt (int index) |
| void | setHasDeletedItems (bool val) |
operations on name/value pairs | |
| Atom | get (Atom name) const |
| Atom | remove (Atom name) |
| bool | contains (Atom name) const |
| void | put (Atom name, const void *value) |
| void | add (Atom name, const void *value) |
Static Public Attributes | |
| static const Atom | EMPTY = 0 |
| static const Atom | DELETED = undefinedAtom |
| static const int | kDefaultCapacity = 8 |
Protected Member Functions | |
| void | put (Atom name, Atom value) |
| int | rehash (Atom *oldAtoms, int oldlen, Atom *newAtoms, int newlen) |
Protected Attributes | |
| Atom * | atoms |
Private Types | |
| enum | { kDontEnumSupport = 1, kHasDeletedItems = 2 } |
Private Member Functions | |
| bool | hasDeletedItems () const |
| void | setNumAtoms (int numAtoms) |
| void | setAtoms (Atom *atoms) |
Static Private Member Functions | |
| static int | FindOneBit (uint32 value) |
Private Attributes | |
| int32_t | size |
| int16_t | logNumAtoms |
| int16_t | flags |
Definition at line 47 of file avmplusHashtable.h.
|
|
Definition at line 74 of file avmplusHashtable.h. 00075 { 00076 kDontEnumBit = 1 00077 };
|
|
|
Definition at line 81 of file avmplusHashtable.h. 00082 { 00083 kDontEnumSupport = 1, 00084 kHasDeletedItems = 2 00085 };
|
|
||||||||||||
|
initialize with a known capacity. i.e. we can fit minSize elements in without rehashing.
Definition at line 55 of file avmplusHashtable.cpp. References initialize(). 00056 { 00057 initialize(gc, capacity); 00058 }
|
|
|
Definition at line 70 of file avmplusHashtable.cpp. References destroy(). 00071 { 00072 destroy(); 00073 }
|
|
||||||||||||
|
Adds a name/value pair to a hash table. Automatically grows the hash table if it is full. Reimplemented in avmplus::WeakKeyHashtable, and avmplus::WeakValueHashtable. Definition at line 227 of file avmplusHashtable.cpp. References grow(), isFull(), and put().
|
|
||||||||||||
|
Definition at line 214 of file avmplusHashtable.h. Referenced by avmplus::AbcParser::addTraits(), avmplus::ScriptObject::setAtomProperty(), avmplus::ScriptObject::setUintProperty(), and avmplus::XMLParser::XMLParser().
|
|
|
Definition at line 197 of file avmplusHashtable.h. References atoms, dontEnumMask(), find(), and getNumAtoms(). Referenced by avmplus::WeakKeyHashtable::contains(), getAtomPropertyIsEnumerable(), avmplus::ScriptObject::hasAtomProperty(), and avmplus::ScriptObject::hasUintProperty(). 00198 { 00199 return (atoms[find(name, atoms, getNumAtoms())] & ~dontEnumMask()) == name; 00200 }
|
|
|
Definition at line 75 of file avmplusHashtable.cpp. References atoms, flags, MMgc::GC::Free(), MMgc::GC::GetGC(), getNumAtoms(), NULL, setNumAtoms(), and size. Referenced by reset(), and ~Hashtable(). 00076 { 00077 if(atoms) { 00078 GC *gc = GC::GetGC(atoms); 00079 #ifdef MMGC_DRC 00080 AvmCore::decrementAtomRegion(atoms, getNumAtoms()); 00081 #endif 00082 gc->Free (atoms); 00083 } 00084 atoms = NULL; 00085 setNumAtoms(0); 00086 size = 0; 00087 flags = 0; 00088 }
|
|
|
Definition at line 68 of file avmplusHashtable.h. References hasDontEnumSupport(), and kDontEnumBit. Referenced by contains(), find(), next(), avmplus::ScriptObject::nextName(), avmplus::ScriptObject::nextNameIndex(), avmplus::ScriptObject::nextValue(), put(), and remove(). 00068 { return hasDontEnumSupport() ? kDontEnumBit : 0; }
|
|
|
Definition at line 230 of file avmplusHashtable.h. References atoms, find(), and getNumAtoms(). 00230 { return find(x, atoms, getNumAtoms()); }
|
|
||||||||||||||||
|
Definition at line 116 of file avmplusHashtable.cpp. References avmplus::String::atom(), AvmAssert, find(), and NULL.
|
|
||||||||||||||||
|
Finds the hash bucket corresponding to the key x in the hash table starting at t, containing tLen atoms. This is a quadratic probe, but we only hit even-numbered slots since those hold keys. Definition at line 122 of file avmplusHashtable.cpp. References avmplus::AvmCore::atomToString(), AvmAssert, avmplus::AvmDebugMsg(), avmplus::String::c_str(), runtests::debug, DELETED, dontEnumMask(), EMPTY, util::threadpool::i, and avmplus::AvmCore::isString(). Referenced by contains(), find(), get(), avmplus::ScriptObject::getAtomProperty(), getAtomPropertyIsEnumerable(), avmplus::ScriptObject::getUintProperty(), put(), rehash(), remove(), and setAtomPropertyIsEnumerable(). 00123 { 00124 int mask = ~dontEnumMask(); 00125 x &= mask; 00126 00127 #if 0 // debug code to print out the strings we're searching for 00128 static int debug =0; 00129 if (debug && AvmCore::isString(x)) 00130 { 00131 Stringp s = AvmCore::atomToString(x); 00132 AvmDebugMsg (s->c_str(), false); 00133 AvmDebugMsg ("\n", false); 00134 } 00135 #endif 00136 00137 int bitmask = (m - 1) & ~0x1; 00138 00139 AvmAssert(x != EMPTY && x != DELETED); 00140 // this is a quadratic probe but we only hit even numbered slots since those hold keys. 00141 int n = 7 << 1; 00142 #ifdef _DEBUG 00143 unsigned loopCount = 0; 00144 #endif 00145 // Note: Mask off MSB to avoid negative indices. Mask off bottom 00146 // 3 bits because it doesn't contribute to hash. Double it 00147 // because names, values stored adjacently. 00148 unsigned i = ((0x7FFFFFF8 & x)>>2) & bitmask; 00149 Atom k; 00150 while ((k=t[i]&mask) != x && k != EMPTY) 00151 { 00152 i = (i + (n += 2)) & bitmask; // quadratic probe 00153 AvmAssert(loopCount++ < m); // don't scan forever 00154 } 00155 AvmAssert(i <= ((m-1)&~0x1)); 00156 return i; 00157 }
|
|
|
Definition at line 148 of file avmplusHashtable.h. References AvmAssert, and util::threadpool::i. Referenced by setNumAtoms(). 00149 { 00150 for (int i=0; i < 32; i++) 00151 if (value & (1<<i)) 00152 return i; 00153 // asm versions of this function are undefined if no bits are set 00154 AvmAssert(false); 00155 return 0; 00156 }
|
|
|
Definition at line 110 of file avmplusHashtable.cpp. References atoms, find(), getNumAtoms(), util::threadpool::i, and avmplus::AtomConstants::undefinedAtom. Referenced by avmplus::WeakValueHashtable::get(), avmplus::WeakKeyHashtable::get(), and avmplus::AvmCore::handleActionBlock(). 00111 { 00112 int i; 00113 return atoms[i = find(name, atoms, getNumAtoms())] == name ? atoms[i+1] : undefinedAtom; 00114 }
|
|
|
Definition at line 293 of file avmplusHashtable.cpp. References atoms, contains(), find(), getNumAtoms(), hasDontEnumSupport(), util::threadpool::i, and kDontEnumBit. Referenced by avmplus::ScriptObject::getAtomPropertyIsEnumerable(). 00294 { 00295 if (hasDontEnumSupport()) 00296 { 00297 int i = find(name, atoms, getNumAtoms()); 00298 if ((atoms[i]&~kDontEnumBit) == name) 00299 { 00300 return (atoms[i]&kDontEnumBit) == 0; 00301 } 00302 else 00303 { 00304 return false; 00305 } 00306 } 00307 else 00308 { 00309 return contains(name); 00310 } 00311 }
|
|
|
Definition at line 164 of file avmplusHashtable.h. References atoms. Referenced by avmplus::ScriptObject::getAtomProperty(), avmplus::ScriptObject::getUintProperty(), avmplus::ScriptObject::nextName(), avmplus::DictionaryObject::nextNameIndex(), avmplus::ScriptObject::nextNameIndex(), and avmplus::ScriptObject::nextValue(). 00164 { return atoms; }
|
|
|
Definition at line 63 of file avmplusHashtable.h. References logNumAtoms. Referenced by contains(), destroy(), find(), get(), avmplus::ScriptObject::getAtomProperty(), getAtomPropertyIsEnumerable(), avmplus::ScriptObject::getUintProperty(), grow(), initialize(), isFull(), next(), avmplus::ScriptObject::nextName(), avmplus::DictionaryObject::nextNameIndex(), avmplus::ScriptObject::nextNameIndex(), avmplus::ScriptObject::nextValue(), avmplus::WeakValueHashtable::prune(), avmplus::WeakKeyHashtable::prune(), put(), remove(), setAtomPropertyIsEnumerable(), and setNumAtoms(). 00063 { return logNumAtoms ? 1<<(logNumAtoms-1) : 0; }
|
|
|
Definition at line 62 of file avmplusHashtable.h. References size. Referenced by isFull(). 00062 { return size; }
|
|
|
Called to grow the Hashtable, particularly by add.
Definition at line 236 of file avmplusHashtable.cpp. References atoms, MMgc::GC::Calloc(), MMgc::GC::Free(), MMgc::GC::GetGC(), getNumAtoms(), hasDeletedItems(), MMgc::GC::kContainsPointers, MMgc::GC::kZero, MMGC_MEM_TYPE, avmplus::MathUtils::nextPowerOfTwo(), rehash(), setAtoms(), setHasDeletedItems(), setNumAtoms(), and size. Referenced by avmplus::WeakValueHashtable::add(), avmplus::WeakKeyHashtable::add(), and add(). 00237 { 00238 // grow the table by 2N+1 00239 // new = 2*old+1 ; old == o.atoms.length/2 00240 // = 2*(o.atoms.length/2)+1 00241 // = o.atoms.length + 1 00242 // If we have deleted slots, we don't grow our HT because our rehash will clear 00243 // out spots for us. 00244 int capacity = hasDeletedItems() ? getNumAtoms() : MathUtils::nextPowerOfTwo(getNumAtoms()+1); 00245 GC* gc = GC::GetGC(atoms); 00246 MMGC_MEM_TYPE(this); 00247 Atom *newAtoms = (Atom *) gc->Calloc(capacity, sizeof(Atom), GC::kContainsPointers|GC::kZero); 00248 size = rehash(atoms, getNumAtoms(), newAtoms, capacity); 00249 gc->Free (atoms); 00250 setAtoms(newAtoms); 00251 setNumAtoms(capacity); 00252 setHasDeletedItems(false); 00253 return; 00254 }
|
|
|
Definition at line 87 of file avmplusHashtable.h. References flags, and kHasDeletedItems. Referenced by grow(). 00087 { return (flags & kHasDeletedItems) != 0; }
|
|
|
Definition at line 65 of file avmplusHashtable.h. References flags, and kDontEnumSupport. Referenced by dontEnumMask(), getAtomPropertyIsEnumerable(), and setAtomPropertyIsEnumerable(). 00065 { return flags & kDontEnumSupport; }
|
|
||||||||||||
|
Definition at line 60 of file avmplusHashtable.cpp. References MMgc::GC::Alloc(), AvmAssert, flags, getNumAtoms(), MMgc::GC::kContainsPointers, MMgc::GC::kZero, MMGC_MEM_TYPE, avmplus::MathUtils::nextPowerOfTwo(), setAtoms(), and setNumAtoms(). Referenced by Hashtable(), reset(), and avmplus::ScriptObject::ScriptObject(). 00061 { 00062 capacity = MathUtils::nextPowerOfTwo(capacity); 00063 setNumAtoms(capacity*2); 00064 AvmAssert(getNumAtoms()); 00065 MMGC_MEM_TYPE(this); 00066 setAtoms((Atom *) gc->Alloc (sizeof(Atom) * getNumAtoms(), GC::kContainsPointers|GC::kZero)); 00067 flags = 0; 00068 }
|
|
|
load factor is 0.9 so we're full if size >= M*0.9 where M = atoms.length/2 Definition at line 209 of file avmplusHashtable.cpp. References getNumAtoms(), and getSize(). Referenced by avmplus::WeakValueHashtable::add(), avmplus::WeakKeyHashtable::add(), add(), and put(). 00210 { 00211 // This seems to work very well and the Intel compiler converts both the multiplies 00212 // into shift+add operations. 00213 return (5*(getSize()+1)) >= 2*getNumAtoms(); // 0.80 00214 #if 0 00215 //return ((size<<3)+1) >= 3*getNumAtoms(); // 0.75 00216 //return ((40*size)+1) >= 19*getNumAtoms(); // 0.95 00217 //return ((40*size)+1) >= 18*getNumAtoms(); // 0.90 00218 //return ((40*size)+1) >= 17*getNumAtoms(); // 0.85 00219 //return ((40*size)+1) >= 15*getNumAtoms(); // 0.75 00220 //Edwins suggestion - if (size > max - max>>N)) grow (N = 5, 4, 3, 2) 00221 //#define SHIFTFACTOR 4 00222 //NOT CORRECT 00223 //return ( ( size << SHIFTFACTOR ) + size > (getNumAtoms() << (SHIFTFACTOR-1)) ); 00224 #endif 00225 }
|
|
|
Definition at line 256 of file avmplusHashtable.cpp. References atoms. 00257 { 00258 return atoms[(index-1)<<1]; 00259 }
|
|
|
Allow caller to enumerate all entries in the table. Definition at line 276 of file avmplusHashtable.cpp. References atoms, DELETED, dontEnumMask(), EMPTY, getNumAtoms(), and kDontEnumBit. 00277 { 00278 if (index != 0) { 00279 index = index<<1; 00280 } 00281 // Advance to first non-empty slot. 00282 int mask = dontEnumMask(); 00283 int numAtoms = getNumAtoms(); 00284 while (index < numAtoms) { 00285 if ((atoms[index]&7) != EMPTY && (atoms[index]&7) != DELETED && (atoms[index]&mask) != kDontEnumBit) { 00286 return (index>>1)+1; 00287 } 00288 index += 2; 00289 } 00290 return 0; 00291 }
|
|
||||||||||||
|
Definition at line 96 of file avmplusHashtable.cpp. References atoms, AvmAssert, dontEnumMask(), find(), MMgc::GC::GetGC(), getNumAtoms(), util::threadpool::i, isFull(), size, and WBATOM. 00097 { 00098 int i = find(name, atoms, getNumAtoms()); 00099 GC *gc = GC::GetGC(atoms); 00100 if ((atoms[i] & ~dontEnumMask()) != name) { 00101 AvmAssert(!isFull()); 00102 //atoms[i] = name; 00103 WBATOM(gc, atoms, &atoms[i], name); 00104 size++; 00105 } 00106 //atoms[i+1] = value; 00107 WBATOM( gc, atoms, &atoms[i+1], value); 00108 }
|
|
||||||||||||
|
convenience functions for storing pointers as values. This is safe for internal tables that always store the same kind of pointer. Definition at line 209 of file avmplusHashtable.h. Referenced by avmplus::WeakValueHashtable::add(), avmplus::WeakKeyHashtable::add(), add(), and avmplus::AvmCore::handleActionBlock().
|
|
||||||||||||||||||||
|
Definition at line 173 of file avmplusHashtable.cpp. References DELETED, EMPTY, find(), and util::threadpool::i. Referenced by grow(). 00174 { 00175 int newSize = 0; 00176 for (int i=0, n=oldlen; i < n; i += 2) 00177 { 00178 Atom oldAtom; 00179 if ((oldAtom=oldAtoms[i]) != EMPTY && oldAtom != DELETED) 00180 { 00181 // inlined & simplified version of put() 00182 int j = find(oldAtom, newAtoms, newlen); 00183 newAtoms[j] = oldAtom; 00184 newAtoms[j+1] = oldAtoms[i+1]; 00185 newSize++; 00186 } 00187 } 00188 00189 return newSize; 00190 }
|
|
|
Reimplemented in avmplus::WeakKeyHashtable, and avmplus::WeakValueHashtable. Definition at line 159 of file avmplusHashtable.cpp. References atoms, DELETED, dontEnumMask(), find(), getNumAtoms(), util::threadpool::i, setHasDeletedItems(), avmplus::AtomConstants::undefinedAtom, and runtests::val. Referenced by avmplus::ScriptObject::deleteAtomProperty(), avmplus::ScriptObject::delUintProperty(), avmplus::WeakValueHashtable::remove(), and avmplus::WeakKeyHashtable::remove(). 00160 { 00161 int i = find(name, atoms, getNumAtoms()); 00162 Atom val = undefinedAtom; 00163 if ((atoms[i]&~dontEnumMask()) == name) 00164 { 00165 val = atoms[i+1]; 00166 atoms[i] = DELETED; 00167 atoms[i+1] = DELETED; 00168 setHasDeletedItems(true); 00169 } 00170 return val; 00171 }
|
|
|
Definition at line 176 of file avmplusHashtable.h. References atoms, destroy(), MMgc::GC::GetGC(), and initialize(). 00177 { 00178 MMgc::GC *gc = MMgc::GC::GetGC(atoms); 00179 destroy(); 00180 initialize(gc); 00181 }
|
|
||||||||||||
|
Definition at line 313 of file avmplusHashtable.cpp. References atoms, find(), getNumAtoms(), hasDontEnumSupport(), util::threadpool::i, and kDontEnumBit. Referenced by avmplus::ScriptObject::setAtomPropertyIsEnumerable(). 00314 { 00315 if (hasDontEnumSupport()) 00316 { 00317 int i = find(name, atoms, getNumAtoms()); 00318 if ((atoms[i]&~kDontEnumBit) == name) 00319 { 00320 atoms[i] = (atoms[i]&~kDontEnumBit) | (enumerable ? 0 : kDontEnumBit); 00321 } 00322 } 00323 }
|
|
|
Definition at line 90 of file avmplusHashtable.cpp. References atoms, MMgc::GC::FindBeginning(), MMgc::GC::GetGC(), and MMgc::GC::writeBarrier(). Referenced by grow(), and initialize(). 00091 { 00092 GC *gc = GC::GetGC(newAtoms); 00093 gc->writeBarrier(gc->FindBeginning(this), &atoms, newAtoms); 00094 }
|
|
|
Definition at line 66 of file avmplusHashtable.h. References flags, and kDontEnumSupport. Referenced by avmplus::ScriptObject::ScriptObject(). 00066 { flags = (short)((flags & ~kDontEnumSupport) | (flag ? kDontEnumSupport : 0)); }
|
|
|
Definition at line 258 of file avmplusHashtable.h. References flags, and kHasDeletedItems. Referenced by grow(), avmplus::DictionaryObject::nextNameIndex(), avmplus::WeakValueHashtable::prune(), avmplus::WeakKeyHashtable::prune(), and remove(). 00258 { flags = (short)((flags & ~kHasDeletedItems) | (val ? kHasDeletedItems : 0)); }
|
|
|
Definition at line 89 of file avmplusHashtable.h. References AvmAssert, FindOneBit(), getNumAtoms(), and logNumAtoms. Referenced by destroy(), grow(), and initialize(). 00090 { 00091 logNumAtoms = numAtoms ? (short)(FindOneBit(numAtoms)+1) : 0; 00092 AvmAssert(getNumAtoms() == numAtoms); 00093 }
|
|
|
Definition at line 261 of file avmplusHashtable.cpp. References atoms. 00262 { 00263 return atoms[((index-1)<<1)+1]; 00264 }
|
|
|
Definition at line 266 of file avmplusHashtable.h. Referenced by contains(), destroy(), find(), get(), getAtomPropertyIsEnumerable(), getAtoms(), avmplus::WeakValueHashtable::getValue(), grow(), keyAt(), next(), avmplus::WeakValueHashtable::prune(), avmplus::WeakKeyHashtable::prune(), put(), remove(), reset(), setAtomPropertyIsEnumerable(), setAtoms(), and valueAt(). |
|
|
DELETED is stored as the key for deleted items5 Definition at line 57 of file avmplusHashtable.h. Referenced by find(), next(), avmplus::DictionaryObject::nextNameIndex(), avmplus::WeakValueHashtable::prune(), avmplus::WeakKeyHashtable::prune(), rehash(), and remove(). |
|
|
since identifiers are always interned strings, they can't be 0, so we can use 0 as the empty value. Definition at line 54 of file avmplusHashtable.h. Referenced by find(), avmplus::ScriptObject::getAtomProperty(), avmplus::ScriptObject::getAtomPropertyFromProtoChain(), avmplus::ScriptObject::getUintProperty(), next(), and rehash(). |
|
|
Definition at line 270 of file avmplusHashtable.h. Referenced by destroy(), hasDeletedItems(), hasDontEnumSupport(), initialize(), setDontEnumSupport(), and setHasDeletedItems(). |
|
|
kDefaultCapacity must be a power of 2 Definition at line 60 of file avmplusHashtable.h. |
|
|
Definition at line 269 of file avmplusHashtable.h. Referenced by getNumAtoms(), and setNumAtoms(). |
|
|
Definition at line 268 of file avmplusHashtable.h. |
1.4.6