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_INDEX
17 #define ZORBA_SIMPLE_STORE_INDEX
18 
19 #include "store/api/shared_types.h"
20 #include "store/api/index.h"
21 #include "store/api/iterator.h"
22 
23 #include "shared_types.h"
24 
25 #include "zorbautils/hashmap.h"
26 
27 namespace zorba
28 {
29 
30 namespace simplestore
31 {
32 
33 class IndexPointConditionImpl;
34 class IndexBoxConditionImpl;
35 
36 
37 /******************************************************************************
38 
39 ********************************************************************************/
40 class IndexImpl : public store::Index
41 {
42 protected:
43   store::Item_t                   theQname;
44   store::IndexSpecification       theSpec;
45 
46 public:
47   IndexImpl(const store::Item_t& qname, const store::IndexSpecification& spec);
48 
49   IndexImpl();
50 
51 public:
52   virtual ~IndexImpl();
53 
54   //
55   // Store api methods
56   //
57 
getName()58   store::Item* getName() const { return theQname.getp(); }
59 
getSpecification()60   const store::IndexSpecification& getSpecification() const { return theSpec; }
61 
getNumColumns()62   csize getNumColumns() const { return theSpec.getNumColumns(); }
63 
getTimezone()64   long getTimezone() const { return theSpec.theTimezone; }
65 
getCollations()66   const std::vector<std::string>& getCollations() const { return theSpec.theCollations; }
67 
68   virtual csize size() const = 0;
69 
70   virtual KeyIterator_t keys() const = 0;
71 
72   virtual void clear() = 0;
73 
74   store::IndexCondition_t createCondition(store::IndexCondition::Kind k);
75 
76   //
77   // Simplestore methods
78   //
79 
isUnique()80   bool isUnique() const { return theSpec.theIsUnique; }
81 
isSorted()82   bool isSorted() const { return theSpec.theIsSorted; }
83 
isTemporary()84   bool isTemporary() const { return theSpec.theIsTemp; }
85 
isThreadSafe()86   bool isThreadSafe() const { return theSpec.theIsThreadSafe; }
87 
isGeneral()88   bool isGeneral() const { return theSpec.theIsGeneral; }
89 };
90 
91 
92 /*******************************************************************************
93 
94 ********************************************************************************/
95 class IndexConditionImpl : public store::IndexCondition
96 {
97   friend class ProbeValueTreeIndexIterator;
98   friend class ProbeValueHashIndexIterator;
99   friend class ProbeGeneralIndexIterator;
100   friend class ProbeGeneralHashIndexIterator;
101   friend class ProbeGeneralTreeIndexIterator;
102 
103 protected:
104   struct RangeFlags
105   {
106     bool  theHaveLowerBound;
107     bool  theHaveUpperBound;
108     bool  theLowerBoundIncl;
109     bool  theUpperBoundIncl;
110 
RangeFlagsRangeFlags111     RangeFlags()
112       :
113       theHaveLowerBound(false),
114       theHaveUpperBound(false),
115       theLowerBoundIncl(true),
116       theUpperBoundIncl(true)
117     {
118     }
119   };
120 
121 public:
122   static store::Item_t         theNegInf;
123   static store::Item_t         thePosInf;
124 
125 protected:
126   rchandle<IndexImpl>          theIndex;
127 
128   store::IndexCondition::Kind  theKind;
129 
130 public:
131   static std::string getKindString(store::IndexCondition::Kind k);
132 
133 public:
134   IndexConditionImpl(IndexImpl* idx, store::IndexCondition::Kind kind);
135 
getKind()136   store::IndexCondition::Kind getKind() const { return theKind; }
137 
getKindString()138   std::string getKindString() const { return getKindString(theKind); }
139 
140   virtual void pushItem(store::Item_t& item);
141 
142   virtual void pushRange(
143       store::Item_t& lower,
144       store::Item_t& upper,
145       bool haveLower,
146       bool haveUpper,
147       bool lowerIncl,
148       bool upperIncl);
149 
150   virtual void pushBound(store::Item_t& bound, bool isLower, bool boundIncl);
151 };
152 
153 
154 /*******************************************************************************
155   Repesents a search condition on a general index.
156 
157   theKind:
158   --------
159   The kind of the condition (one of POINT_VALUE, POINT_GENERAL, BOX_VALUE, or
160   BOX_GENERAL).
161 
162   theIsSet:
163   ---------
164   Set to true the 1st time one of the pushXXX methods is called and reset to
165   false by the clear() method. Used to check that the user is not trying to
166   push more than once.
167 
168   theKey:
169   ------------
170   The search key for the POINT conditions. It is non-NULL and points to an
171   atomic item.
172 
173   theRangeFlags:
174   --------------
175   Use only for the BOX conditions. Specifies the kind of operator and whether
176   the lower/upper bound is INFINITY or not.
177 
178   theLowerBound:
179   --------------
180   The search key that serves as the lower bound for the BOX conditions. If,
181   according to theRangeFlags, the bound is not -INFINITY, theLowerBound is
182   not NULL and points to an atomicitem; otherwise, the value of theLowerBound
183   is irrelevant (is not used).
184 
185   theUpperBound:
186   --------------
187   The search key that serves as the upper bound for the BOX conditions. If,
188   according to theRangeFlags, the bound is not +INFINITY, theUpperBound is
189   not NULL and points to an atomic item; otherwise, the value of theUpperBound
190   is irrelevant (is not used).
191 ********************************************************************************/
192 class GeneralIndexCondition : public IndexConditionImpl
193 {
194   friend class ProbeGeneralIndexIterator;
195   friend class ProbeGeneralHashIndexIterator;
196   friend class ProbeGeneralTreeIndexIterator;
197 
198   friend std::ostream& operator<<(std::ostream& os, const GeneralIndexCondition& c);
199 
200 protected:
201   bool                         theIsSet;
202 
203   AtomicItem_t                 theKey;
204 
205   RangeFlags                   theRangeFlags;
206   AtomicItem_t                 theLowerBound;
207   AtomicItem_t                 theUpperBound;
208 
209 public:
210   GeneralIndexCondition(IndexImpl* idx, store::IndexCondition::Kind);
211 
212   std::string toString() const;
213 
214   void clear();
215 
216   void pushItem(store::Item_t& item);
217 
218   void pushRange(
219       store::Item_t& lower,
220       store::Item_t& upper,
221       bool haveLower,
222       bool haveUpper,
223       bool lowerIncl,
224       bool upperIncl);
225 
226   void pushBound(store::Item_t& bound, bool isLower, bool boundIncl);
227 };
228 
229 
230 std::ostream& operator<<(std::ostream& os, const GeneralIndexCondition& cond);
231 
232 
233 /*******************************************************************************
234 
235 ********************************************************************************/
236 class IndexPointCondition : public IndexConditionImpl
237 {
238   friend class ProbeValueTreeIndexIterator;
239   friend class ProbeValueHashIndexIterator;
240   friend class ProbeGeneralHashIndexIterator;
241   friend class ProbeGeneralTreeIndexIterator;
242 
243 protected:
244   store::IndexKey theKey;
245 
246 public:
IndexPointCondition(IndexImpl * idx,store::IndexCondition::Kind kind)247   IndexPointCondition(IndexImpl* idx, store::IndexCondition::Kind kind)
248     :
249     IndexConditionImpl(idx, kind)
250   {
251   }
252 
getKey()253   const store::IndexKey& getKey() const { return theKey; }
254 
255   void clear();
256 
257   void pushItem(store::Item_t& item);
258 
259   bool test(const store::IndexKey& key) const;
260 
261   std::string toString() const;
262 };
263 
264 
265 std::ostream& operator<<(std::ostream& os, const IndexPointCondition& cond);
266 
267 
268 /*******************************************************************************
269   It represents a condition that is satisfied by the index keys inside a
270   user-specified "box".
271 
272   Let M be the number of key columns. Then, an M-dimensional box is defined as
273   a conjuction of M range conditions on columns 0 to M-1. Each range condition
274   specifies a range of acceptable values for some key column. Specifically, a
275   range is defined as the set of all key values K such that
276 
277   lower_bound <? K <? upper_bound, where <? is either the lt or the le operator.
278 
279   The lower bound may be -INFINITY and the upper bound may be +INFINTY.
280 ********************************************************************************/
281 class IndexBoxValueCondition : public IndexConditionImpl
282 {
283   friend class ValueTreeIndex;
284   friend class ProbeValueTreeIndexIterator;
285   friend class ProbeGeneralTreeIndexIterator;
286 
287   friend std::ostream& operator<<(std::ostream& os, const IndexBoxValueCondition& c);
288 
289 protected:
290   std::vector<RangeFlags>  theRangeFlags;
291   store::IndexKey          theLowerBounds;
292   store::IndexKey          theUpperBounds;
293 
294 public:
IndexBoxValueCondition(IndexImpl * idx,store::IndexCondition::Kind kind)295   IndexBoxValueCondition(IndexImpl* idx, store::IndexCondition::Kind kind)
296     :
297     IndexConditionImpl(idx, kind)
298   {
299   }
300 
numRanges()301   csize numRanges() const { return theLowerBounds.size(); }
302 
303   void clear();
304 
305   void pushRange(
306       store::Item_t& lower,
307       store::Item_t& upper,
308       bool haveLower,
309       bool haveUpper,
310       bool lowerIncl,
311       bool upperIncl);
312 
313   bool test(const store::IndexKey& key) const;
314 
315   std::string toString() const;
316 };
317 
318 
319 std::ostream& operator<<(std::ostream& os, const IndexBoxValueCondition& cond);
320 
321 
322 /**************************************************************************//**
323   A index delta is a set of [domain-node, associated-key(s)] pairs.
324 *******************************************************************************/
325 class IndexDeltaImpl : public store::IndexDelta
326 {
327 public:
328   typedef std::vector<store::IndexDelta::ValuePair>::iterator
329   ValueIterator;
330 
331   typedef std::vector<store::IndexDelta::ValuePair>::reverse_iterator
332   ReverseValueIterator;
333 
334   typedef std::vector<store::IndexDelta::GeneralPair>::iterator
335   GeneralIterator;
336 
337   typedef std::vector<store::IndexDelta::GeneralPair>::reverse_iterator
338   ReverseGeneralIterator;
339 
340 public:
IndexDeltaImpl()341   IndexDeltaImpl() { }
342 
getValueDelta()343   ValueDelta& getValueDelta() { return theValueDelta; }
344 
getGeneralDelta()345   GeneralDelta& getGeneralDelta() { return theGeneralDelta; }
346 };
347 
348 
349 }
350 }
351 
352 #endif
353 
354 /*
355  * Local variables:
356  * mode: c++
357  * End:
358  */
359 /* vim:set et sw=2 ts=2: */
360