1 /*
2  * Copyright 2006-2008 The FLWOR Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef ZORBA_SIMPLE_STORE_QNAME_POOL
17 #define ZORBA_SIMPLE_STORE_QNAME_POOL
18 
19 #include <vector>
20 
21 #include "zorbautils/hashfun.h"
22 #include "zorbautils/hashset.h"
23 
24 #include "common/shared_types.h"
25 #include "common/common.h"
26 
27 #include "atomic_items.h"
28 
29 namespace zorba { namespace simplestore {
30 
31 class StringPool;
32 
33 /*******************************************************************************
34 
35   theCache :
36   ----------
37   An array of QName slots that is managed as a cache. This means that slots that
38   are not used are placed in a free list. When a new qname is inserted in the
39   cache, a slot is taken from the free list and the qname currently in that slot
40   is replaced with the new slot.
41 
42   theCacheSize :
43   --------------
44   The size of theCache (number of slots). This size is given as a param to the
45   QNamePool constructor, and it never changes afterwards.
46 
47   theFirstFree :
48   --------------
49   The position in theCache of the 1st free slot. NOTE: the 1st slot of theCache
50   (at position 0) is reserved (i.e., never used) so that position 0 can be used
51   to indicate the end of the free list.
52 
53   theNumFree :
54   ------------
55   Number of free slots in theCache.
56 
57   theHashSet :
58   ------------
59   A hash set mapping qnames (i.e. triplets of strings) to QName slots.
60 
61 ********************************************************************************/
62 class QNamePool
63 {
64 protected:
65 
66   class CompareFunction
67   {
68   public:
equal(const QNameItem * t1,const QNameItem * t2)69     static bool equal(const QNameItem* t1, const QNameItem* t2)
70     {
71       return (t1->getLocalName() == t2->getLocalName() &&
72               t1->getNamespace() == t2->getNamespace() &&
73               t1->getPrefix() == t2->getPrefix());
74     }
75 
hash(const QNameItem * t)76     static uint32_t hash(const QNameItem* t)
77     {
78       return  hashfun::h32(t->getPrefix().c_str(),
79                            hashfun::h32(t->getLocalName().c_str(),
80                                         hashfun::h32(t->getNamespace().c_str())));
81     }
82   };
83 
84 
85   class QNamePoolHashSet : public HashSet<QNameItem*, CompareFunction>
86   {
87     friend class QNamePool;
88 
89   public:
QNamePoolHashSet(ulong size)90     QNamePoolHashSet(ulong size)
91       :
92       HashSet<QNameItem*, CompareFunction>(size, true)
93     {
94     }
95   };
96 
97 
98  typedef HashEntry<QNameItem*, DummyHashValue> QNHashEntry;
99 
100 public:
101   static const ulong MAX_CACHE_SIZE = 32768;
102 
103 protected:
104   QNameItem         * theCache;
105   ulong               theCacheSize;
106 	ulong               theFirstFree;
107   ulong               theNumFree;
108 
109   QNamePoolHashSet    theHashSet;
110 
111   StringPool        * theNamespacePool;
112 
113 public:
114   QNamePool(ulong size, StringPool* nspool);
115 
116   ~QNamePool();
117 
118   store::Item_t insert(const char* ns, const char* pre, const char* ln);
119 
120   store::Item_t insert(const zstring& ns, const zstring& pre, const zstring& ln);
121 
122   void remove(QNameItem* qn);
123 
124 protected:
125   QNameItem* cacheInsert(QNameItem*& normVictim);
126 
127   void cachePin(QNameItem* qn);
128 
129   QNHashEntry* hashFind(
130       const char* ns,
131       const char* pre,
132       const char* ln,
133       csize       nslen,
134       csize       prelen,
135       csize       lnlen,
136       csize       hval);
137 
138   void addInFreeList(QNameItem* qn);
139 
140   void removeFromFreeList(QNameItem* qn);
141 
142   QNameItem* popFreeList();
143 };
144 
145 
146 } // namespace store
147 } // namespace zorba
148 
149 #endif
150 /* vim:set et sw=2 ts=2: */
151