LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
StringMap.h
Go to the documentation of this file.
1 //===--- StringMap.h - String Hash table map interface ----------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the StringMap class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_ADT_STRINGMAP_H
15 #define LLVM_ADT_STRINGMAP_H
16 
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/Support/Allocator.h"
19 #include <cstring>
20 
21 namespace llvm {
22  template<typename ValueT>
24  template<typename ValueT>
26  template<typename ValueTy>
28 
29 /// StringMapEntryInitializer - This datatype can be partially specialized for
30 /// various datatypes in a stringmap to allow them to be initialized when an
31 /// entry is default constructed for the map.
32 template<typename ValueTy>
34 public:
35  template <typename InitTy>
36  static void Initialize(StringMapEntry<ValueTy> &T, InitTy InitVal) {
37  T.second = InitVal;
38  }
39 };
40 
41 
42 /// StringMapEntryBase - Shared base class of StringMapEntry instances.
44  unsigned StrLen;
45 public:
46  explicit StringMapEntryBase(unsigned Len) : StrLen(Len) {}
47 
48  unsigned getKeyLength() const { return StrLen; }
49 };
50 
51 /// StringMapImpl - This is the base class of StringMap that is shared among
52 /// all of its instantiations.
54 protected:
55  // Array of NumBuckets pointers to entries, null pointers are holes.
56  // TheTable[NumBuckets] contains a sentinel value for easy iteration. Followed
57  // by an array of the actual hash values as unsigned integers.
59  unsigned NumBuckets;
60  unsigned NumItems;
61  unsigned NumTombstones;
62  unsigned ItemSize;
63 protected:
64  explicit StringMapImpl(unsigned itemSize) : ItemSize(itemSize) {
65  // Initialize the map with zero buckets to allocation.
66  TheTable = 0;
67  NumBuckets = 0;
68  NumItems = 0;
69  NumTombstones = 0;
70  }
71  StringMapImpl(unsigned InitSize, unsigned ItemSize);
72  void RehashTable();
73 
74  /// LookupBucketFor - Look up the bucket that the specified string should end
75  /// up in. If it already exists as a key in the map, the Item pointer for the
76  /// specified bucket will be non-null. Otherwise, it will be null. In either
77  /// case, the FullHashValue field of the bucket will be set to the hash value
78  /// of the string.
79  unsigned LookupBucketFor(StringRef Key);
80 
81  /// FindKey - Look up the bucket that contains the specified key. If it exists
82  /// in the map, return the bucket number of the key. Otherwise return -1.
83  /// This does not modify the map.
84  int FindKey(StringRef Key) const;
85 
86  /// RemoveKey - Remove the specified StringMapEntry from the table, but do not
87  /// delete it. This aborts if the value isn't in the table.
89 
90  /// RemoveKey - Remove the StringMapEntry for the specified key from the
91  /// table, returning it. If the key is not in the table, this returns null.
93 private:
94  void init(unsigned Size);
95 public:
97  return (StringMapEntryBase*)-1;
98  }
99 
100  unsigned getNumBuckets() const { return NumBuckets; }
101  unsigned getNumItems() const { return NumItems; }
102 
103  bool empty() const { return NumItems == 0; }
104  unsigned size() const { return NumItems; }
105 
106  void swap(StringMapImpl &Other) {
107  std::swap(TheTable, Other.TheTable);
109  std::swap(NumItems, Other.NumItems);
111  }
112 };
113 
114 /// StringMapEntry - This is used to represent one value that is inserted into
115 /// a StringMap. It contains the Value itself and the key: the string length
116 /// and data.
117 template<typename ValueTy>
118 class StringMapEntry : public StringMapEntryBase {
119  StringMapEntry(StringMapEntry &E) LLVM_DELETED_FUNCTION;
120 public:
121  ValueTy second;
122 
123  explicit StringMapEntry(unsigned strLen)
124  : StringMapEntryBase(strLen), second() {}
125  StringMapEntry(unsigned strLen, const ValueTy &V)
126  : StringMapEntryBase(strLen), second(V) {}
127 
128  StringRef getKey() const {
129  return StringRef(getKeyData(), getKeyLength());
130  }
131 
132  const ValueTy &getValue() const { return second; }
133  ValueTy &getValue() { return second; }
134 
135  void setValue(const ValueTy &V) { second = V; }
136 
137  /// getKeyData - Return the start of the string data that is the key for this
138  /// value. The string data is always stored immediately after the
139  /// StringMapEntry object.
140  const char *getKeyData() const {return reinterpret_cast<const char*>(this+1);}
141 
142  StringRef first() const { return StringRef(getKeyData(), getKeyLength()); }
143 
144  /// Create - Create a StringMapEntry for the specified key and default
145  /// construct the value.
146  template<typename AllocatorTy, typename InitType>
147  static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
148  AllocatorTy &Allocator,
149  InitType InitVal) {
150  unsigned KeyLength = static_cast<unsigned>(KeyEnd-KeyStart);
151 
152  // Okay, the item doesn't already exist, and 'Bucket' is the bucket to fill
153  // in. Allocate a new item with space for the string at the end and a null
154  // terminator.
155 
156  unsigned AllocSize = static_cast<unsigned>(sizeof(StringMapEntry))+
157  KeyLength+1;
158  unsigned Alignment = alignOf<StringMapEntry>();
159 
160  StringMapEntry *NewItem =
161  static_cast<StringMapEntry*>(Allocator.Allocate(AllocSize,Alignment));
162 
163  // Default construct the value.
164  new (NewItem) StringMapEntry(KeyLength);
165 
166  // Copy the string information.
167  char *StrBuffer = const_cast<char*>(NewItem->getKeyData());
168  memcpy(StrBuffer, KeyStart, KeyLength);
169  StrBuffer[KeyLength] = 0; // Null terminate for convenience of clients.
170 
171  // Initialize the value if the client wants to.
173  return NewItem;
174  }
175 
176  template<typename AllocatorTy>
177  static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
178  AllocatorTy &Allocator) {
179  return Create(KeyStart, KeyEnd, Allocator, 0);
180  }
181 
182  /// Create - Create a StringMapEntry with normal malloc/free.
183  template<typename InitType>
184  static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
185  InitType InitVal) {
187  return Create(KeyStart, KeyEnd, A, InitVal);
188  }
189 
190  static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd) {
191  return Create(KeyStart, KeyEnd, ValueTy());
192  }
193 
194  /// GetStringMapEntryFromValue - Given a value that is known to be embedded
195  /// into a StringMapEntry, return the StringMapEntry itself.
197  StringMapEntry *EPtr = 0;
198  char *Ptr = reinterpret_cast<char*>(&V) -
199  (reinterpret_cast<char*>(&EPtr->second) -
200  reinterpret_cast<char*>(EPtr));
201  return *reinterpret_cast<StringMapEntry*>(Ptr);
202  }
203  static const StringMapEntry &GetStringMapEntryFromValue(const ValueTy &V) {
204  return GetStringMapEntryFromValue(const_cast<ValueTy&>(V));
205  }
206 
207  /// GetStringMapEntryFromKeyData - Given key data that is known to be embedded
208  /// into a StringMapEntry, return the StringMapEntry itself.
209  static StringMapEntry &GetStringMapEntryFromKeyData(const char *KeyData) {
210  char *Ptr = const_cast<char*>(KeyData) - sizeof(StringMapEntry<ValueTy>);
211  return *reinterpret_cast<StringMapEntry*>(Ptr);
212  }
213 
214  /// Destroy - Destroy this StringMapEntry, releasing memory back to the
215  /// specified allocator.
216  template<typename AllocatorTy>
217  void Destroy(AllocatorTy &Allocator) {
218  // Free memory referenced by the item.
219  this->~StringMapEntry();
220  Allocator.Deallocate(this);
221  }
222 
223  /// Destroy this object, releasing memory back to the malloc allocator.
224  void Destroy() {
226  Destroy(A);
227  }
228 };
229 
230 
231 /// StringMap - This is an unconventional map that is specialized for handling
232 /// keys that are "strings", which are basically ranges of bytes. This does some
233 /// funky memory allocation and hashing things to make it extremely efficient,
234 /// storing the string data *after* the value in the map.
235 template<typename ValueTy, typename AllocatorTy = MallocAllocator>
236 class StringMap : public StringMapImpl {
237  AllocatorTy Allocator;
238 public:
240 
241  StringMap() : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {}
242  explicit StringMap(unsigned InitialSize)
243  : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) {}
244 
245  explicit StringMap(AllocatorTy A)
246  : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A) {}
247 
248  StringMap(unsigned InitialSize, AllocatorTy A)
249  : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))),
250  Allocator(A) {}
251 
252  StringMap(const StringMap &RHS)
253  : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {
254  assert(RHS.empty() &&
255  "Copy ctor from non-empty stringmap not implemented yet!");
256  (void)RHS;
257  }
258  void operator=(const StringMap &RHS) {
259  assert(RHS.empty() &&
260  "assignment from non-empty stringmap not implemented yet!");
261  (void)RHS;
262  clear();
263  }
264 
267  AllocatorRefTy getAllocator() { return Allocator; }
268  AllocatorCRefTy getAllocator() const { return Allocator; }
269 
270  typedef const char* key_type;
271  typedef ValueTy mapped_type;
273  typedef size_t size_type;
274 
277 
279  return iterator(TheTable, NumBuckets == 0);
280  }
282  return iterator(TheTable+NumBuckets, true);
283  }
285  return const_iterator(TheTable, NumBuckets == 0);
286  }
287  const_iterator end() const {
288  return const_iterator(TheTable+NumBuckets, true);
289  }
290 
292  int Bucket = FindKey(Key);
293  if (Bucket == -1) return end();
294  return iterator(TheTable+Bucket, true);
295  }
296 
298  int Bucket = FindKey(Key);
299  if (Bucket == -1) return end();
300  return const_iterator(TheTable+Bucket, true);
301  }
302 
303  /// lookup - Return the entry for the specified key, or a default
304  /// constructed value if no such entry exists.
305  ValueTy lookup(StringRef Key) const {
306  const_iterator it = find(Key);
307  if (it != end())
308  return it->second;
309  return ValueTy();
310  }
311 
312  ValueTy &operator[](StringRef Key) {
313  return GetOrCreateValue(Key).getValue();
314  }
315 
316  size_type count(StringRef Key) const {
317  return find(Key) == end() ? 0 : 1;
318  }
319 
320  /// insert - Insert the specified key/value pair into the map. If the key
321  /// already exists in the map, return false and ignore the request, otherwise
322  /// insert it and return true.
323  bool insert(MapEntryTy *KeyValue) {
324  unsigned BucketNo = LookupBucketFor(KeyValue->getKey());
325  StringMapEntryBase *&Bucket = TheTable[BucketNo];
326  if (Bucket && Bucket != getTombstoneVal())
327  return false; // Already exists in map.
328 
329  if (Bucket == getTombstoneVal())
330  --NumTombstones;
331  Bucket = KeyValue;
332  ++NumItems;
333  assert(NumItems + NumTombstones <= NumBuckets);
334 
335  RehashTable();
336  return true;
337  }
338 
339  // clear - Empties out the StringMap
340  void clear() {
341  if (empty()) return;
342 
343  // Zap all values, resetting the keys back to non-present (not tombstone),
344  // which is safe because we're removing all elements.
345  for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
346  StringMapEntryBase *&Bucket = TheTable[I];
347  if (Bucket && Bucket != getTombstoneVal()) {
348  static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator);
349  }
350  Bucket = 0;
351  }
352 
353  NumItems = 0;
354  NumTombstones = 0;
355  }
356 
357  /// GetOrCreateValue - Look up the specified key in the table. If a value
358  /// exists, return it. Otherwise, default construct a value, insert it, and
359  /// return.
360  template <typename InitTy>
362  unsigned BucketNo = LookupBucketFor(Key);
363  StringMapEntryBase *&Bucket = TheTable[BucketNo];
364  if (Bucket && Bucket != getTombstoneVal())
365  return *static_cast<MapEntryTy*>(Bucket);
366 
367  MapEntryTy *NewItem =
368  MapEntryTy::Create(Key.begin(), Key.end(), Allocator, Val);
369 
370  if (Bucket == getTombstoneVal())
371  --NumTombstones;
372  ++NumItems;
373  assert(NumItems + NumTombstones <= NumBuckets);
374 
375  // Fill in the bucket for the hash table. The FullHashValue was already
376  // filled in by LookupBucketFor.
377  Bucket = NewItem;
378 
379  RehashTable();
380  return *NewItem;
381  }
382 
384  return GetOrCreateValue(Key, ValueTy());
385  }
386 
387  /// remove - Remove the specified key/value pair from the map, but do not
388  /// erase it. This aborts if the key is not in the map.
389  void remove(MapEntryTy *KeyValue) {
390  RemoveKey(KeyValue);
391  }
392 
393  void erase(iterator I) {
394  MapEntryTy &V = *I;
395  remove(&V);
396  V.Destroy(Allocator);
397  }
398 
399  bool erase(StringRef Key) {
400  iterator I = find(Key);
401  if (I == end()) return false;
402  erase(I);
403  return true;
404  }
405 
407  clear();
408  free(TheTable);
409  }
410 };
411 
412 
413 template<typename ValueTy>
414 class StringMapConstIterator {
415 protected:
417 public:
419 
421 
423  bool NoAdvance = false)
424  : Ptr(Bucket) {
425  if (!NoAdvance) AdvancePastEmptyBuckets();
426  }
427 
428  const value_type &operator*() const {
429  return *static_cast<StringMapEntry<ValueTy>*>(*Ptr);
430  }
431  const value_type *operator->() const {
432  return static_cast<StringMapEntry<ValueTy>*>(*Ptr);
433  }
434 
435  bool operator==(const StringMapConstIterator &RHS) const {
436  return Ptr == RHS.Ptr;
437  }
438  bool operator!=(const StringMapConstIterator &RHS) const {
439  return Ptr != RHS.Ptr;
440  }
441 
442  inline StringMapConstIterator& operator++() { // Preincrement
443  ++Ptr;
444  AdvancePastEmptyBuckets();
445  return *this;
446  }
447  StringMapConstIterator operator++(int) { // Postincrement
448  StringMapConstIterator tmp = *this; ++*this; return tmp;
449  }
450 
451 private:
452  void AdvancePastEmptyBuckets() {
453  while (*Ptr == 0 || *Ptr == StringMapImpl::getTombstoneVal())
454  ++Ptr;
455  }
456 };
457 
458 template<typename ValueTy>
459 class StringMapIterator : public StringMapConstIterator<ValueTy> {
460 public:
463  bool NoAdvance = false)
464  : StringMapConstIterator<ValueTy>(Bucket, NoAdvance) {
465  }
467  return *static_cast<StringMapEntry<ValueTy>*>(*this->Ptr);
468  }
470  return static_cast<StringMapEntry<ValueTy>*>(*this->Ptr);
471  }
472 };
473 
474 }
475 
476 #endif
StringMapEntryBase ** Ptr
Definition: StringMap.h:416
const ValueTy & getValue() const
Definition: StringMap.h:132
unsigned getNumItems() const
Definition: StringMap.h:101
StringMapImpl(unsigned itemSize)
Definition: StringMap.h:64
static const StringMapEntry & GetStringMapEntryFromValue(const ValueTy &V)
Definition: StringMap.h:203
AllocatorCRefTy getAllocator() const
Definition: StringMap.h:268
bool operator!=(const StringMapConstIterator &RHS) const
Definition: StringMap.h:438
const_iterator find(StringRef Key) const
Definition: StringMap.h:297
void setValue(const ValueTy &V)
Definition: StringMap.h:135
StringMapEntryBase(unsigned Len)
Definition: StringMap.h:46
bool empty() const
Definition: StringMap.h:103
StringMapEntry< ValueTy > value_type
Definition: StringMap.h:418
int FindKey(StringRef Key) const
Definition: StringMap.cpp:116
iterator find(StringRef Key)
Definition: StringMap.h:291
unsigned LookupBucketFor(StringRef Key)
Definition: StringMap.cpp:58
StringRef first() const
Definition: StringMap.h:142
StringMapIterator(StringMapEntryBase **Bucket, bool NoAdvance=false)
Definition: StringMap.h:462
static StringMapEntry * Create(const char *KeyStart, const char *KeyEnd)
Definition: StringMap.h:190
StringMap(const StringMap &RHS)
Definition: StringMap.h:252
void operator=(const StringMap &RHS)
Definition: StringMap.h:258
unsigned getNumBuckets() const
Definition: StringMap.h:100
StringMapEntry< ValueTy > * operator->() const
Definition: StringMap.h:469
static StringMapEntry & GetStringMapEntryFromKeyData(const char *KeyData)
Definition: StringMap.h:209
StringMap(AllocatorTy A)
Definition: StringMap.h:245
size_type count(StringRef Key) const
Definition: StringMap.h:316
void Destroy(AllocatorTy &Allocator)
Definition: StringMap.h:217
size_t size_type
Definition: StringMap.h:273
void swap(StringMapImpl &Other)
Definition: StringMap.h:106
StringMapConstIterator< ValueTy > const_iterator
Definition: StringMap.h:275
StringMapIterator< ValueTy > iterator
Definition: StringMap.h:276
StringMapConstIterator operator++(int)
Definition: StringMap.h:447
MapEntryTy & GetOrCreateValue(StringRef Key)
Definition: StringMap.h:383
iterator begin() const
Definition: StringRef.h:97
bool operator==(const StringMapConstIterator &RHS) const
Definition: StringMap.h:435
unsigned NumItems
Definition: StringMap.h:60
StringMapEntryBase ** TheTable
Definition: StringMap.h:58
StringMapEntry(unsigned strLen)
Definition: StringMap.h:123
StringMapEntry< ValueTy > MapEntryTy
Definition: StringMap.h:239
void erase(iterator I)
Definition: StringMap.h:393
void free(void *ptr);
unsigned size() const
Definition: StringMap.h:104
ReferenceAdder< const AllocatorTy >::result AllocatorCRefTy
Definition: StringMap.h:266
const_iterator end() const
Definition: StringMap.h:287
void Destroy()
Destroy this object, releasing memory back to the malloc allocator.
Definition: StringMap.h:224
StringMapEntry(unsigned strLen, const ValueTy &V)
Definition: StringMap.h:125
const char * key_type
Definition: StringMap.h:270
StringMap(unsigned InitialSize)
Definition: StringMap.h:242
const_iterator begin() const
Definition: StringMap.h:284
StringMapConstIterator(StringMapEntryBase **Bucket, bool NoAdvance=false)
Definition: StringMap.h:422
bool erase(StringRef Key)
Definition: StringMap.h:399
ValueTy lookup(StringRef Key) const
Definition: StringMap.h:305
unsigned ItemSize
Definition: StringMap.h:62
void RemoveKey(StringMapEntryBase *V)
Definition: StringMap.cpp:158
StringMapEntry< ValueTy > value_type
Definition: StringMap.h:272
static StringMapEntry * Create(const char *KeyStart, const char *KeyEnd, AllocatorTy &Allocator, InitType InitVal)
Definition: StringMap.h:147
const char * getKeyData() const
Definition: StringMap.h:140
static StringMapEntryBase * getTombstoneVal()
Definition: StringMap.h:96
bool insert(MapEntryTy *KeyValue)
Definition: StringMap.h:323
unsigned NumBuckets
Definition: StringMap.h:59
#define LLVM_DELETED_FUNCTION
Definition: Compiler.h:137
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:591
StringMapConstIterator & operator++()
Definition: StringMap.h:442
StringRef getKey() const
Definition: StringMap.h:128
ValueTy & getValue()
Definition: StringMap.h:133
StringMap(unsigned InitialSize, AllocatorTy A)
Definition: StringMap.h:248
MapEntryTy & GetOrCreateValue(StringRef Key, InitTy Val)
Definition: StringMap.h:361
static void Initialize(StringMapEntry< ValueTy > &T, InitTy InitVal)
Definition: StringMap.h:36
ValueTy mapped_type
Definition: StringMap.h:271
iterator begin()
Definition: StringMap.h:278
StringMapEntry< ValueTy > & operator*() const
Definition: StringMap.h:466
const value_type * operator->() const
Definition: StringMap.h:431
static StringMapEntry * Create(const char *KeyStart, const char *KeyEnd, AllocatorTy &Allocator)
Definition: StringMap.h:177
#define I(x, y, z)
Definition: MD5.cpp:54
unsigned getKeyLength() const
Definition: StringMap.h:48
static StringMapEntry & GetStringMapEntryFromValue(ValueTy &V)
Definition: StringMap.h:196
unsigned NumTombstones
Definition: StringMap.h:61
const value_type & operator*() const
Definition: StringMap.h:428
StringMapEntryBase - Shared base class of StringMapEntry instances.
Definition: StringMap.h:43
iterator end() const
Definition: StringRef.h:99
AllocatorRefTy getAllocator()
Definition: StringMap.h:267
ValueTy & operator[](StringRef Key)
Definition: StringMap.h:312
ReferenceAdder< AllocatorTy >::result AllocatorRefTy
Definition: StringMap.h:265
static StringMapEntry * Create(const char *KeyStart, const char *KeyEnd, InitType InitVal)
Create - Create a StringMapEntry with normal malloc/free.
Definition: StringMap.h:184
iterator end()
Definition: StringMap.h:281