![]() |
Public API Reference |
![]() |
00001 /* 00002 Copyright (C) 2001 by Martin Geisse <mgeisse@gmx.net> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public 00015 License along with this library; if not, write to the Free 00016 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00017 */ 00018 00019 #ifndef __CS_STRSET_H__ 00020 #define __CS_STRSET_H__ 00021 00022 #include "csextern.h" 00023 #include "csutil/strhash.h" 00024 00029 namespace CS 00030 { 00031 namespace Utility 00032 { 00047 template<typename Tag, bool Locked = false> 00048 class StringSet 00049 { 00050 private: 00051 typedef CS::Threading::OptionalMutex<Locked> MutexType; 00052 StringHash<Tag> registry; 00053 csHash<const char*, CS::StringID<Tag> > reverse; // ID to string mapping. 00054 /* Inherit from OptionalMutex<> to avoid spending extra memory if locking 00055 is disabled */ 00056 struct LockAndId : public MutexType 00057 { 00058 unsigned int next_id; 00059 00060 LockAndId() : next_id (0) {} 00061 }; 00062 mutable LockAndId lockAndId; 00063 00064 void Copy(StringSet const& s) 00065 { 00066 if (&s != this) 00067 { 00068 CS::Threading::ScopedLock<MutexType> l1 (lockAndId); 00069 CS::Threading::ScopedLock<MutexType> l2 (s.lockAndId); 00070 registry = s.registry; 00071 reverse = s.reverse; 00072 lockAndId.next_id = s.lockAndId.next_id; 00073 } 00074 } 00075 00076 public: 00077 typedef csStringHash::GlobalIterator GlobalIterator; 00078 00079 public: 00081 StringSet (size_t size = 23) : registry(size), reverse(size) {} 00083 StringSet (StringSet const& s) { Copy(s); } 00085 ~StringSet () {} 00087 StringSet& operator=(StringSet const& s) { Copy(s); return *this; } 00088 00095 CS::StringID<Tag> Request (const char* s) 00096 { 00097 CS::Threading::ScopedLock<MutexType> lock (lockAndId); 00098 CS::StringID<Tag> id = registry.Request(s); 00099 if (id == CS::InvalidStringID<Tag> ()) 00100 { 00101 const char* t = registry.Register(s, lockAndId.next_id); 00102 id = lockAndId.next_id++; 00103 reverse.Put (id, t); 00104 } 00105 return id; 00106 } 00107 00113 char const* Request (CS::StringID<Tag> id) const 00114 { 00115 CS::Threading::ScopedLock<MutexType> lock (lockAndId); 00116 return reverse.Get(id, 0); 00117 } 00118 00122 bool Contains(char const* s) const 00123 { 00124 CS::Threading::ScopedLock<MutexType> lock (lockAndId); 00125 return registry.Request(s) != CS::InvalidStringID<Tag> (); 00126 } 00127 00133 bool Contains(CS::StringID<Tag> id) const 00134 { 00135 CS::Threading::ScopedLock<MutexType> lock (lockAndId); 00136 return Request(id) != 0; 00137 } 00138 00143 bool Delete(char const* s) 00144 { 00145 CS::Threading::ScopedLock<MutexType> lock (lockAndId); 00146 CS::StringID<Tag> const id = registry.Request(s); 00147 bool const ok = (id != csInvalidStringID); 00148 if (ok) 00149 { 00150 registry.Delete(s); 00151 reverse.DeleteAll(id); 00152 } 00153 return ok; 00154 } 00155 00160 bool Delete(CS::StringID<Tag> id) 00161 { 00162 CS::Threading::ScopedLock<MutexType> lock (lockAndId); 00163 char const* s = reverse.Get(id,0); 00164 bool const ok = (s != 0); 00165 if (ok) 00166 { 00167 registry.Delete(s); 00168 reverse.DeleteAll(id); 00169 } 00170 return ok; 00171 } 00172 00177 void Empty () 00178 { 00179 CS::Threading::ScopedLock<MutexType> lock (lockAndId); 00180 registry.Empty(); 00181 reverse.Empty(); 00182 } 00183 00188 CS_DEPRECATED_METHOD_MSG("Use Empty() instead.") 00189 void Clear () 00190 { Empty(); } 00191 00193 size_t GetSize () const 00194 { 00195 CS::Threading::ScopedLock<MutexType> lock (lockAndId); 00196 return registry.GetSize (); 00197 } 00198 00204 bool IsEmpty() const 00205 { 00206 CS::Threading::ScopedLock<MutexType> lock (lockAndId); 00207 return GetSize() == 0; 00208 } 00209 00216 GlobalIterator GetIterator () const 00217 { return registry.GetIterator(); } 00218 }; 00219 } // namespace Utility 00220 } // namespace CS 00221 00222 typedef CS::Utility::StringSet<CS::StringSetTag::General> csStringSet; 00223 00224 #endif // __CS_STRSET_H__