Extend StringMap to support being initialized as completely empty. When
authorChris Lattner <sabre@nondot.org>
Wed, 4 Apr 2007 00:29:37 +0000 (00:29 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 4 Apr 2007 00:29:37 +0000 (00:29 +0000)
initialized this way, they do not do a malloc to allocate their buckets.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35642 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/StringMap.h
lib/Support/StringMap.cpp

index c035f8cc6d7e4844b84f2cdb691de02ca9f9c5c9..3c5f76a3c1c1854f0c84ebdffc49f5fcfc0cd580 100644 (file)
@@ -55,6 +55,7 @@ protected:
   unsigned NumTombstones;
   unsigned ItemSize;
 protected:
+  StringMapImpl(unsigned itemSize) : ItemSize(itemSize) { init(16); }
   StringMapImpl(unsigned InitSize, unsigned ItemSize);
   void RehashTable();
   
@@ -87,7 +88,8 @@ protected:
   /// RemoveKey - Remove the StringMapEntry for the specified key from the
   /// table, returning it.  If the key is not in the table, this returns null.
   StringMapEntryBase *RemoveKey(const char *KeyStart, const char *KeyEnd);
-  
+private:
+  void init(unsigned Size);
 public:
   static StringMapEntryBase *getTombstoneVal() {
     return (StringMapEntryBase*)-1;
@@ -185,7 +187,8 @@ class StringMap : public StringMapImpl {
   AllocatorTy Allocator;
   typedef StringMapEntry<ValueTy> MapEntryTy;
 public:
-  StringMap(unsigned InitialSize = 0)
+  StringMap() : StringMapImpl(sizeof(MapEntryTy)) {}
+  StringMap(unsigned InitialSize)
     : StringMapImpl(InitialSize, sizeof(MapEntryTy)) {}
   
   AllocatorTy &getAllocator() { return Allocator; }
@@ -194,11 +197,18 @@ public:
   typedef StringMapConstIterator<ValueTy> const_iterator;
   typedef StringMapIterator<ValueTy> iterator;
   
-  iterator begin() { return iterator(TheTable); }
-  iterator end() { return iterator(TheTable+NumBuckets); }
-  const_iterator begin() const { return const_iterator(TheTable); }
-  const_iterator end() const { return const_iterator(TheTable+NumBuckets); }
-  
+  iterator begin() {
+    return iterator(TheTable, NumBuckets == 0);
+  }
+  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) {
     int Bucket = FindKey(KeyStart, KeyEnd);
@@ -279,8 +289,10 @@ class StringMapConstIterator {
 protected:
   StringMapImpl::ItemBucket *Ptr;
 public:
-  StringMapConstIterator(StringMapImpl::ItemBucket *Bucket) : Ptr(Bucket) {
-    AdvancePastEmptyBuckets();
+  StringMapConstIterator(StringMapImpl::ItemBucket *Bucket,
+                         bool NoAdvance = false)
+  : Ptr(Bucket) {
+    if (!NoAdvance) AdvancePastEmptyBuckets();
   }
   
   const StringMapEntry<ValueTy> &operator*() const {
@@ -316,8 +328,9 @@ private:
 template<typename ValueTy>
 class StringMapIterator : public StringMapConstIterator<ValueTy> {
 public:  
-  StringMapIterator(StringMapImpl::ItemBucket *Bucket)
-    : StringMapConstIterator<ValueTy>(Bucket) {
+  StringMapIterator(StringMapImpl::ItemBucket *Bucket,
+                    bool NoAdvance = false)
+    : StringMapConstIterator<ValueTy>(Bucket, NoAdvance) {
   }
   StringMapEntry<ValueTy> &operator*() const {
     return *static_cast<StringMapEntry<ValueTy>*>(this->Ptr->Item);
index a84cd9dbc64c9e57ed46f133a2d99d6c93841b72..caf9ba350efc55426d72242b5fc9a464c1d6b973 100644 (file)
 using namespace llvm;
 
 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 &&
          "Init Size must be a power of 2 or zero!");
   NumBuckets = InitSize ? InitSize : 16;
-  ItemSize = itemSize;
   NumItems = 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
 /// of the string.
 unsigned StringMapImpl::LookupBucketFor(const char *NameStart,
-                                         const char *NameEnd) {
+                                        const char *NameEnd) {
   unsigned HTSize = NumBuckets;
+  if (HTSize == 0) {  // Hash table unallocated so far?
+    init(16);
+    HTSize = NumBuckets;
+  }
   unsigned FullHashValue = HashString(NameStart, NameEnd);
   unsigned BucketNo = FullHashValue & (HTSize-1);
   
@@ -110,6 +129,7 @@ unsigned StringMapImpl::LookupBucketFor(const char *NameStart,
 /// This does not modify the map.
 int StringMapImpl::FindKey(const char *KeyStart, const char *KeyEnd) const {
   unsigned HTSize = NumBuckets;
+  if (HTSize == 0) return -1;  // Really empty table?
   unsigned FullHashValue = HashString(KeyStart, KeyEnd);
   unsigned BucketNo = FullHashValue & (HTSize-1);