pooledstring.h

Go to the documentation of this file.
00001 
00002 #if !defined(INCLUDED_POOLEDSTRING_H)
00003 #define INCLUDED_POOLEDSTRING_H
00004 
00005 #include <map>
00006 #include "generic/static.h"
00007 #include "string/string.h"
00008 #include "container/hashtable.h"
00009 #include "container/hashfunc.h"
00010 
00012 class StringPool : public HashTable<char*, std::size_t, RawStringHash, RawStringEqual> {
00013 };
00014 
00015 inline void StringPool_analyse(StringPool& pool) {
00016     typedef std::multimap<std::size_t, const char*> Ordered;
00017     Ordered ordered;
00018     std::size_t total = 0;
00019     std::size_t pooled = 0;
00020     for (StringPool::iterator i = pool.begin(); i != pool.end(); ++i) {
00021         std::size_t size =  string_length((*i).key) + 1;
00022         total += size * (*i).value;
00023         pooled += size + 20;
00024         ordered.insert(Ordered::value_type((*i).value, (*i).key));
00025     }
00026     globalOutputStream() << "total: " << Unsigned(total) << " pooled:" << Unsigned(pooled) << "\n";
00027     for (Ordered::iterator i = ordered.begin(); i != ordered.end(); ++i) {
00028         globalOutputStream() << (*i).second << " " << Unsigned((*i).first) << "\n";
00029     }
00030 }
00031 
00032 
00036 template<typename PoolContext>
00037 class PooledString {
00038     StringPool::iterator m_i;
00039     static StringPool::iterator increment(StringPool::iterator i) {
00040         ++(*i).value;
00041         return i;
00042     }
00043     static StringPool::iterator insert(const char* string) {
00044         StringPool::iterator i = PoolContext::instance().find(const_cast<char*>(string));
00045         if (i == PoolContext::instance().end()) {
00046             return PoolContext::instance().insert(string_clone(string), 1);
00047         }
00048         return increment(i);
00049     }
00050     static void erase(StringPool::iterator i) {
00051         if (--(*i).value == 0) {
00052             char* string = (*i).key;
00053             PoolContext::instance().erase(i);
00054             string_release(string, string_length(string));
00055         }
00056     }
00057 public:
00058     PooledString() : m_i(insert("")) {
00059     }
00060     PooledString(const PooledString& other) : m_i(increment(other.m_i)) {
00061     }
00062     PooledString(const char* string) : m_i(insert(string)) {
00063     }
00064     ~PooledString() {
00065         erase(m_i);
00066     }
00067     PooledString& operator=(const PooledString& other) {
00068         PooledString tmp(other);
00069         tmp.swap(*this);
00070         return *this;
00071     }
00072     PooledString& operator=(const char* string) {
00073         PooledString tmp(string);
00074         tmp.swap(*this);
00075         return *this;
00076     }
00077     void swap(PooledString& other) {
00078         std::swap(m_i, other.m_i);
00079     }
00080     bool operator==(const PooledString& other) const {
00081         return m_i == other.m_i;
00082     }
00083     const char* c_str() const {
00084         return (*m_i).key;
00085     }
00086 };
00087 
00088 
00089 #endif

Generated by  doxygen 1.6.2