1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 ***************************************************************************/
18 #include<CatalogTables.h>
22 #include<PredicateImpl.h>
23 DbRetVal
TupleIterator::open()
25 PredicateImpl
*predImpl
= (PredicateImpl
*) pred_
;
26 if (fullTableScan
== scanType_
)
28 cIter
= new ChunkIterator();
29 *cIter
= ((Chunk
*)chunkPtr_
)->getIterator();
30 }else if (hashIndexScan
== scanType_
)
32 HashIndexInfo
*hIdxInfo
= (HashIndexInfo
*)info
;
34 FieldIterator iter
= hIdxInfo
->idxFldList
.getIterator();
36 int offset
= hIdxInfo
->fldOffset
;
37 keyBuffer
= (char*) malloc(hIdxInfo
->compLength
);
38 void *keyStartBuffer
= (void*) keyBuffer
, *keyPtr
;
39 while(iter
.hasElement())
41 FieldDef
*def
= iter
.nextElement();
42 keyPtr
= (void*)predImpl
->valPtrForIndexField(def
->fldName_
);
43 AllDataType::copyVal(keyBuffer
, keyPtr
, def
->type_
, def
->length_
);
44 keyBuffer
= keyBuffer
+ def
->length_
;
47 if (hIdxInfo
->type
== typeComposite
)
48 bucketNo
= HashIndex::computeHashBucket(hIdxInfo
->type
,
49 (char *)keyStartBuffer
, hIdxInfo
->noOfBuckets
, hIdxInfo
->compLength
);
50 else bucketNo
= HashIndex::computeHashBucket(hIdxInfo
->type
,
51 keyStartBuffer
, hIdxInfo
->noOfBuckets
, hIdxInfo
->compLength
);
53 Bucket
*bucket
= &(hIdxInfo
->buckets
[bucketNo
]);
54 int ret
= bucket
->mutex_
.getLock(procSlot
);
57 printError(ErrLockTimeOut
,"Unable to acquire bucket Mutex for bucket %d",bucketNo
);
58 return ErrLockTimeOut
;
60 HashIndexNode
*head
= (HashIndexNode
*) bucket
->bucketList_
;
63 bucket
->mutex_
.releaseLock(procSlot
);
67 printDebug(DM_HashIndex
, "open:head for bucket %x is :%x", bucket
, head
);
68 bIter
= new BucketIter(head
);
69 bucket
->mutex_
.releaseLock(procSlot
);
70 }else if (treeIndexScan
== scanType_
)
72 HashIndexInfo
*hIdxInfo
= (HashIndexInfo
*)info
;
74 FieldIterator iter
= hIdxInfo
->idxFldList
.getIterator();
75 void *keyPtr
; ComparisionOp op
;
78 FieldDef
*def
= iter
.nextElement();
79 keyPtr
= (void*)predImpl
->valPtrForIndexField(def
->fldName_
);
80 op
= predImpl
->opForIndexField(def
->fldName_
);
81 //TODO::remove this predicate term as it is pushed to tree iter
83 CINDEX
*iptr
= (CINDEX
*) hIdxInfo
->indexPtr
;
84 tIter
= new TreeIter((TreeNode
*)iptr
->hashNodeChunk_
);
85 tIter
->setSearchKey(keyPtr
, op
);
86 tIter
->setFldOffset(hIdxInfo
->fldOffset
);
87 tIter
->setTypeLength(hIdxInfo
->type
, hIdxInfo
->compLength
);
89 if(predImpl
) predImpl
->setIfNoLeftRight();
93 //not returing previous tuple for all iterators and for tree iterator.
94 //it just decrements the nodeOffset for tree iterator.
95 void* TupleIterator::prev()
97 PredicateImpl
*predImpl
= (PredicateImpl
*) pred_
;
99 if (treeIndexScan
== scanType_
)
101 if (NULL
== tIter
) return NULL
;
102 tuple
= tIter
->prev();
103 predImpl
->setTuple(tuple
);
105 printDebug(DM_HashIndex
, "prev::tuple is null");
107 //TODO::evaluate as it is done in next() before returning
112 void* TupleIterator::next()
114 PredicateImpl
*predImpl
= (PredicateImpl
*) pred_
;
117 if (fullTableScan
== scanType_
)
123 return cIter
->nextElement();
128 void *val
= predImpl
->getValIfPointLookupOnInt(offset
);
133 tup
= (char*)cIter
->nextElement();
134 if(NULL
== tup
) return NULL
;
135 if (*(int*)val
== *((int*)(tup
+offset
))) break;
139 val
= predImpl
->getVal1IfBetweenOnInt(offset
);
141 void *val2
= predImpl
->getVal2IfBetweenOnInt(offset
);
144 tup
= (char*)cIter
->nextElement();
145 if(NULL
== tup
) return NULL
;
146 if (*((int*)(tup
+offset
)) >= *(int*)val
&&
147 *((int*)(tup
+offset
)) <= *(int*)val2
) break;
152 //evaluate till it succeeds
156 tuple
= cIter
->nextElement();
157 if(NULL
== tuple
) return NULL
;
158 //predImpl->setTuple(tuple);
159 printDebug(DM_Table
, "Evaluating the predicate from fullTableScan");
160 predImpl
->evaluateForTable(result
, (char*)tuple
);
163 }else if (hashIndexScan
== scanType_
)
167 //if there are no nodes in bucket bIter will be null
170 //evaluate till it succeeds
174 HashIndexNode
*node
= bIter
->next();
175 if (node
== NULL
) return NULL
;
176 printDebug(DM_HashIndex
, "next: returned HashIndexNode: %x", node
);
177 tuple
= node
->ptrToTuple_
;
179 printDebug(DM_HashIndex
, "next::tuple is null");
183 //if (!predImpl->isSingleTerm()) {
184 printDebug(DM_HashIndex
, "next: predicate has more than single term");
185 //predImpl->setTuple(tuple);
186 printDebug(DM_Table
, "Evaluating the predicate from hashIndexScan: has more than one term");
187 predImpl
->evaluateForTable(result
, (char*)tuple
);
193 }else if (treeIndexScan
== scanType_
)
195 if (NULL
== tIter
) return NULL
;
199 tuple
= tIter
->next();
201 printDebug(DM_HashIndex
, "next::tuple is null");
204 //predImpl->setTuple(tuple);
205 predImpl
->evaluateForTable(result
, (char*)tuple
);
206 if(!result
&& (isBetInvolved() || isPointLookInvolved())) tIter
->nextNode();
212 DbRetVal
TupleIterator::close()
214 if (scanType_
== fullTableScan
)
218 } else if (scanType_
== hashIndexScan
)
222 } else if (scanType_
== treeIndexScan
)
228 scanType_
= unknownScan
;
232 void TupleIterator::reset()
235 if (scanType_
== fullTableScan
) *cIter
= ((Chunk
*)chunkPtr_
)->getIterator();
236 else if (scanType_
== hashIndexScan
) if(bIter
) bIter
->reset();
237 else if (scanType_
== treeIndexScan
) if(tIter
) tIter
->reset();