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 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
);
50 Bucket
*bucket
= &(hIdxInfo
->buckets
[bucketNo
]);
51 int ret
= bucket
->mutex_
.getLock(procSlot
);
54 printError(ErrLockTimeOut
,"Unable to acquire bucket Mutex for bucket %d",bucketNo
);
55 return ErrLockTimeOut
;
57 HashIndexNode
*head
= (HashIndexNode
*) bucket
->bucketList_
;
60 bucket
->mutex_
.releaseLock(procSlot
);
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_
;
72 FieldIterator iter
= hIdxInfo
->idxFldList
.getIterator();
73 void *keyPtr
; ComparisionOp op
;
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
);
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_
;
98 if (treeIndexScan
== scanType_
)
100 if (NULL
== tIter
) return NULL
;
101 tuple
= tIter
->prev();
102 predImpl
->setTuple(tuple
);
104 printDebug(DM_HashIndex
, "prev::tuple is null");
110 void* TupleIterator::next()
112 PredicateImpl
*predImpl
= (PredicateImpl
*) pred_
;
115 if (fullTableScan
== scanType_
)
121 return cIter
->nextElement();
125 //evaluate till it succeeds
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_
)
141 //if there are no nodes in bucket bIter will be null
144 //evaluate till it succeeds
148 HashIndexNode
*node
= bIter
->next();
149 if (node
== NULL
) return NULL
;
150 printDebug(DM_HashIndex
, "next: returned HashIndexNode: %x", node
);
151 tuple
= node
->ptrToTuple_
;
153 printDebug(DM_HashIndex
, "next::tuple is 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
;
168 }else if (treeIndexScan
== scanType_
)
170 if (NULL
== tIter
) return NULL
;
174 tuple
= tIter
->next();
176 printDebug(DM_HashIndex
, "next::tuple is null");
179 predImpl
->setTuple(tuple
);
180 rv
= predImpl
->evaluate(result
);
181 if (rv
!= OK
) return NULL
;
187 DbRetVal
TupleIterator::close()
189 if (scanType_
== fullTableScan
)
193 } else if (scanType_
== hashIndexScan
)
197 } else if (scanType_
== treeIndexScan
)
203 scanType_
= unknownScan
;