blob: 4341da2d97bdb911ba32badafca4cd3463105c2e [file] [log] [blame]
Chris Lattner751a4202007-02-08 19:20:57 +00001//===--- StringMap.cpp - String Hash table map implementation -------------===//
Chris Lattner149e6662006-10-29 23:42:03 +00002//
3// The LLVM Compiler Infrastructure
4//
Chris Lattnerf3ebc3f2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattner149e6662006-10-29 23:42:03 +00007//
8//===----------------------------------------------------------------------===//
9//
Chris Lattner751a4202007-02-08 19:20:57 +000010// This file implements the StringMap class.
Chris Lattner149e6662006-10-29 23:42:03 +000011//
12//===----------------------------------------------------------------------===//
13
Chris Lattner751a4202007-02-08 19:20:57 +000014#include "llvm/ADT/StringMap.h"
Daniel Dunbar77668002009-10-17 18:21:06 +000015#include "llvm/ADT/StringExtras.h"
Benjamin Kramerffa24e02012-08-29 22:57:04 +000016#include "llvm/Support/Compiler.h"
Eugene Zelenko33d7b762016-08-23 17:14:32 +000017#include "llvm/Support/MathExtras.h"
Chris Lattner149e6662006-10-29 23:42:03 +000018#include <cassert>
Eugene Zelenko33d7b762016-08-23 17:14:32 +000019
Chris Lattner149e6662006-10-29 23:42:03 +000020using namespace llvm;
21
Mehdi Aminibe8a57f2016-03-25 05:57:57 +000022/// Returns the number of buckets to allocate to ensure that the DenseMap can
23/// accommodate \p NumEntries without need to grow().
24static unsigned getMinBucketToReserveForEntries(unsigned NumEntries) {
25 // Ensure that "NumEntries * 4 < NumBuckets * 3"
26 if (NumEntries == 0)
27 return 0;
28 // +1 is required because of the strict equality.
29 // For example if NumEntries is 48, we need to return 401.
30 return NextPowerOf2(NumEntries * 4 / 3 + 1);
31}
32
Chris Lattner751a4202007-02-08 19:20:57 +000033StringMapImpl::StringMapImpl(unsigned InitSize, unsigned itemSize) {
Chris Lattner23763462007-04-04 00:29:37 +000034 ItemSize = itemSize;
35
36 // If a size is specified, initialize the table with that many buckets.
37 if (InitSize) {
Mehdi Aminibe8a57f2016-03-25 05:57:57 +000038 // The table will grow when the number of entries reach 3/4 of the number of
39 // buckets. To guarantee that "InitSize" number of entries can be inserted
40 // in the table without growing, we allocate just what is needed here.
41 init(getMinBucketToReserveForEntries(InitSize));
Chris Lattner23763462007-04-04 00:29:37 +000042 return;
43 }
44
45 // Otherwise, initialize it with zero buckets to avoid the allocation.
Craig Topperc10719f2014-04-07 04:17:22 +000046 TheTable = nullptr;
Chris Lattner23763462007-04-04 00:29:37 +000047 NumBuckets = 0;
48 NumItems = 0;
49 NumTombstones = 0;
50}
51
52void StringMapImpl::init(unsigned InitSize) {
Chris Lattner149e6662006-10-29 23:42:03 +000053 assert((InitSize & (InitSize-1)) == 0 &&
54 "Init Size must be a power of 2 or zero!");
Matthias Braunc20b3382017-07-20 01:30:39 +000055
56 unsigned NewNumBuckets = InitSize ? InitSize : 16;
Chris Lattner149e6662006-10-29 23:42:03 +000057 NumItems = 0;
Chris Lattner77baa562007-02-11 20:58:00 +000058 NumTombstones = 0;
Chris Lattner149e6662006-10-29 23:42:03 +000059
Matthias Braunc20b3382017-07-20 01:30:39 +000060 TheTable = (StringMapEntryBase **)calloc(NewNumBuckets+1,
Benjamin Kramer46236ee2011-12-27 20:35:07 +000061 sizeof(StringMapEntryBase **) +
62 sizeof(unsigned));
63
Matthias Braunc20b3382017-07-20 01:30:39 +000064 if (TheTable == nullptr)
65 report_bad_alloc_error("Allocation of StringMap table failed.");
66
67 // Set the member only if TheTable was successfully allocated
68 NumBuckets = NewNumBuckets;
69
Chris Lattnere15605c2007-02-11 08:20:35 +000070 // Allocate one extra bucket, set it to look filled so the iterators stop at
71 // end.
Benjamin Kramer46236ee2011-12-27 20:35:07 +000072 TheTable[NumBuckets] = (StringMapEntryBase*)2;
Chris Lattner149e6662006-10-29 23:42:03 +000073}
74
Chris Lattner149e6662006-10-29 23:42:03 +000075/// LookupBucketFor - Look up the bucket that the specified string should end
76/// up in. If it already exists as a key in the map, the Item pointer for the
77/// specified bucket will be non-null. Otherwise, it will be null. In either
78/// case, the FullHashValue field of the bucket will be set to the hash value
79/// of the string.
Daniel Dunbarad36e8a2009-11-06 10:58:06 +000080unsigned StringMapImpl::LookupBucketFor(StringRef Name) {
Chris Lattner149e6662006-10-29 23:42:03 +000081 unsigned HTSize = NumBuckets;
Chris Lattner23763462007-04-04 00:29:37 +000082 if (HTSize == 0) { // Hash table unallocated so far?
83 init(16);
84 HTSize = NumBuckets;
85 }
Daniel Dunbar77668002009-10-17 18:21:06 +000086 unsigned FullHashValue = HashString(Name);
Chris Lattner149e6662006-10-29 23:42:03 +000087 unsigned BucketNo = FullHashValue & (HTSize-1);
Benjamin Kramer46236ee2011-12-27 20:35:07 +000088 unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1);
89
Chris Lattner149e6662006-10-29 23:42:03 +000090 unsigned ProbeAmt = 1;
Chris Lattner77baa562007-02-11 20:58:00 +000091 int FirstTombstone = -1;
Eugene Zelenko33d7b762016-08-23 17:14:32 +000092 while (true) {
Benjamin Kramer46236ee2011-12-27 20:35:07 +000093 StringMapEntryBase *BucketItem = TheTable[BucketNo];
Chris Lattner149e6662006-10-29 23:42:03 +000094 // If we found an empty bucket, this key isn't in the table yet, return it.
Craig Topper8d399f82014-04-09 04:20:00 +000095 if (LLVM_LIKELY(!BucketItem)) {
Chris Lattner77baa562007-02-11 20:58:00 +000096 // If we found a tombstone, we want to reuse the tombstone instead of an
97 // empty bucket. This reduces probing.
98 if (FirstTombstone != -1) {
Benjamin Kramer46236ee2011-12-27 20:35:07 +000099 HashTable[FirstTombstone] = FullHashValue;
Chris Lattner77baa562007-02-11 20:58:00 +0000100 return FirstTombstone;
101 }
102
Benjamin Kramer46236ee2011-12-27 20:35:07 +0000103 HashTable[BucketNo] = FullHashValue;
Chris Lattner149e6662006-10-29 23:42:03 +0000104 return BucketNo;
105 }
106
Chris Lattner77baa562007-02-11 20:58:00 +0000107 if (BucketItem == getTombstoneVal()) {
108 // Skip over tombstones. However, remember the first one we see.
109 if (FirstTombstone == -1) FirstTombstone = BucketNo;
Benjamin Kramerffa24e02012-08-29 22:57:04 +0000110 } else if (LLVM_LIKELY(HashTable[BucketNo] == FullHashValue)) {
Chris Lattner77baa562007-02-11 20:58:00 +0000111 // If the full hash value matches, check deeply for a match. The common
112 // case here is that we are only looking at the buckets (for item info
113 // being non-null and for the full hash value) not at the items. This
114 // is important for cache locality.
115
Daniel Dunbar5bf72e22009-07-23 18:17:34 +0000116 // Do the comparison like this because Name isn't necessarily
Chris Lattner149e6662006-10-29 23:42:03 +0000117 // null-terminated!
118 char *ItemStr = (char*)BucketItem+ItemSize;
Daniel Dunbar5bf72e22009-07-23 18:17:34 +0000119 if (Name == StringRef(ItemStr, BucketItem->getKeyLength())) {
Chris Lattner149e6662006-10-29 23:42:03 +0000120 // We found a match!
121 return BucketNo;
122 }
123 }
124
125 // Okay, we didn't find the item. Probe to the next bucket.
126 BucketNo = (BucketNo+ProbeAmt) & (HTSize-1);
127
128 // Use quadratic probing, it has fewer clumping artifacts than linear
129 // probing and has good cache behavior in the common case.
130 ++ProbeAmt;
131 }
132}
133
Chris Lattnerdb08c1b2007-02-11 19:49:41 +0000134/// FindKey - Look up the bucket that contains the specified key. If it exists
135/// in the map, return the bucket number of the key. Otherwise return -1.
136/// This does not modify the map.
Daniel Dunbarad36e8a2009-11-06 10:58:06 +0000137int StringMapImpl::FindKey(StringRef Key) const {
Chris Lattnerdb08c1b2007-02-11 19:49:41 +0000138 unsigned HTSize = NumBuckets;
Chris Lattner23763462007-04-04 00:29:37 +0000139 if (HTSize == 0) return -1; // Really empty table?
Daniel Dunbar77668002009-10-17 18:21:06 +0000140 unsigned FullHashValue = HashString(Key);
Chris Lattnerdb08c1b2007-02-11 19:49:41 +0000141 unsigned BucketNo = FullHashValue & (HTSize-1);
Benjamin Kramer46236ee2011-12-27 20:35:07 +0000142 unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1);
143
Chris Lattnerdb08c1b2007-02-11 19:49:41 +0000144 unsigned ProbeAmt = 1;
Eugene Zelenko33d7b762016-08-23 17:14:32 +0000145 while (true) {
Benjamin Kramer46236ee2011-12-27 20:35:07 +0000146 StringMapEntryBase *BucketItem = TheTable[BucketNo];
Chris Lattnerdb08c1b2007-02-11 19:49:41 +0000147 // If we found an empty bucket, this key isn't in the table yet, return.
Craig Topper8d399f82014-04-09 04:20:00 +0000148 if (LLVM_LIKELY(!BucketItem))
Chris Lattnerdb08c1b2007-02-11 19:49:41 +0000149 return -1;
150
Chris Lattner77baa562007-02-11 20:58:00 +0000151 if (BucketItem == getTombstoneVal()) {
152 // Ignore tombstones.
Benjamin Kramerffa24e02012-08-29 22:57:04 +0000153 } else if (LLVM_LIKELY(HashTable[BucketNo] == FullHashValue)) {
Chris Lattner77baa562007-02-11 20:58:00 +0000154 // If the full hash value matches, check deeply for a match. The common
155 // case here is that we are only looking at the buckets (for item info
156 // being non-null and for the full hash value) not at the items. This
157 // is important for cache locality.
158
Chris Lattnerdb08c1b2007-02-11 19:49:41 +0000159 // Do the comparison like this because NameStart isn't necessarily
160 // null-terminated!
161 char *ItemStr = (char*)BucketItem+ItemSize;
Daniel Dunbar5bf72e22009-07-23 18:17:34 +0000162 if (Key == StringRef(ItemStr, BucketItem->getKeyLength())) {
Chris Lattnerdb08c1b2007-02-11 19:49:41 +0000163 // We found a match!
164 return BucketNo;
165 }
166 }
167
168 // Okay, we didn't find the item. Probe to the next bucket.
169 BucketNo = (BucketNo+ProbeAmt) & (HTSize-1);
170
171 // Use quadratic probing, it has fewer clumping artifacts than linear
172 // probing and has good cache behavior in the common case.
173 ++ProbeAmt;
174 }
175}
176
Chris Lattner77baa562007-02-11 20:58:00 +0000177/// RemoveKey - Remove the specified StringMapEntry from the table, but do not
178/// delete it. This aborts if the value isn't in the table.
179void StringMapImpl::RemoveKey(StringMapEntryBase *V) {
180 const char *VStr = (char*)V + ItemSize;
Daniel Dunbar5bf72e22009-07-23 18:17:34 +0000181 StringMapEntryBase *V2 = RemoveKey(StringRef(VStr, V->getKeyLength()));
Jeffrey Yasskin9b43f332010-12-23 00:58:24 +0000182 (void)V2;
Chris Lattner77baa562007-02-11 20:58:00 +0000183 assert(V == V2 && "Didn't find key?");
184}
185
186/// RemoveKey - Remove the StringMapEntry for the specified key from the
187/// table, returning it. If the key is not in the table, this returns null.
Daniel Dunbarad36e8a2009-11-06 10:58:06 +0000188StringMapEntryBase *StringMapImpl::RemoveKey(StringRef Key) {
Daniel Dunbar5bf72e22009-07-23 18:17:34 +0000189 int Bucket = FindKey(Key);
Craig Topperc10719f2014-04-07 04:17:22 +0000190 if (Bucket == -1) return nullptr;
Chris Lattner77baa562007-02-11 20:58:00 +0000191
Benjamin Kramer46236ee2011-12-27 20:35:07 +0000192 StringMapEntryBase *Result = TheTable[Bucket];
193 TheTable[Bucket] = getTombstoneVal();
Chris Lattner77baa562007-02-11 20:58:00 +0000194 --NumItems;
195 ++NumTombstones;
Jakob Stoklund Olesen846f9502011-03-30 18:32:51 +0000196 assert(NumItems + NumTombstones <= NumBuckets);
197
Chris Lattner77baa562007-02-11 20:58:00 +0000198 return Result;
199}
200
Chris Lattner149e6662006-10-29 23:42:03 +0000201/// RehashTable - Grow the table, redistributing values into the buckets with
202/// the appropriate mod-of-hashtable-size.
David Blaikie16a9eab2014-06-23 18:28:53 +0000203unsigned StringMapImpl::RehashTable(unsigned BucketNo) {
Jakob Stoklund Olesenf587f442011-03-30 18:32:44 +0000204 unsigned NewSize;
Benjamin Kramer46236ee2011-12-27 20:35:07 +0000205 unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1);
Jakob Stoklund Olesenf587f442011-03-30 18:32:44 +0000206
207 // If the hash table is now more than 3/4 full, or if fewer than 1/8 of
208 // the buckets are empty (meaning that many are filled with tombstones),
209 // grow/rehash the table.
Benjamin Kramer654a85e2015-02-23 16:41:36 +0000210 if (LLVM_UNLIKELY(NumItems * 4 > NumBuckets * 3)) {
Jakob Stoklund Olesenf587f442011-03-30 18:32:44 +0000211 NewSize = NumBuckets*2;
Benjamin Kramer654a85e2015-02-23 16:41:36 +0000212 } else if (LLVM_UNLIKELY(NumBuckets - (NumItems + NumTombstones) <=
213 NumBuckets / 8)) {
Jakob Stoklund Olesenf587f442011-03-30 18:32:44 +0000214 NewSize = NumBuckets;
215 } else {
David Blaikie16a9eab2014-06-23 18:28:53 +0000216 return BucketNo;
Jakob Stoklund Olesenf587f442011-03-30 18:32:44 +0000217 }
218
David Blaikie16a9eab2014-06-23 18:28:53 +0000219 unsigned NewBucketNo = BucketNo;
Chris Lattnere15605c2007-02-11 08:20:35 +0000220 // Allocate one extra bucket which will always be non-empty. This allows the
221 // iterators to stop at end.
Benjamin Kramer46236ee2011-12-27 20:35:07 +0000222 StringMapEntryBase **NewTableArray =
223 (StringMapEntryBase **)calloc(NewSize+1, sizeof(StringMapEntryBase *) +
224 sizeof(unsigned));
Matthias Braunc20b3382017-07-20 01:30:39 +0000225
226 if (NewTableArray == nullptr)
227 report_bad_alloc_error("Allocation of StringMap hash table failed.");
228
Benjamin Kramer46236ee2011-12-27 20:35:07 +0000229 unsigned *NewHashArray = (unsigned *)(NewTableArray + NewSize + 1);
230 NewTableArray[NewSize] = (StringMapEntryBase*)2;
231
Chris Lattner149e6662006-10-29 23:42:03 +0000232 // Rehash all the items into their new buckets. Luckily :) we already have
233 // the hash values available, so we don't have to rehash any strings.
Benjamin Kramer46236ee2011-12-27 20:35:07 +0000234 for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
235 StringMapEntryBase *Bucket = TheTable[I];
236 if (Bucket && Bucket != getTombstoneVal()) {
Chris Lattner149e6662006-10-29 23:42:03 +0000237 // Fast case, bucket available.
Benjamin Kramer46236ee2011-12-27 20:35:07 +0000238 unsigned FullHash = HashTable[I];
Chris Lattner149e6662006-10-29 23:42:03 +0000239 unsigned NewBucket = FullHash & (NewSize-1);
Craig Topper8d399f82014-04-09 04:20:00 +0000240 if (!NewTableArray[NewBucket]) {
Benjamin Kramer46236ee2011-12-27 20:35:07 +0000241 NewTableArray[FullHash & (NewSize-1)] = Bucket;
242 NewHashArray[FullHash & (NewSize-1)] = FullHash;
David Blaikie16a9eab2014-06-23 18:28:53 +0000243 if (I == BucketNo)
244 NewBucketNo = NewBucket;
Chris Lattner149e6662006-10-29 23:42:03 +0000245 continue;
246 }
247
Chris Lattner77baa562007-02-11 20:58:00 +0000248 // Otherwise probe for a spot.
Chris Lattner149e6662006-10-29 23:42:03 +0000249 unsigned ProbeSize = 1;
250 do {
251 NewBucket = (NewBucket + ProbeSize++) & (NewSize-1);
Benjamin Kramer46236ee2011-12-27 20:35:07 +0000252 } while (NewTableArray[NewBucket]);
Chris Lattner149e6662006-10-29 23:42:03 +0000253
254 // Finally found a slot. Fill it in.
Benjamin Kramer46236ee2011-12-27 20:35:07 +0000255 NewTableArray[NewBucket] = Bucket;
256 NewHashArray[NewBucket] = FullHash;
David Blaikie16a9eab2014-06-23 18:28:53 +0000257 if (I == BucketNo)
258 NewBucketNo = NewBucket;
Chris Lattner149e6662006-10-29 23:42:03 +0000259 }
260 }
261
Chris Lattnerc770a022007-04-04 17:24:28 +0000262 free(TheTable);
Chris Lattner149e6662006-10-29 23:42:03 +0000263
264 TheTable = NewTableArray;
265 NumBuckets = NewSize;
Jakob Stoklund Olesen846f9502011-03-30 18:32:51 +0000266 NumTombstones = 0;
David Blaikie16a9eab2014-06-23 18:28:53 +0000267 return NewBucketNo;
Chris Lattner149e6662006-10-29 23:42:03 +0000268}