*** empty log message ***
[csql.git] / src / storage / TupleIterator.cxx
blob8fb0b76742147296688e6becb8f5f13e5f1ca0ec
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()
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_;
34 bool isPtr = false;
35 FieldIterator iter = hIdxInfo->idxFldList.getIterator();
36 char *keyBuffer;
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 + AllDataType::size(def.type_, def.length_);
47 int bucketNo = HashIndex::computeHashBucket(hIdxInfo->type,
48 keyStartBuffer, hIdxInfo->noOfBuckets, hIdxInfo->compLength);
49 free(keyStartBuffer);
50 Bucket *bucket = &(hIdxInfo->buckets[bucketNo]);
51 int ret = bucket->mutex_.getLock(procSlot);
52 if (ret != 0)
54 printError(ErrLockTimeOut,"Unable to acquire bucket Mutex for bucket %d",bucketNo);
55 return ErrLockTimeOut;
57 HashIndexNode *head = (HashIndexNode*) bucket->bucketList_;
58 if (!head)
60 bucket->mutex_.releaseLock(procSlot);
61 bIter = NULL ;
62 return OK;
64 printDebug(DM_HashIndex, "open:head for bucket %x is :%x", bucket, head);
65 bIter = new BucketIter(head);
66 bucket->mutex_.releaseLock(procSlot);
67 }else if (treeIndexScan == scanType_)
69 HashIndexInfo *hIdxInfo = (HashIndexInfo*)info;
70 PredicateImpl *predImpl = (PredicateImpl*) pred_;
71 bool isPtr = false;
72 FieldIterator iter = hIdxInfo->idxFldList.getIterator();
73 void *keyPtr; ComparisionOp op;
74 if(iter.hasElement())
76 FieldDef def = iter.nextElement();
77 keyPtr = (void*)predImpl->valPtrForIndexField(def.fldName_);
78 op = predImpl->opForIndexField(def.fldName_);
79 //TODO::remove this predicate term as it is pushed to tree iter
81 CINDEX *iptr = (CINDEX*) hIdxInfo->indexPtr;
82 tIter = new TreeIter((TreeNode*)iptr->hashNodeChunk_);
83 tIter->setSearchKey(keyPtr, op);
84 tIter->setFldOffset(hIdxInfo->fldOffset);
85 tIter->setTypeLength(hIdxInfo->type, hIdxInfo->compLength);
89 return OK;
92 //not returing previous tuple for all iterators and for tree iterator.
93 //it just decrements the nodeOffset for tree iterator.
94 void* TupleIterator::prev()
96 PredicateImpl *predImpl = (PredicateImpl*) pred_;
97 void *tuple = NULL;
98 if (treeIndexScan == scanType_)
100 if (NULL == tIter) return NULL;
101 tuple = tIter->prev();
102 predImpl->setTuple(tuple);
103 if(NULL == tuple) {
104 printDebug(DM_HashIndex, "prev::tuple is null");
107 return tuple;
110 void* TupleIterator::next()
112 PredicateImpl *predImpl = (PredicateImpl*) pred_;
113 void *tuple = NULL;
114 DbRetVal rv = OK;
115 if (fullTableScan == scanType_)
118 if (NULL == pred_ )
120 //no predicates
121 return cIter->nextElement();
123 else
125 //evaluate till it succeeds
126 bool result = false;
127 while (!result)
129 tuple = cIter->nextElement();
130 if(NULL == tuple) return NULL;
131 predImpl->setTuple(tuple);
132 printDebug(DM_Table, "Evaluating the predicate from fullTableScan");
133 rv = predImpl->evaluate(result);
134 if (rv != OK) return NULL;
137 }else if (hashIndexScan == scanType_)
139 if (NULL == bIter)
141 //if there are no nodes in bucket bIter will be null
142 return NULL;
144 //evaluate till it succeeds
145 bool result = false;
146 while (!result)
148 HashIndexNode *node = bIter->next();
149 if (node == NULL) return NULL;
150 printDebug(DM_HashIndex, "next: returned HashIndexNode: %x", node);
151 tuple = node->ptrToTuple_;
152 if(NULL == tuple) {
153 printDebug(DM_HashIndex, "next::tuple is null");
154 return NULL;
157 //if (!predImpl->isSingleTerm()) {
158 printDebug(DM_HashIndex, "next: predicate has more than single term");
159 predImpl->setTuple(tuple);
160 printDebug(DM_Table, "Evaluating the predicate from hashIndexScan: has more than one term");
161 rv = predImpl->evaluate(result);
162 if (rv != OK) return NULL;
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 rv = predImpl->evaluate(result);
181 if (rv != OK) return NULL;
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;