LLVM API Documentation
00001 //===--- StringMap.h - String Hash table map interface ----------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the StringMap class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_ADT_STRINGMAP_H 00015 #define LLVM_ADT_STRINGMAP_H 00016 00017 #include "llvm/ADT/StringRef.h" 00018 #include "llvm/Support/Allocator.h" 00019 #include <cstring> 00020 00021 namespace llvm { 00022 template<typename ValueT> 00023 class StringMapConstIterator; 00024 template<typename ValueT> 00025 class StringMapIterator; 00026 template<typename ValueTy> 00027 class StringMapEntry; 00028 00029 /// StringMapEntryInitializer - This datatype can be partially specialized for 00030 /// various datatypes in a stringmap to allow them to be initialized when an 00031 /// entry is default constructed for the map. 00032 template<typename ValueTy> 00033 class StringMapEntryInitializer { 00034 public: 00035 template <typename InitTy> 00036 static void Initialize(StringMapEntry<ValueTy> &T, InitTy InitVal) { 00037 T.second = InitVal; 00038 } 00039 }; 00040 00041 00042 /// StringMapEntryBase - Shared base class of StringMapEntry instances. 00043 class StringMapEntryBase { 00044 unsigned StrLen; 00045 public: 00046 explicit StringMapEntryBase(unsigned Len) : StrLen(Len) {} 00047 00048 unsigned getKeyLength() const { return StrLen; } 00049 }; 00050 00051 /// StringMapImpl - This is the base class of StringMap that is shared among 00052 /// all of its instantiations. 00053 class StringMapImpl { 00054 protected: 00055 // Array of NumBuckets pointers to entries, null pointers are holes. 00056 // TheTable[NumBuckets] contains a sentinel value for easy iteration. Followed 00057 // by an array of the actual hash values as unsigned integers. 00058 StringMapEntryBase **TheTable; 00059 unsigned NumBuckets; 00060 unsigned NumItems; 00061 unsigned NumTombstones; 00062 unsigned ItemSize; 00063 protected: 00064 explicit StringMapImpl(unsigned itemSize) : ItemSize(itemSize) { 00065 // Initialize the map with zero buckets to allocation. 00066 TheTable = 0; 00067 NumBuckets = 0; 00068 NumItems = 0; 00069 NumTombstones = 0; 00070 } 00071 StringMapImpl(unsigned InitSize, unsigned ItemSize); 00072 void RehashTable(); 00073 00074 /// LookupBucketFor - Look up the bucket that the specified string should end 00075 /// up in. If it already exists as a key in the map, the Item pointer for the 00076 /// specified bucket will be non-null. Otherwise, it will be null. In either 00077 /// case, the FullHashValue field of the bucket will be set to the hash value 00078 /// of the string. 00079 unsigned LookupBucketFor(StringRef Key); 00080 00081 /// FindKey - Look up the bucket that contains the specified key. If it exists 00082 /// in the map, return the bucket number of the key. Otherwise return -1. 00083 /// This does not modify the map. 00084 int FindKey(StringRef Key) const; 00085 00086 /// RemoveKey - Remove the specified StringMapEntry from the table, but do not 00087 /// delete it. This aborts if the value isn't in the table. 00088 void RemoveKey(StringMapEntryBase *V); 00089 00090 /// RemoveKey - Remove the StringMapEntry for the specified key from the 00091 /// table, returning it. If the key is not in the table, this returns null. 00092 StringMapEntryBase *RemoveKey(StringRef Key); 00093 private: 00094 void init(unsigned Size); 00095 public: 00096 static StringMapEntryBase *getTombstoneVal() { 00097 return (StringMapEntryBase*)-1; 00098 } 00099 00100 unsigned getNumBuckets() const { return NumBuckets; } 00101 unsigned getNumItems() const { return NumItems; } 00102 00103 bool empty() const { return NumItems == 0; } 00104 unsigned size() const { return NumItems; } 00105 }; 00106 00107 /// StringMapEntry - This is used to represent one value that is inserted into 00108 /// a StringMap. It contains the Value itself and the key: the string length 00109 /// and data. 00110 template<typename ValueTy> 00111 class StringMapEntry : public StringMapEntryBase { 00112 public: 00113 ValueTy second; 00114 00115 explicit StringMapEntry(unsigned strLen) 00116 : StringMapEntryBase(strLen), second() {} 00117 StringMapEntry(unsigned strLen, const ValueTy &V) 00118 : StringMapEntryBase(strLen), second(V) {} 00119 00120 StringRef getKey() const { 00121 return StringRef(getKeyData(), getKeyLength()); 00122 } 00123 00124 const ValueTy &getValue() const { return second; } 00125 ValueTy &getValue() { return second; } 00126 00127 void setValue(const ValueTy &V) { second = V; } 00128 00129 /// getKeyData - Return the start of the string data that is the key for this 00130 /// value. The string data is always stored immediately after the 00131 /// StringMapEntry object. 00132 const char *getKeyData() const {return reinterpret_cast<const char*>(this+1);} 00133 00134 StringRef first() const { return StringRef(getKeyData(), getKeyLength()); } 00135 00136 /// Create - Create a StringMapEntry for the specified key and default 00137 /// construct the value. 00138 template<typename AllocatorTy, typename InitType> 00139 static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd, 00140 AllocatorTy &Allocator, 00141 InitType InitVal) { 00142 unsigned KeyLength = static_cast<unsigned>(KeyEnd-KeyStart); 00143 00144 // Okay, the item doesn't already exist, and 'Bucket' is the bucket to fill 00145 // in. Allocate a new item with space for the string at the end and a null 00146 // terminator. 00147 00148 unsigned AllocSize = static_cast<unsigned>(sizeof(StringMapEntry))+ 00149 KeyLength+1; 00150 unsigned Alignment = alignOf<StringMapEntry>(); 00151 00152 StringMapEntry *NewItem = 00153 static_cast<StringMapEntry*>(Allocator.Allocate(AllocSize,Alignment)); 00154 00155 // Default construct the value. 00156 new (NewItem) StringMapEntry(KeyLength); 00157 00158 // Copy the string information. 00159 char *StrBuffer = const_cast<char*>(NewItem->getKeyData()); 00160 memcpy(StrBuffer, KeyStart, KeyLength); 00161 StrBuffer[KeyLength] = 0; // Null terminate for convenience of clients. 00162 00163 // Initialize the value if the client wants to. 00164 StringMapEntryInitializer<ValueTy>::Initialize(*NewItem, InitVal); 00165 return NewItem; 00166 } 00167 00168 template<typename AllocatorTy> 00169 static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd, 00170 AllocatorTy &Allocator) { 00171 return Create(KeyStart, KeyEnd, Allocator, 0); 00172 } 00173 00174 /// Create - Create a StringMapEntry with normal malloc/free. 00175 template<typename InitType> 00176 static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd, 00177 InitType InitVal) { 00178 MallocAllocator A; 00179 return Create(KeyStart, KeyEnd, A, InitVal); 00180 } 00181 00182 static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd) { 00183 return Create(KeyStart, KeyEnd, ValueTy()); 00184 } 00185 00186 /// GetStringMapEntryFromValue - Given a value that is known to be embedded 00187 /// into a StringMapEntry, return the StringMapEntry itself. 00188 static StringMapEntry &GetStringMapEntryFromValue(ValueTy &V) { 00189 StringMapEntry *EPtr = 0; 00190 char *Ptr = reinterpret_cast<char*>(&V) - 00191 (reinterpret_cast<char*>(&EPtr->second) - 00192 reinterpret_cast<char*>(EPtr)); 00193 return *reinterpret_cast<StringMapEntry*>(Ptr); 00194 } 00195 static const StringMapEntry &GetStringMapEntryFromValue(const ValueTy &V) { 00196 return GetStringMapEntryFromValue(const_cast<ValueTy&>(V)); 00197 } 00198 00199 /// GetStringMapEntryFromKeyData - Given key data that is known to be embedded 00200 /// into a StringMapEntry, return the StringMapEntry itself. 00201 static StringMapEntry &GetStringMapEntryFromKeyData(const char *KeyData) { 00202 char *Ptr = const_cast<char*>(KeyData) - sizeof(StringMapEntry<ValueTy>); 00203 return *reinterpret_cast<StringMapEntry*>(Ptr); 00204 } 00205 00206 /// Destroy - Destroy this StringMapEntry, releasing memory back to the 00207 /// specified allocator. 00208 template<typename AllocatorTy> 00209 void Destroy(AllocatorTy &Allocator) { 00210 // Free memory referenced by the item. 00211 this->~StringMapEntry(); 00212 Allocator.Deallocate(this); 00213 } 00214 00215 /// Destroy this object, releasing memory back to the malloc allocator. 00216 void Destroy() { 00217 MallocAllocator A; 00218 Destroy(A); 00219 } 00220 }; 00221 00222 00223 /// StringMap - This is an unconventional map that is specialized for handling 00224 /// keys that are "strings", which are basically ranges of bytes. This does some 00225 /// funky memory allocation and hashing things to make it extremely efficient, 00226 /// storing the string data *after* the value in the map. 00227 template<typename ValueTy, typename AllocatorTy = MallocAllocator> 00228 class StringMap : public StringMapImpl { 00229 AllocatorTy Allocator; 00230 public: 00231 typedef StringMapEntry<ValueTy> MapEntryTy; 00232 00233 StringMap() : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {} 00234 explicit StringMap(unsigned InitialSize) 00235 : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) {} 00236 00237 explicit StringMap(AllocatorTy A) 00238 : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A) {} 00239 00240 StringMap(unsigned InitialSize, AllocatorTy A) 00241 : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))), 00242 Allocator(A) {} 00243 00244 StringMap(const StringMap &RHS) 00245 : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) { 00246 assert(RHS.empty() && 00247 "Copy ctor from non-empty stringmap not implemented yet!"); 00248 (void)RHS; 00249 } 00250 void operator=(const StringMap &RHS) { 00251 assert(RHS.empty() && 00252 "assignment from non-empty stringmap not implemented yet!"); 00253 (void)RHS; 00254 clear(); 00255 } 00256 00257 typedef typename ReferenceAdder<AllocatorTy>::result AllocatorRefTy; 00258 typedef typename ReferenceAdder<const AllocatorTy>::result AllocatorCRefTy; 00259 AllocatorRefTy getAllocator() { return Allocator; } 00260 AllocatorCRefTy getAllocator() const { return Allocator; } 00261 00262 typedef const char* key_type; 00263 typedef ValueTy mapped_type; 00264 typedef StringMapEntry<ValueTy> value_type; 00265 typedef size_t size_type; 00266 00267 typedef StringMapConstIterator<ValueTy> const_iterator; 00268 typedef StringMapIterator<ValueTy> iterator; 00269 00270 iterator begin() { 00271 return iterator(TheTable, NumBuckets == 0); 00272 } 00273 iterator end() { 00274 return iterator(TheTable+NumBuckets, true); 00275 } 00276 const_iterator begin() const { 00277 return const_iterator(TheTable, NumBuckets == 0); 00278 } 00279 const_iterator end() const { 00280 return const_iterator(TheTable+NumBuckets, true); 00281 } 00282 00283 iterator find(StringRef Key) { 00284 int Bucket = FindKey(Key); 00285 if (Bucket == -1) return end(); 00286 return iterator(TheTable+Bucket, true); 00287 } 00288 00289 const_iterator find(StringRef Key) const { 00290 int Bucket = FindKey(Key); 00291 if (Bucket == -1) return end(); 00292 return const_iterator(TheTable+Bucket, true); 00293 } 00294 00295 /// lookup - Return the entry for the specified key, or a default 00296 /// constructed value if no such entry exists. 00297 ValueTy lookup(StringRef Key) const { 00298 const_iterator it = find(Key); 00299 if (it != end()) 00300 return it->second; 00301 return ValueTy(); 00302 } 00303 00304 ValueTy &operator[](StringRef Key) { 00305 return GetOrCreateValue(Key).getValue(); 00306 } 00307 00308 size_type count(StringRef Key) const { 00309 return find(Key) == end() ? 0 : 1; 00310 } 00311 00312 /// insert - Insert the specified key/value pair into the map. If the key 00313 /// already exists in the map, return false and ignore the request, otherwise 00314 /// insert it and return true. 00315 bool insert(MapEntryTy *KeyValue) { 00316 unsigned BucketNo = LookupBucketFor(KeyValue->getKey()); 00317 StringMapEntryBase *&Bucket = TheTable[BucketNo]; 00318 if (Bucket && Bucket != getTombstoneVal()) 00319 return false; // Already exists in map. 00320 00321 if (Bucket == getTombstoneVal()) 00322 --NumTombstones; 00323 Bucket = KeyValue; 00324 ++NumItems; 00325 assert(NumItems + NumTombstones <= NumBuckets); 00326 00327 RehashTable(); 00328 return true; 00329 } 00330 00331 // clear - Empties out the StringMap 00332 void clear() { 00333 if (empty()) return; 00334 00335 // Zap all values, resetting the keys back to non-present (not tombstone), 00336 // which is safe because we're removing all elements. 00337 for (unsigned I = 0, E = NumBuckets; I != E; ++I) { 00338 StringMapEntryBase *&Bucket = TheTable[I]; 00339 if (Bucket && Bucket != getTombstoneVal()) { 00340 static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator); 00341 } 00342 Bucket = 0; 00343 } 00344 00345 NumItems = 0; 00346 NumTombstones = 0; 00347 } 00348 00349 /// GetOrCreateValue - Look up the specified key in the table. If a value 00350 /// exists, return it. Otherwise, default construct a value, insert it, and 00351 /// return. 00352 template <typename InitTy> 00353 MapEntryTy &GetOrCreateValue(StringRef Key, InitTy Val) { 00354 unsigned BucketNo = LookupBucketFor(Key); 00355 StringMapEntryBase *&Bucket = TheTable[BucketNo]; 00356 if (Bucket && Bucket != getTombstoneVal()) 00357 return *static_cast<MapEntryTy*>(Bucket); 00358 00359 MapEntryTy *NewItem = 00360 MapEntryTy::Create(Key.begin(), Key.end(), Allocator, Val); 00361 00362 if (Bucket == getTombstoneVal()) 00363 --NumTombstones; 00364 ++NumItems; 00365 assert(NumItems + NumTombstones <= NumBuckets); 00366 00367 // Fill in the bucket for the hash table. The FullHashValue was already 00368 // filled in by LookupBucketFor. 00369 Bucket = NewItem; 00370 00371 RehashTable(); 00372 return *NewItem; 00373 } 00374 00375 MapEntryTy &GetOrCreateValue(StringRef Key) { 00376 return GetOrCreateValue(Key, ValueTy()); 00377 } 00378 00379 /// remove - Remove the specified key/value pair from the map, but do not 00380 /// erase it. This aborts if the key is not in the map. 00381 void remove(MapEntryTy *KeyValue) { 00382 RemoveKey(KeyValue); 00383 } 00384 00385 void erase(iterator I) { 00386 MapEntryTy &V = *I; 00387 remove(&V); 00388 V.Destroy(Allocator); 00389 } 00390 00391 bool erase(StringRef Key) { 00392 iterator I = find(Key); 00393 if (I == end()) return false; 00394 erase(I); 00395 return true; 00396 } 00397 00398 ~StringMap() { 00399 clear(); 00400 free(TheTable); 00401 } 00402 }; 00403 00404 00405 template<typename ValueTy> 00406 class StringMapConstIterator { 00407 protected: 00408 StringMapEntryBase **Ptr; 00409 public: 00410 typedef StringMapEntry<ValueTy> value_type; 00411 00412 explicit StringMapConstIterator(StringMapEntryBase **Bucket, 00413 bool NoAdvance = false) 00414 : Ptr(Bucket) { 00415 if (!NoAdvance) AdvancePastEmptyBuckets(); 00416 } 00417 00418 const value_type &operator*() const { 00419 return *static_cast<StringMapEntry<ValueTy>*>(*Ptr); 00420 } 00421 const value_type *operator->() const { 00422 return static_cast<StringMapEntry<ValueTy>*>(*Ptr); 00423 } 00424 00425 bool operator==(const StringMapConstIterator &RHS) const { 00426 return Ptr == RHS.Ptr; 00427 } 00428 bool operator!=(const StringMapConstIterator &RHS) const { 00429 return Ptr != RHS.Ptr; 00430 } 00431 00432 inline StringMapConstIterator& operator++() { // Preincrement 00433 ++Ptr; 00434 AdvancePastEmptyBuckets(); 00435 return *this; 00436 } 00437 StringMapConstIterator operator++(int) { // Postincrement 00438 StringMapConstIterator tmp = *this; ++*this; return tmp; 00439 } 00440 00441 private: 00442 void AdvancePastEmptyBuckets() { 00443 while (*Ptr == 0 || *Ptr == StringMapImpl::getTombstoneVal()) 00444 ++Ptr; 00445 } 00446 }; 00447 00448 template<typename ValueTy> 00449 class StringMapIterator : public StringMapConstIterator<ValueTy> { 00450 public: 00451 explicit StringMapIterator(StringMapEntryBase **Bucket, 00452 bool NoAdvance = false) 00453 : StringMapConstIterator<ValueTy>(Bucket, NoAdvance) { 00454 } 00455 StringMapEntry<ValueTy> &operator*() const { 00456 return *static_cast<StringMapEntry<ValueTy>*>(*this->Ptr); 00457 } 00458 StringMapEntry<ValueTy> *operator->() const { 00459 return static_cast<StringMapEntry<ValueTy>*>(*this->Ptr); 00460 } 00461 }; 00462 00463 } 00464 00465 #endif