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()
26 if (fullTableScan
== scanType_
)
28 cIter
= new ChunkIterator();
29 *cIter
= ((Chunk
*)chunkPtr_
)->getIterator();
30 }else if (hashIndexScan
== scanType_
)
32 HashIndexInfo
*hIdxInfo
= (HashIndexInfo
*)info
;
33 PredicateImpl
*predImpl
= (PredicateImpl
*) pred_
;
35 FieldIterator iter
= hIdxInfo
->idxFldList
.getIterator();
37 int offset
= hIdxInfo
->fldOffset
;
38 keyBuffer
= (char*) malloc(hIdxInfo
->compLength
);
39 void *keyStartBuffer
= (void*) keyBuffer
, *keyPtr
;
40 while(iter
.hasElement())
42 FieldDef def
= iter
.nextElement();
43 keyPtr
= (void*)predImpl
->valPtrForIndexField(def
.fldName_
);
44 AllDataType::copyVal(keyBuffer
, keyPtr
, def
.type_
, def
.length_
);
45 keyBuffer
= keyBuffer
+ AllDataType::size(def
.type_
, def
.length_
);
48 if (hIdxInfo
->type
== typeComposite
)
49 bucketNo
= HashIndex::computeHashBucket(hIdxInfo
->type
,
50 (char *)keyStartBuffer
, hIdxInfo
->noOfBuckets
, hIdxInfo
->compLength
);
51 else bucketNo
= HashIndex::computeHashBucket(hIdxInfo
->type
,
52 keyStartBuffer
, hIdxInfo
->noOfBuckets
, hIdxInfo
->compLength
);
54 Bucket
*bucket
= &(hIdxInfo
->buckets
[bucketNo
]);
55 int ret
= bucket
->mutex_
.getLock(procSlot
);
58 printError(ErrLockTimeOut
,"Unable to acquire bucket Mutex for bucket %d",bucketNo
);
59 return ErrLockTimeOut
;
61 HashIndexNode
*head
= (HashIndexNode
*) bucket
->bucketList_
;
64 bucket
->mutex_
.releaseLock(procSlot
);
68 printDebug(DM_HashIndex
, "open:head for bucket %x is :%x", bucket
, head
);
69 bIter
= new BucketIter(head
);
70 bucket
->mutex_
.releaseLock(procSlot
);
71 }else if (treeIndexScan
== scanType_
)
73 HashIndexInfo
*hIdxInfo
= (HashIndexInfo
*)info
;
74 PredicateImpl
*predImpl
= (PredicateImpl
*) pred_
;
76 FieldIterator iter
= hIdxInfo
->idxFldList
.getIterator();
77 void *keyPtr
; ComparisionOp op
;
80 FieldDef def
= iter
.nextElement();
81 keyPtr
= (void*)predImpl
->valPtrForIndexField(def
.fldName_
);
82 op
= predImpl
->opForIndexField(def
.fldName_
);
83 //TODO::remove this predicate term as it is pushed to tree iter
85 CINDEX
*iptr
= (CINDEX
*) hIdxInfo
->indexPtr
;
86 tIter
= new TreeIter((TreeNode
*)iptr
->hashNodeChunk_
);
87 tIter
->setSearchKey(keyPtr
, op
);
88 tIter
->setFldOffset(hIdxInfo
->fldOffset
);
89 tIter
->setTypeLength(hIdxInfo
->type
, hIdxInfo
->compLength
);
94 //not returing previous tuple for all iterators and for tree iterator.
95 //it just decrements the nodeOffset for tree iterator.
96 void* TupleIterator::prev()
98 PredicateImpl
*predImpl
= (PredicateImpl
*) pred_
;
100 if (treeIndexScan
== scanType_
)
102 if (NULL
== tIter
) return NULL
;
103 tuple
= tIter
->prev();
104 predImpl
->setTuple(tuple
);
106 printDebug(DM_HashIndex
, "prev::tuple is null");
112 void* TupleIterator::next()
114 PredicateImpl
*predImpl
= (PredicateImpl
*) pred_
;
117 if (fullTableScan
== scanType_
)
123 return cIter
->nextElement();
127 //evaluate till it succeeds
131 tuple
= cIter
->nextElement();
132 if(NULL
== tuple
) return NULL
;
133 predImpl
->setTuple(tuple
);
134 printDebug(DM_Table
, "Evaluating the predicate from fullTableScan");
135 rv
= predImpl
->evaluate(result
);
136 if (rv
!= OK
) return NULL
;
139 }else if (hashIndexScan
== scanType_
)
143 //if there are no nodes in bucket bIter will be null
146 //evaluate till it succeeds
150 HashIndexNode
*node
= bIter
->next();
151 if (node
== NULL
) return NULL
;
152 printDebug(DM_HashIndex
, "next: returned HashIndexNode: %x", node
);
153 tuple
= node
->ptrToTuple_
;
155 printDebug(DM_HashIndex
, "next::tuple is null");
159 //if (!predImpl->isSingleTerm()) {
160 printDebug(DM_HashIndex
, "next: predicate has more than single term");
161 predImpl
->setTuple(tuple
);
162 printDebug(DM_Table
, "Evaluating the predicate from hashIndexScan: has more than one term");
163 rv
= predImpl
->evaluate(result
);
164 if (rv
!= OK
) return NULL
;
170 }else if (treeIndexScan
== scanType_
)
172 if (NULL
== tIter
) return NULL
;
176 tuple
= tIter
->next();
178 printDebug(DM_HashIndex
, "next::tuple is null");
181 predImpl
->setTuple(tuple
);
182 rv
= predImpl
->evaluate(result
);
183 if (rv
!= OK
) return NULL
;
184 if(!result
&& (isBetInvolved() || isPointLookInvolved())) tIter
->nextNode();
190 DbRetVal
TupleIterator::close()
192 if (scanType_
== fullTableScan
)
196 } else if (scanType_
== hashIndexScan
)
200 } else if (scanType_
== treeIndexScan
)
206 scanType_
= unknownScan
;
210 void TupleIterator::reset()
213 if (scanType_
== fullTableScan
) *cIter
= ((Chunk
*)chunkPtr_
)->getIterator();
214 else if (scanType_
== hashIndexScan
) if(bIter
) bIter
->reset();
215 else if (scanType_
== treeIndexScan
) if(tIter
) tIter
->reset();