performance fixes
[csql.git] / src / storage / TupleIterator.cxx
blob56d57ee634693853c06945212165d4a346e10c19
1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
4 * *
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. *
9 * *
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. *
14 * *
15 ***************************************************************************/
16 #include<Table.h>
17 #include<Index.h>
18 #include<CatalogTables.h>
19 #include<Lock.h>
20 #include<Debug.h>
21 #include<TableImpl.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;
33 bool isPtr = false;
34 FieldIterator iter = hIdxInfo->idxFldList.getIterator();
35 char *keyBuffer;
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_;
46 int bucketNo = 0;
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);
52 free(keyStartBuffer);
53 Bucket *bucket = &(hIdxInfo->buckets[bucketNo]);
54 int ret = bucket->mutex_.getLock(procSlot);
55 if (ret != 0)
57 printError(ErrLockTimeOut,"Unable to acquire bucket Mutex for bucket %d",bucketNo);
58 return ErrLockTimeOut;
60 HashIndexNode *head = (HashIndexNode*) bucket->bucketList_;
61 if (!head)
63 bucket->mutex_.releaseLock(procSlot);
64 bIter = NULL ;
65 return OK;
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;
73 bool isPtr = false;
74 FieldIterator iter = hIdxInfo->idxFldList.getIterator();
75 void *keyPtr; ComparisionOp op;
76 if(iter.hasElement())
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();
90 return OK;
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_;
98 void *tuple = NULL;
99 if (treeIndexScan == scanType_)
101 if (NULL == tIter) return NULL;
102 tuple = tIter->prev();
103 predImpl->setTuple(tuple);
104 if(NULL == tuple) {
105 printDebug(DM_HashIndex, "prev::tuple is null");
107 //TODO::evaluate as it is done in next() before returning
109 return tuple;
112 void* TupleIterator::next()
114 PredicateImpl *predImpl = (PredicateImpl*) pred_;
115 void *tuple = NULL;
116 DbRetVal rv = OK;
117 if (fullTableScan == scanType_)
120 if (NULL == pred_ )
122 //no predicates
123 return cIter->nextElement();
125 else
127 //evaluate till it succeeds
128 bool result = false;
129 while (!result)
131 tuple = cIter->nextElement();
132 if(NULL == tuple) return NULL;
133 //predImpl->setTuple(tuple);
134 printDebug(DM_Table, "Evaluating the predicate from fullTableScan");
135 predImpl->evaluateForTable(result, (char*)tuple);
138 }else if (hashIndexScan == scanType_)
140 if (NULL == bIter)
142 //if there are no nodes in bucket bIter will be null
143 return NULL;
145 //evaluate till it succeeds
146 bool result = false;
147 while (!result)
149 HashIndexNode *node = bIter->next();
150 if (node == NULL) return NULL;
151 printDebug(DM_HashIndex, "next: returned HashIndexNode: %x", node);
152 tuple = node->ptrToTuple_;
153 if(NULL == tuple) {
154 printDebug(DM_HashIndex, "next::tuple is null");
155 return NULL;
158 //if (!predImpl->isSingleTerm()) {
159 printDebug(DM_HashIndex, "next: predicate has more than single term");
160 //predImpl->setTuple(tuple);
161 printDebug(DM_Table, "Evaluating the predicate from hashIndexScan: has more than one term");
162 predImpl->evaluateForTable(result, (char*)tuple);
163 //}
164 //else
165 // return tuple;
168 }else if (treeIndexScan == scanType_)
170 if (NULL == tIter) return NULL;
171 bool result = false;
172 while (!result)
174 tuple = tIter->next();
175 if(NULL == tuple) {
176 printDebug(DM_HashIndex, "next::tuple is null");
177 return NULL;
179 //predImpl->setTuple(tuple);
180 predImpl->evaluateForTable(result, (char*)tuple);
181 if(!result && (isBetInvolved() || isPointLookInvolved())) tIter->nextNode();
184 return tuple;
187 DbRetVal TupleIterator::close()
189 if (scanType_ == fullTableScan)
191 delete cIter;
192 cIter = NULL;
193 } else if (scanType_ == hashIndexScan)
195 delete bIter;
196 bIter = NULL;
197 } else if (scanType_ == treeIndexScan)
199 delete tIter;
200 tIter = NULL;
203 scanType_ = unknownScan;
204 return OK;
207 void TupleIterator::reset()
209 DbRetVal rv = OK;
210 if (scanType_ == fullTableScan) *cIter = ((Chunk*)chunkPtr_)->getIterator();
211 else if (scanType_ == hashIndexScan) if(bIter) bIter->reset();
212 else if (scanType_ == treeIndexScan) if(tIter) tIter->reset();