00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00019
00020 #ifndef NET_INSTAWEB_UTIL_PUBLIC_SYMBOL_TABLE_H_
00021 #define NET_INSTAWEB_UTIL_PUBLIC_SYMBOL_TABLE_H_
00022
00023 #include <cstddef>
00024 #include <vector>
00025
00026 #ifdef __GNUC__
00027 #define SYMBOL_TABLE_USE_HASH_TABLE 1
00028 #else
00029 #define SYMBOL_TABLE_USE_HASH_TABLE 0
00030 #endif
00031
00032 #if SYMBOL_TABLE_USE_HASH_TABLE
00033
00048
00049 #ifndef _BACKWARD_BACKWARD_WARNING_H
00050 #define NEED_UNDEF
00051 #define _BACKWARD_BACKWARD_WARNING_H
00052 #endif
00053 #include <ext/hash_set>
00054 #ifdef NEED_UNDEF
00055 #undef NEED_UNDEF
00056 #undef _BACKWARD_BACKWARD_WARNING_H
00057 #endif
00058
00059 #else
00060 #include <set>
00061 #endif
00062
00063 #include "net/instaweb/util/public/basictypes.h"
00064 #include "net/instaweb/util/public/atom.h"
00065 #include "net/instaweb/util/public/string_hash.h"
00066 #include "net/instaweb/util/public/string_util.h"
00067
00068 namespace net_instaweb {
00069
00088 template<class CharTransform> class SymbolTable {
00089 public:
00090 SymbolTable();
00091 ~SymbolTable() { Clear(); }
00092
00095 void Clear();
00096
00098 Atom Intern(const StringPiece& src);
00099
00102 size_t string_bytes_allocated() const { return string_bytes_allocated_; }
00103
00104 private:
00105 #if SYMBOL_TABLE_USE_HASH_TABLE
00106
00107 struct Comparator {
00108 bool operator()(const StringPiece& key_a, const StringPiece& key_b) const {
00109 if (key_a.length() == key_b.length()) {
00110 const char* a = key_a.data();
00111 const char* b = key_b.data();
00112 const char* a_end = a + key_a.length();
00113 while (a < a_end) {
00114 if (CharTransform::Normalize(*a) != CharTransform::Normalize(*b)) {
00115 return false;
00116 }
00117 ++a;
00118 ++b;
00119 }
00120 return true;
00121 } else {
00122 return false;
00123 }
00124 }
00125 };
00126
00127 struct Hash {
00128 size_t operator()(const StringPiece& key) const {
00129 return HashString<CharTransform, size_t>(key.data(), key.length());
00130 }
00131 };
00132
00133 typedef __gnu_cxx::hash_set<StringPiece, Hash, Comparator> SymbolSet;
00134 #else
00135 struct Compare {
00136 bool operator()(const StringPiece& a, const StringPiece& b) const {
00137 return CharTransform::Compare(a, b);
00138 }
00139 };
00140
00141 typedef std::set<StringPiece, Compare> SymbolSet;
00142 #endif
00143 SymbolSet string_set_;
00144
00146 inline void NewStorage();
00147
00162 std::vector<char*> storage_;
00163 char* next_ptr_;
00164 size_t string_bytes_allocated_;
00165
00166 DISALLOW_COPY_AND_ASSIGN(SymbolTable);
00167 };
00168
00169 typedef SymbolTable<CaseFold> SymbolTableInsensitive;
00170 typedef SymbolTable<CasePreserve> SymbolTableSensitive;
00171
00172 }
00173
00174 #endif ///< NET_INSTAWEB_UTIL_PUBLIC_SYMBOL_TABLE_H_