From bb28a81ba3c112853f0eb3d8df0190accc0379c9 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 8 Feb 2007 19:20:57 +0000 Subject: [PATCH] Rename CStringMap -> StringMap, since it now supports nul characters in the strings. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34064 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/CStringMap.h | 182 ---------------------------------- include/llvm/ADT/StringMap.h | 34 +++---- lib/Support/CStringMap.cpp | 138 -------------------------- lib/Support/StringMap.cpp | 16 +-- 4 files changed, 25 insertions(+), 345 deletions(-) delete mode 100644 include/llvm/ADT/CStringMap.h delete mode 100644 lib/Support/CStringMap.cpp diff --git a/include/llvm/ADT/CStringMap.h b/include/llvm/ADT/CStringMap.h deleted file mode 100644 index feb65878ebc..00000000000 --- a/include/llvm/ADT/CStringMap.h +++ /dev/null @@ -1,182 +0,0 @@ -//===--- CStringMap.h - CString Hash table map interface --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by Chris Lattner and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the CStringMap class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_CSTRINGMAP_H -#define LLVM_ADT_CSTRINGMAP_H - -#include "llvm/Support/Allocator.h" -#include - -namespace llvm { - -/// StringMapEntryBase - Shared base class of StringMapEntry instances. -class StringMapEntryBase { - unsigned StrLen; -public: - StringMapEntryBase(unsigned Len) : StrLen(Len) {} - - unsigned getKeyLength() const { return StrLen; } -}; - -/// CStringMapVisitor - Subclasses of this class may be implemented to walk all -/// of the items in a CStringMap. -class CStringMapVisitor { -public: - virtual ~CStringMapVisitor(); - virtual void Visit(const char *Key, StringMapEntryBase *Value) const = 0; -}; - -/// CStringMapImpl - This is the base class of CStringMap that is shared among -/// all of its instantiations. -class CStringMapImpl { -protected: - /// ItemBucket - The hash table consists of an array of these. If Item is - /// non-null, this is an extant entry, otherwise, it is a hole. - struct ItemBucket { - /// FullHashValue - This remembers the full hash value of the key for - /// easy scanning. - unsigned FullHashValue; - - /// Item - This is a pointer to the actual item object. - StringMapEntryBase *Item; - }; - - ItemBucket *TheTable; - unsigned NumBuckets; - unsigned NumItems; - unsigned ItemSize; -protected: - CStringMapImpl(unsigned InitSize, unsigned ItemSize); - void RehashTable(); - - /// LookupBucketFor - Look up the bucket that the specified string should end - /// up in. If it already exists as a key in the map, the Item pointer for the - /// specified bucket will be non-null. Otherwise, it will be null. In either - /// case, the FullHashValue field of the bucket will be set to the hash value - /// of the string. - unsigned LookupBucketFor(const char *KeyStart, const char *KeyEnd); - -public: - unsigned getNumBuckets() const { return NumBuckets; } - unsigned getNumItems() const { return NumItems; } - - void VisitEntries(const CStringMapVisitor &Visitor) const; -}; - -/// StringMapEntry - This is used to represent one value that is inserted into -/// a StringMap. It contains the Value itself and the key: the string length -/// and data. -template -class StringMapEntry : public StringMapEntryBase { - ValueTy Val; -public: - StringMapEntry(unsigned StrLen) - : StringMapEntryBase(StrLen), Val() {} - StringMapEntry(unsigned StrLen, const ValueTy &V) - : StringMapEntryBase(StrLen), Val(V) {} - - const ValueTy &getValue() const { return Val; } - ValueTy &getValue() { return Val; } - - void setValue(const ValueTy &V) { Val = V; } - - /// getKeyData - Return the start of the string data that is the key for this - /// value. The string data is always stored immediately after the - /// StringMapEntry object. - const char *getKeyData() const {return reinterpret_cast(this+1);} -}; - - -/// CStringMap - This is an unconventional map that is specialized for handling -/// keys that are "strings", which are basically ranges of bytes. This does some -/// funky memory allocation and hashing things to make it extremely efficient, -/// storing the string data *after* the value in the map. -template -class CStringMap : public CStringMapImpl { - AllocatorTy Allocator; - typedef StringMapEntry MapEntryTy; -public: - CStringMap(unsigned InitialSize = 0) - : CStringMapImpl(InitialSize, sizeof(MapEntryTy)) {} - - AllocatorTy &getAllocator() { return Allocator; } - const AllocatorTy &getAllocator() const { return Allocator; } - - /// FindValue - Look up the specified key in the map. If it exists, return a - /// pointer to the element, otherwise return null. - MapEntryTy *FindValue(const char *KeyStart, const char *KeyEnd) { - unsigned BucketNo = LookupBucketFor(KeyStart, KeyEnd); - return static_cast(TheTable[BucketNo].Item); - } - - /// GetOrCreateValue - Look up the specified key in the table. If a value - /// exists, return it. Otherwise, default construct a value, insert it, and - /// return. - StringMapEntry &GetOrCreateValue(const char *KeyStart, - const char *KeyEnd) { - unsigned BucketNo = LookupBucketFor(KeyStart, KeyEnd); - ItemBucket &Bucket = TheTable[BucketNo]; - if (Bucket.Item) - return *static_cast(Bucket.Item); - - unsigned KeyLength = KeyEnd-KeyStart; - - // Okay, the item doesn't already exist, and 'Bucket' is the bucket to fill - // in. Allocate a new item with space for the string at the end and a null - // terminator. - unsigned AllocSize = sizeof(MapEntryTy)+KeyLength+1; - -#ifdef __GNUC__ - unsigned Alignment = __alignof__(MapEntryTy); -#else - // FIXME: ugly. - unsigned Alignment = 8; -#endif - MapEntryTy *NewItem = - static_cast(Allocator.Allocate(AllocSize, Alignment)); - - // Default construct the value. - new (NewItem) MapEntryTy(KeyLength); - ++NumItems; - - // Copy the string information. - char *StrBuffer = const_cast(NewItem->getKeyData()); - memcpy(StrBuffer, KeyStart, KeyLength); - StrBuffer[KeyLength] = 0; // Null terminate for convenience of clients. - - // Fill in the bucket for the hash table. The FullHashValue was already - // filled in by LookupBucketFor. - Bucket.Item = NewItem; - - // If the hash table is now more than 3/4 full, rehash into a larger table. - if (NumItems > NumBuckets*3/4) - RehashTable(); - return *NewItem; - } - - ~CStringMap() { - for (ItemBucket *I = TheTable, *E = TheTable+NumBuckets; I != E; ++I) { - if (MapEntryTy *Id = static_cast(I->Item)) { - // Free memory referenced by the item. - Id->~MapEntryTy(); - Allocator.Deallocate(Id); - } - } - delete [] TheTable; - } -}; - -} - -#endif - diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h index feb65878ebc..375472cc1f7 100644 --- a/include/llvm/ADT/StringMap.h +++ b/include/llvm/ADT/StringMap.h @@ -1,4 +1,4 @@ -//===--- CStringMap.h - CString Hash table map interface --------*- C++ -*-===// +//===--- StringMap.h - String Hash table map interface ----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,12 +7,12 @@ // //===----------------------------------------------------------------------===// // -// This file defines the CStringMap class. +// This file defines the StringMap class. // //===----------------------------------------------------------------------===// -#ifndef LLVM_ADT_CSTRINGMAP_H -#define LLVM_ADT_CSTRINGMAP_H +#ifndef LLVM_ADT_STRINGMAP_H +#define LLVM_ADT_STRINGMAP_H #include "llvm/Support/Allocator.h" #include @@ -28,17 +28,17 @@ public: unsigned getKeyLength() const { return StrLen; } }; -/// CStringMapVisitor - Subclasses of this class may be implemented to walk all -/// of the items in a CStringMap. -class CStringMapVisitor { +/// StringMapVisitor - Subclasses of this class may be implemented to walk all +/// of the items in a StringMap. +class StringMapVisitor { public: - virtual ~CStringMapVisitor(); + virtual ~StringMapVisitor(); virtual void Visit(const char *Key, StringMapEntryBase *Value) const = 0; }; -/// CStringMapImpl - This is the base class of CStringMap that is shared among +/// StringMapImpl - This is the base class of StringMap that is shared among /// all of its instantiations. -class CStringMapImpl { +class StringMapImpl { protected: /// ItemBucket - The hash table consists of an array of these. If Item is /// non-null, this is an extant entry, otherwise, it is a hole. @@ -56,7 +56,7 @@ protected: unsigned NumItems; unsigned ItemSize; protected: - CStringMapImpl(unsigned InitSize, unsigned ItemSize); + StringMapImpl(unsigned InitSize, unsigned ItemSize); void RehashTable(); /// LookupBucketFor - Look up the bucket that the specified string should end @@ -70,7 +70,7 @@ public: unsigned getNumBuckets() const { return NumBuckets; } unsigned getNumItems() const { return NumItems; } - void VisitEntries(const CStringMapVisitor &Visitor) const; + void VisitEntries(const StringMapVisitor &Visitor) const; }; /// StringMapEntry - This is used to represent one value that is inserted into @@ -97,17 +97,17 @@ public: }; -/// CStringMap - This is an unconventional map that is specialized for handling +/// StringMap - This is an unconventional map that is specialized for handling /// keys that are "strings", which are basically ranges of bytes. This does some /// funky memory allocation and hashing things to make it extremely efficient, /// storing the string data *after* the value in the map. template -class CStringMap : public CStringMapImpl { +class StringMap : public StringMapImpl { AllocatorTy Allocator; typedef StringMapEntry MapEntryTy; public: - CStringMap(unsigned InitialSize = 0) - : CStringMapImpl(InitialSize, sizeof(MapEntryTy)) {} + StringMap(unsigned InitialSize = 0) + : StringMapImpl(InitialSize, sizeof(MapEntryTy)) {} AllocatorTy &getAllocator() { return Allocator; } const AllocatorTy &getAllocator() const { return Allocator; } @@ -164,7 +164,7 @@ public: return *NewItem; } - ~CStringMap() { + ~StringMap() { for (ItemBucket *I = TheTable, *E = TheTable+NumBuckets; I != E; ++I) { if (MapEntryTy *Id = static_cast(I->Item)) { // Free memory referenced by the item. diff --git a/lib/Support/CStringMap.cpp b/lib/Support/CStringMap.cpp deleted file mode 100644 index b145e2ef81a..00000000000 --- a/lib/Support/CStringMap.cpp +++ /dev/null @@ -1,138 +0,0 @@ -//===--- CStringMap.cpp - CString Hash table map implementation -----------===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by Chris Lattner and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the CStringMap class. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ADT/CStringMap.h" -#include -using namespace llvm; - -CStringMapVisitor::~CStringMapVisitor() { -} - -CStringMapImpl::CStringMapImpl(unsigned InitSize, unsigned itemSize) { - assert((InitSize & (InitSize-1)) == 0 && - "Init Size must be a power of 2 or zero!"); - NumBuckets = InitSize ? InitSize : 512; - ItemSize = itemSize; - NumItems = 0; - - TheTable = new ItemBucket[NumBuckets](); - memset(TheTable, 0, NumBuckets*sizeof(ItemBucket)); -} - - -/// HashString - Compute a hash code for the specified string. -/// -static unsigned HashString(const char *Start, const char *End) { - // Bernstein hash function. - unsigned int Result = 0; - // TODO: investigate whether a modified bernstein hash function performs - // better: http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx - // X*33+c -> X*33^c - while (Start != End) - Result = Result * 33 + *Start++; - Result = Result + (Result >> 5); - return Result; -} - -/// LookupBucketFor - Look up the bucket that the specified string should end -/// up in. If it already exists as a key in the map, the Item pointer for the -/// specified bucket will be non-null. Otherwise, it will be null. In either -/// case, the FullHashValue field of the bucket will be set to the hash value -/// of the string. -unsigned CStringMapImpl::LookupBucketFor(const char *NameStart, - const char *NameEnd) { - unsigned HTSize = NumBuckets; - unsigned FullHashValue = HashString(NameStart, NameEnd); - unsigned BucketNo = FullHashValue & (HTSize-1); - - unsigned ProbeAmt = 1; - while (1) { - ItemBucket &Bucket = TheTable[BucketNo]; - StringMapEntryBase *BucketItem = Bucket.Item; - // If we found an empty bucket, this key isn't in the table yet, return it. - if (BucketItem == 0) { - Bucket.FullHashValue = FullHashValue; - return BucketNo; - } - - // If the full hash value matches, check deeply for a match. The common - // case here is that we are only looking at the buckets (for item info - // being non-null and for the full hash value) not at the items. This - // is important for cache locality. - if (Bucket.FullHashValue == FullHashValue) { - // Do the comparison like this because NameStart isn't necessarily - // null-terminated! - char *ItemStr = (char*)BucketItem+ItemSize; - unsigned ItemStrLen = BucketItem->getKeyLength(); - if (unsigned(NameEnd-NameStart) == ItemStrLen && - memcmp(ItemStr, NameStart, ItemStrLen) == 0) { - // We found a match! - return BucketNo; - } - } - - // Okay, we didn't find the item. Probe to the next bucket. - BucketNo = (BucketNo+ProbeAmt) & (HTSize-1); - - // Use quadratic probing, it has fewer clumping artifacts than linear - // probing and has good cache behavior in the common case. - ++ProbeAmt; - } -} - -/// RehashTable - Grow the table, redistributing values into the buckets with -/// the appropriate mod-of-hashtable-size. -void CStringMapImpl::RehashTable() { - unsigned NewSize = NumBuckets*2; - ItemBucket *NewTableArray = new ItemBucket[NewSize](); - memset(NewTableArray, 0, NewSize*sizeof(ItemBucket)); - - // Rehash all the items into their new buckets. Luckily :) we already have - // the hash values available, so we don't have to rehash any strings. - for (ItemBucket *IB = TheTable, *E = TheTable+NumBuckets; IB != E; ++IB) { - if (IB->Item) { - // Fast case, bucket available. - unsigned FullHash = IB->FullHashValue; - unsigned NewBucket = FullHash & (NewSize-1); - if (NewTableArray[NewBucket].Item == 0) { - NewTableArray[FullHash & (NewSize-1)].Item = IB->Item; - NewTableArray[FullHash & (NewSize-1)].FullHashValue = FullHash; - continue; - } - - unsigned ProbeSize = 1; - do { - NewBucket = (NewBucket + ProbeSize++) & (NewSize-1); - } while (NewTableArray[NewBucket].Item); - - // Finally found a slot. Fill it in. - NewTableArray[NewBucket].Item = IB->Item; - NewTableArray[NewBucket].FullHashValue = FullHash; - } - } - - delete[] TheTable; - - TheTable = NewTableArray; - NumBuckets = NewSize; -} - - -/// VisitEntries - This method walks through all of the items, -/// invoking Visitor.Visit for each of them. -void CStringMapImpl::VisitEntries(const CStringMapVisitor &Visitor) const { - for (ItemBucket *IB = TheTable, *E = TheTable+NumBuckets; IB != E; ++IB) { - if (StringMapEntryBase *Id = IB->Item) - Visitor.Visit((char*)Id + ItemSize, Id); - } -} diff --git a/lib/Support/StringMap.cpp b/lib/Support/StringMap.cpp index b145e2ef81a..6eefd44c52f 100644 --- a/lib/Support/StringMap.cpp +++ b/lib/Support/StringMap.cpp @@ -1,4 +1,4 @@ -//===--- CStringMap.cpp - CString Hash table map implementation -----------===// +//===--- StringMap.cpp - String Hash table map implementation -------------===// // // The LLVM Compiler Infrastructure // @@ -7,18 +7,18 @@ // //===----------------------------------------------------------------------===// // -// This file implements the CStringMap class. +// This file implements the StringMap class. // //===----------------------------------------------------------------------===// -#include "llvm/ADT/CStringMap.h" +#include "llvm/ADT/StringMap.h" #include using namespace llvm; -CStringMapVisitor::~CStringMapVisitor() { +StringMapVisitor::~StringMapVisitor() { } -CStringMapImpl::CStringMapImpl(unsigned InitSize, unsigned itemSize) { +StringMapImpl::StringMapImpl(unsigned InitSize, unsigned itemSize) { assert((InitSize & (InitSize-1)) == 0 && "Init Size must be a power of 2 or zero!"); NumBuckets = InitSize ? InitSize : 512; @@ -49,7 +49,7 @@ static unsigned HashString(const char *Start, const char *End) { /// specified bucket will be non-null. Otherwise, it will be null. In either /// case, the FullHashValue field of the bucket will be set to the hash value /// of the string. -unsigned CStringMapImpl::LookupBucketFor(const char *NameStart, +unsigned StringMapImpl::LookupBucketFor(const char *NameStart, const char *NameEnd) { unsigned HTSize = NumBuckets; unsigned FullHashValue = HashString(NameStart, NameEnd); @@ -92,7 +92,7 @@ unsigned CStringMapImpl::LookupBucketFor(const char *NameStart, /// RehashTable - Grow the table, redistributing values into the buckets with /// the appropriate mod-of-hashtable-size. -void CStringMapImpl::RehashTable() { +void StringMapImpl::RehashTable() { unsigned NewSize = NumBuckets*2; ItemBucket *NewTableArray = new ItemBucket[NewSize](); memset(NewTableArray, 0, NewSize*sizeof(ItemBucket)); @@ -130,7 +130,7 @@ void CStringMapImpl::RehashTable() { /// VisitEntries - This method walks through all of the items, /// invoking Visitor.Visit for each of them. -void CStringMapImpl::VisitEntries(const CStringMapVisitor &Visitor) const { +void StringMapImpl::VisitEntries(const StringMapVisitor &Visitor) const { for (ItemBucket *IB = TheTable, *E = TheTable+NumBuckets; IB != E; ++IB) { if (StringMapEntryBase *Id = IB->Item) Visitor.Visit((char*)Id + ItemSize, Id);