Replace the ugly FindValue method with STL-like find methods.
authorChris Lattner <sabre@nondot.org>
Sun, 11 Feb 2007 19:49:41 +0000 (19:49 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 11 Feb 2007 19:49:41 +0000 (19:49 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34183 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 52982589f792b142b8b82afb93c62e475e183902..7cc9ce7b6ce48ee9707c3052e5e5645f63b8ad30 100644 (file)
@@ -64,6 +64,11 @@ protected:
   /// of the string.
   unsigned LookupBucketFor(const char *KeyStart, const char *KeyEnd);
   
+  /// FindKey - Look up the bucket that contains the specified key. If it exists
+  /// in the map, return the bucket number of the key.  Otherwise return -1.
+  /// This does not modify the map.
+  int FindKey(const char *KeyStart, const char *KeyEnd) const;
+  
 public:
   static StringMapEntryBase *getTombstoneVal() {
     return (StringMapEntryBase*)-1;
@@ -175,11 +180,17 @@ public:
   const_iterator begin() const { return const_iterator(TheTable); }
   const_iterator end() const { return const_iterator(TheTable+NumBuckets); }
   
-  /// 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<MapEntryTy*>(TheTable[BucketNo].Item);
+  
+  iterator find(const char *KeyStart, const char *KeyEnd) {
+    int Bucket = FindKey(KeyStart, KeyEnd);
+    if (Bucket == -1) return end();
+    return iterator(TheTable+Bucket);
+  }
+
+  const_iterator find(const char *KeyStart, const char *KeyEnd) const {
+    int Bucket = FindKey(KeyStart, KeyEnd);
+    if (Bucket == -1) return end();
+    return const_iterator(TheTable+Bucket);
   }
   
   /// GetOrCreateValue - Look up the specified key in the table.  If a value
index 5a3896424e72474ce4776757e303e9d3550915d8..02d42b9b49bb3b7d24aafbbd0ec0aa24e80d7a4c 100644 (file)
@@ -91,6 +91,49 @@ unsigned StringMapImpl::LookupBucketFor(const char *NameStart,
   }
 }
 
+
+/// FindKey - Look up the bucket that contains the specified key. If it exists
+/// in the map, return the bucket number of the key.  Otherwise return -1.
+/// This does not modify the map.
+int StringMapImpl::FindKey(const char *KeyStart, const char *KeyEnd) const {
+  unsigned HTSize = NumBuckets;
+  unsigned FullHashValue = HashString(KeyStart, KeyEnd);
+  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.
+    if (BucketItem == 0)
+      return -1;
+    
+    // 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(KeyEnd-KeyStart) == ItemStrLen &&
+          memcmp(ItemStr, KeyStart, 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 StringMapImpl::RehashTable() {