void QStringHashData::rehashToBits(short bits) { numBits = qMax(MinNumBits, (int)bits); int nb = primeForNumBits(numBits); if (nb == numBuckets && buckets) return; #ifdef QSTRINGHASH_LINK_DEBUG if (linkCount) qFatal("QStringHash: Illegal attempt to rehash a linked hash."); #endif QStringHashNode **newBuckets = new QStringHashNode *[nb]; ::memset(newBuckets, 0, sizeof(QStringHashNode *) * nb); // Preserve the existing order within buckets so that items with the // same key will retain the same find/findNext order for (int i = 0; i < numBuckets; ++i) { QStringHashNode *bucket = buckets[i]; if (bucket) rehashNode(newBuckets, nb, bucket); } delete [] buckets; buckets = newBuckets; numBuckets = nb; }
void QStringHashData::rehashToSize(int size) { short bits = qMax(MinNumBits, (int)numBits); while (primeForNumBits(bits) < size) bits++; if (bits > numBits) rehashToBits(bits); }
IdentifierTable::IdentifierTable(ExecutionEngine *engine) : engine(engine) , size(0) , numBits(8) { alloc = primeForNumBits(numBits); entries = (Heap::String **)malloc(alloc*sizeof(Heap::String *)); memset(entries, 0, alloc*sizeof(Heap::String *)); }
void IdentifierTable::addEntry(Heap::String *str) { uint hash = str->hashValue(); if (str->subtype == Heap::String::StringType_ArrayIndex) return; str->identifier = new Identifier; str->identifier->string = str->toQString(); str->identifier->hashValue = hash; bool grow = (alloc <= size*2); if (grow) { ++numBits; int newAlloc = primeForNumBits(numBits); Heap::String **newEntries = (Heap::String **)malloc(newAlloc*sizeof(Heap::String *)); memset(newEntries, 0, newAlloc*sizeof(Heap::String *)); for (int i = 0; i < alloc; ++i) { Heap::String *e = entries[i]; if (!e) continue; uint idx = e->stringHash % newAlloc; while (newEntries[idx]) { ++idx; idx %= newAlloc; } newEntries[idx] = e; } free(entries); entries = newEntries; alloc = newAlloc; } uint idx = hash % alloc; while (entries[idx]) { ++idx; idx %= alloc; } entries[idx] = str; ++size; }