LLVM API Documentation

StringPool.h

Go to the documentation of this file.
00001 //===-- StringPool.h - Interned string pool -------------------------------===//
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 declares an interned string pool, which helps reduce the cost of
00011 // strings by using the same storage for identical strings.
00012 // 
00013 // To intern a string:
00014 // 
00015 //   StringPool Pool;
00016 //   PooledStringPtr Str = Pool.intern("wakka wakka");
00017 // 
00018 // To use the value of an interned string, use operator bool and operator*:
00019 // 
00020 //   if (Str)
00021 //     cerr << "the string is" << *Str << "\n";
00022 // 
00023 // Pooled strings are immutable, but you can change a PooledStringPtr to point
00024 // to another instance. So that interned strings can eventually be freed,
00025 // strings in the string pool are reference-counted (automatically).
00026 // 
00027 //===----------------------------------------------------------------------===//
00028 
00029 #ifndef LLVM_SUPPORT_STRINGPOOL_H
00030 #define LLVM_SUPPORT_STRINGPOOL_H
00031 
00032 #include "llvm/ADT/StringMap.h"
00033 #include <new>
00034 #include <cassert>
00035 
00036 namespace llvm {
00037 
00038   class PooledStringPtr;
00039 
00040   /// StringPool - An interned string pool. Use the intern method to add a
00041   /// string. Strings are removed automatically as PooledStringPtrs are
00042   /// destroyed.
00043   class StringPool {
00044     /// PooledString - This is the value of an entry in the pool's interning
00045     /// table.
00046     struct PooledString {
00047       StringPool *Pool;  ///< So the string can remove itself.
00048       unsigned Refcount; ///< Number of referencing PooledStringPtrs.
00049       
00050     public:
00051       PooledString() : Pool(0), Refcount(0) { }
00052     };
00053     
00054     friend class PooledStringPtr;
00055     
00056     typedef StringMap<PooledString> table_t;
00057     typedef StringMapEntry<PooledString> entry_t;
00058     table_t InternTable;
00059     
00060   public:
00061     StringPool();
00062     ~StringPool();
00063     
00064     /// intern - Adds a string to the pool and returns a reference-counted
00065     /// pointer to it. No additional memory is allocated if the string already
00066     /// exists in the pool.
00067     PooledStringPtr intern(const char *Begin, const char *End);
00068     
00069     /// intern - Adds a null-terminated string to the pool and returns a
00070     /// reference-counted pointer to it. No additional memory is allocated if
00071     /// the string already exists in the pool.
00072     inline PooledStringPtr intern(const char *Str);
00073     
00074     /// empty - Checks whether the pool is empty. Returns true if so.
00075     /// 
00076     inline bool empty() const { return InternTable.empty(); }
00077   };
00078   
00079   /// PooledStringPtr - A pointer to an interned string. Use operator bool to
00080   /// test whether the pointer is valid, and operator * to get the string if so.
00081   /// This is a lightweight value class with storage requirements equivalent to
00082   /// a single pointer, but it does have reference-counting overhead when
00083   /// copied.
00084   class PooledStringPtr {
00085     typedef StringPool::entry_t entry_t;
00086     entry_t *S;
00087     
00088   public:
00089     PooledStringPtr() : S(0) {}
00090     
00091     explicit PooledStringPtr(entry_t *E) : S(E) {
00092       if (S) ++S->getValue().Refcount;
00093     }
00094     
00095     PooledStringPtr(const PooledStringPtr &That) : S(That.S) {
00096       if (S) ++S->getValue().Refcount;
00097     }
00098     
00099     PooledStringPtr &operator=(const PooledStringPtr &That) {
00100       if (S != That.S) {
00101         clear();
00102         S = That.S;
00103         if (S) ++S->getValue().Refcount;
00104       }
00105       return *this;
00106     }
00107     
00108     void clear() {
00109       if (!S)
00110         return;
00111       if (--S->getValue().Refcount == 0) {
00112         S->getValue().Pool->InternTable.remove(S);
00113         S->Destroy();
00114       }
00115       S = 0;
00116     }
00117     
00118     ~PooledStringPtr() { clear(); }
00119     
00120     inline const char *begin() const {
00121       assert(*this && "Attempt to dereference empty PooledStringPtr!");
00122       return S->getKeyData();
00123     }
00124     
00125     inline const char *end() const {
00126       assert(*this && "Attempt to dereference empty PooledStringPtr!");
00127       return S->getKeyData() + S->getKeyLength();
00128     }
00129     
00130     inline unsigned size() const {
00131       assert(*this && "Attempt to dereference empty PooledStringPtr!");
00132       return S->getKeyLength();
00133     }
00134     
00135     inline const char *operator*() const { return begin(); }
00136     inline operator bool() const { return S != 0; }
00137     
00138     inline bool operator==(const PooledStringPtr &That) { return S == That.S; }
00139     inline bool operator!=(const PooledStringPtr &That) { return S != That.S; }
00140   };
00141   
00142   PooledStringPtr StringPool::intern(const char *Str) {
00143     return intern(Str, Str + strlen(Str));
00144   }
00145 
00146 } // End llvm namespace
00147 
00148 #endif



This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.