1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00

Extend StringMap to support being initialized as completely empty. When

initialized this way, they do not do a malloc to allocate their buckets.

llvm-svn: 35642
This commit is contained in:
Chris Lattner 2007-04-04 00:29:37 +00:00
parent 5bd266a791
commit dbf6a79a71
2 changed files with 46 additions and 13 deletions

View File

@ -55,6 +55,7 @@ protected:
unsigned NumTombstones; unsigned NumTombstones;
unsigned ItemSize; unsigned ItemSize;
protected: protected:
StringMapImpl(unsigned itemSize) : ItemSize(itemSize) { init(16); }
StringMapImpl(unsigned InitSize, unsigned ItemSize); StringMapImpl(unsigned InitSize, unsigned ItemSize);
void RehashTable(); void RehashTable();
@ -87,7 +88,8 @@ protected:
/// RemoveKey - Remove the StringMapEntry for the specified key from the /// RemoveKey - Remove the StringMapEntry for the specified key from the
/// table, returning it. If the key is not in the table, this returns null. /// table, returning it. If the key is not in the table, this returns null.
StringMapEntryBase *RemoveKey(const char *KeyStart, const char *KeyEnd); StringMapEntryBase *RemoveKey(const char *KeyStart, const char *KeyEnd);
private:
void init(unsigned Size);
public: public:
static StringMapEntryBase *getTombstoneVal() { static StringMapEntryBase *getTombstoneVal() {
return (StringMapEntryBase*)-1; return (StringMapEntryBase*)-1;
@ -185,7 +187,8 @@ class StringMap : public StringMapImpl {
AllocatorTy Allocator; AllocatorTy Allocator;
typedef StringMapEntry<ValueTy> MapEntryTy; typedef StringMapEntry<ValueTy> MapEntryTy;
public: public:
StringMap(unsigned InitialSize = 0) StringMap() : StringMapImpl(sizeof(MapEntryTy)) {}
StringMap(unsigned InitialSize)
: StringMapImpl(InitialSize, sizeof(MapEntryTy)) {} : StringMapImpl(InitialSize, sizeof(MapEntryTy)) {}
AllocatorTy &getAllocator() { return Allocator; } AllocatorTy &getAllocator() { return Allocator; }
@ -194,11 +197,18 @@ public:
typedef StringMapConstIterator<ValueTy> const_iterator; typedef StringMapConstIterator<ValueTy> const_iterator;
typedef StringMapIterator<ValueTy> iterator; typedef StringMapIterator<ValueTy> iterator;
iterator begin() { return iterator(TheTable); } iterator begin() {
iterator end() { return iterator(TheTable+NumBuckets); } return iterator(TheTable, NumBuckets == 0);
const_iterator begin() const { return const_iterator(TheTable); } }
const_iterator end() const { return const_iterator(TheTable+NumBuckets); } iterator end() {
return iterator(TheTable+NumBuckets, true);
}
const_iterator begin() const {
return const_iterator(TheTable, NumBuckets == 0);
}
const_iterator end() const {
return const_iterator(TheTable+NumBuckets, true);
}
iterator find(const char *KeyStart, const char *KeyEnd) { iterator find(const char *KeyStart, const char *KeyEnd) {
int Bucket = FindKey(KeyStart, KeyEnd); int Bucket = FindKey(KeyStart, KeyEnd);
@ -279,8 +289,10 @@ class StringMapConstIterator {
protected: protected:
StringMapImpl::ItemBucket *Ptr; StringMapImpl::ItemBucket *Ptr;
public: public:
StringMapConstIterator(StringMapImpl::ItemBucket *Bucket) : Ptr(Bucket) { StringMapConstIterator(StringMapImpl::ItemBucket *Bucket,
AdvancePastEmptyBuckets(); bool NoAdvance = false)
: Ptr(Bucket) {
if (!NoAdvance) AdvancePastEmptyBuckets();
} }
const StringMapEntry<ValueTy> &operator*() const { const StringMapEntry<ValueTy> &operator*() const {
@ -316,8 +328,9 @@ private:
template<typename ValueTy> template<typename ValueTy>
class StringMapIterator : public StringMapConstIterator<ValueTy> { class StringMapIterator : public StringMapConstIterator<ValueTy> {
public: public:
StringMapIterator(StringMapImpl::ItemBucket *Bucket) StringMapIterator(StringMapImpl::ItemBucket *Bucket,
: StringMapConstIterator<ValueTy>(Bucket) { bool NoAdvance = false)
: StringMapConstIterator<ValueTy>(Bucket, NoAdvance) {
} }
StringMapEntry<ValueTy> &operator*() const { StringMapEntry<ValueTy> &operator*() const {
return *static_cast<StringMapEntry<ValueTy>*>(this->Ptr->Item); return *static_cast<StringMapEntry<ValueTy>*>(this->Ptr->Item);

View File

@ -16,10 +16,25 @@
using namespace llvm; using namespace llvm;
StringMapImpl::StringMapImpl(unsigned InitSize, unsigned itemSize) { StringMapImpl::StringMapImpl(unsigned InitSize, unsigned itemSize) {
ItemSize = itemSize;
// If a size is specified, initialize the table with that many buckets.
if (InitSize) {
init(InitSize);
return;
}
// Otherwise, initialize it with zero buckets to avoid the allocation.
TheTable = 0;
NumBuckets = 0;
NumItems = 0;
NumTombstones = 0;
}
void StringMapImpl::init(unsigned InitSize) {
assert((InitSize & (InitSize-1)) == 0 && assert((InitSize & (InitSize-1)) == 0 &&
"Init Size must be a power of 2 or zero!"); "Init Size must be a power of 2 or zero!");
NumBuckets = InitSize ? InitSize : 16; NumBuckets = InitSize ? InitSize : 16;
ItemSize = itemSize;
NumItems = 0; NumItems = 0;
NumTombstones = 0; NumTombstones = 0;
@ -52,8 +67,12 @@ static unsigned HashString(const char *Start, const char *End) {
/// case, the FullHashValue field of the bucket will be set to the hash value /// case, the FullHashValue field of the bucket will be set to the hash value
/// of the string. /// of the string.
unsigned StringMapImpl::LookupBucketFor(const char *NameStart, unsigned StringMapImpl::LookupBucketFor(const char *NameStart,
const char *NameEnd) { const char *NameEnd) {
unsigned HTSize = NumBuckets; unsigned HTSize = NumBuckets;
if (HTSize == 0) { // Hash table unallocated so far?
init(16);
HTSize = NumBuckets;
}
unsigned FullHashValue = HashString(NameStart, NameEnd); unsigned FullHashValue = HashString(NameStart, NameEnd);
unsigned BucketNo = FullHashValue & (HTSize-1); unsigned BucketNo = FullHashValue & (HTSize-1);
@ -110,6 +129,7 @@ unsigned StringMapImpl::LookupBucketFor(const char *NameStart,
/// This does not modify the map. /// This does not modify the map.
int StringMapImpl::FindKey(const char *KeyStart, const char *KeyEnd) const { int StringMapImpl::FindKey(const char *KeyStart, const char *KeyEnd) const {
unsigned HTSize = NumBuckets; unsigned HTSize = NumBuckets;
if (HTSize == 0) return -1; // Really empty table?
unsigned FullHashValue = HashString(KeyStart, KeyEnd); unsigned FullHashValue = HashString(KeyStart, KeyEnd);
unsigned BucketNo = FullHashValue & (HTSize-1); unsigned BucketNo = FullHashValue & (HTSize-1);