00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __STRINGPOOL_HPP
00023 #define __STRINGPOOL_HPP
00024
00025 #include <xqilla/framework/XQillaExport.hpp>
00026 #include <xercesc/framework/MemoryManager.hpp>
00027 #include <memory>
00028 #include <string>
00029
00030 class XQILLA_API StringPool
00031 {
00032 public:
00033 StringPool(XERCES_CPP_NAMESPACE_QUALIFIER MemoryManager *mm);
00034 ~StringPool();
00035
00037 const XMLCh* getPooledString(const XMLCh *src);
00039 const XMLCh* getPooledString(const XMLCh *src, unsigned int length);
00041 const XMLCh* getPooledString(const char *src);
00042
00043 unsigned int getCount() const { return _count; }
00044 unsigned int getHits() const { return _hits; }
00045 unsigned int getMisses() const { return _misses; }
00046 unsigned int getTooBig() const { return _toobig; }
00047 void dumpStatistics() const;
00048
00049 private:
00050 StringPool(const StringPool&);
00051 StringPool &operator=(const StringPool&);
00052
00053 static unsigned int hash(const XMLCh *v, unsigned int length);
00054 const XMLCh *replicate(const XMLCh *v, unsigned int length) const;
00055 void resize();
00056
00057 class Bucket
00058 {
00059 public:
00060 Bucket(const XMLCh *v, unsigned int l, unsigned int h, Bucket *n)
00061 : value(v), length(l), hashValue(h), next(n) {}
00062
00063 const XMLCh *value;
00064 unsigned int length;
00065 unsigned int hashValue;
00066 Bucket *next;
00067 };
00068
00069 XERCES_CPP_NAMESPACE_QUALIFIER MemoryManager *_mm;
00070 Bucket **_bucketList;
00071 unsigned int _modulus;
00072 unsigned int _count;
00073 unsigned int _hits;
00074 unsigned int _misses;
00075 unsigned int _toobig;
00076 };
00077
00078 inline unsigned int StringPool::hash(const XMLCh *v, unsigned int length)
00079 {
00080 unsigned int hashVal = 0;
00081 while(length) {
00082 hashVal += (hashVal * 37) + (hashVal >> 24) + (unsigned int)(*v);
00083 ++v;
00084 --length;
00085 }
00086 return hashVal;
00087 }
00088
00089 inline const XMLCh *StringPool::replicate(const XMLCh *v, unsigned int length) const
00090 {
00091 unsigned int size = length * sizeof(XMLCh);
00092 XMLCh *ret = (XMLCh*)_mm->allocate(size + sizeof(XMLCh));
00093 memcpy(ret, v, size);
00094 ret[length] = 0;
00095 return ret;
00096 }
00097
00098 #endif