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