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 #include <cstring>
00030
00031 class XQILLA_API StringPool
00032 {
00033 public:
00034 StringPool(XERCES_CPP_NAMESPACE_QUALIFIER MemoryManager *mm);
00035 ~StringPool();
00036
00038 const XMLCh* getPooledString(const XMLCh *src);
00040 const XMLCh* getPooledString(const XMLCh *src, unsigned int length);
00042 const XMLCh* getPooledString(const char *src);
00043
00044 unsigned int getCount() const { return _count; }
00045 unsigned int getHits() const { return _hits; }
00046 unsigned int getMisses() const { return _misses; }
00047 unsigned int getTooBig() const { return _toobig; }
00048 void dumpStatistics() const;
00049
00050 private:
00051 StringPool(const StringPool&);
00052 StringPool &operator=(const StringPool&);
00053
00054 static unsigned int hash(const XMLCh *v, unsigned int length);
00055 const XMLCh *replicate(const XMLCh *v, unsigned int length) const;
00056 void resize();
00057
00058 class Bucket
00059 {
00060 public:
00061 Bucket(const XMLCh *v, unsigned int l, unsigned int h, Bucket *n)
00062 : value(v), length(l), hashValue(h), next(n) {}
00063
00064 const XMLCh *value;
00065 unsigned int length;
00066 unsigned int hashValue;
00067 Bucket *next;
00068 };
00069
00070 XERCES_CPP_NAMESPACE_QUALIFIER MemoryManager *_mm;
00071 Bucket **_bucketList;
00072 unsigned int _modulus;
00073 unsigned int _count;
00074 unsigned int _hits;
00075 unsigned int _misses;
00076 unsigned int _toobig;
00077 };
00078
00079 inline unsigned int StringPool::hash(const XMLCh *v, unsigned int length)
00080 {
00081 unsigned int hashVal = 0;
00082 while(length) {
00083 hashVal += (hashVal * 37) + (hashVal >> 24) + (unsigned int)(*v);
00084 ++v;
00085 --length;
00086 }
00087 return hashVal;
00088 }
00089
00090 inline const XMLCh *StringPool::replicate(const XMLCh *v, unsigned int length) const
00091 {
00092 unsigned int size = length * sizeof(XMLCh);
00093 XMLCh *ret = (XMLCh*)_mm->allocate(size + sizeof(XMLCh));
00094 memcpy(ret, v, size);
00095 ret[length] = 0;
00096 return ret;
00097 }
00098
00099 #endif