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 ***************************************************************************/
17 #include<CatalogTables.h>
23 #include<PredicateImpl.h>
25 DbRetVal
TreeIndex::insert(TableImpl
*tbl
, Transaction
*tr
, void *indexPtr
, IndexInfo
*indInfo
, void *tuple
, bool undoFlag
)
27 printDebug(DM_TreeIndex
, "\nInside TreeNode::Insert - 1");
28 HashIndexInfo
*info
= (HashIndexInfo
*) indInfo
;
29 CINDEX
*iptr
= (CINDEX
*)indexPtr
;
30 TreeNode
*start
= (TreeNode
*) iptr
->hashNodeChunk_
;
32 int offset
= info
->fldOffset
;
33 DataType type
= info
->type
;
34 printDebug(DM_TreeIndex
, "Inserting tree index node for %s", iptr
->indName_
);
35 void *keyPtr
=(void*)((char*)tuple
+ offset
);
38 //TODO::there is chance that two threads can insert first node at
39 //same time causing the first tree node to leak.
40 printDebug(DM_TreeIndex
, "\nInside if - start=NULL");
41 Chunk
*chunk
= (Chunk
*) iptr
->chunkPtr_
;
42 TreeNode
*tnode
= (TreeNode
*) chunk
->allocate(tbl
->db_
, &rc
);
45 printDebug(DM_TreeIndex
, "\nExit TreeNode::Insert - 1 tnode=NULL");
51 tnode
->noElements_
=1;
55 char **rec
= (char**)((char*) tnode
+ sizeof(TreeNode
));
56 printDebug(DM_TreeIndex
, "\nStoring first record at %x\n", rec
);
58 iptr
->hashNodeChunk_
= tnode
;
60 rc
= start
->insert(tbl
->db_
, indInfo
, indexPtr
, tuple
);
62 printError(rc
, "Error in tree node insertion\n");
65 printDebug(DM_TreeIndex
, "\nExit TreeNode::Insert - 1");
68 void TreeNode::displayAll(int fldOffset
)
70 TreeNode
*iter
= this;
74 printf("PRABA::ITERATING\n");
77 printf("\nDISPLAY NODES:START\n");
80 char **rec
= (char**)((char*) iter
+ sizeof(TreeNode
));
82 for(loc
=0;loc
<iter
->noElements_
;loc
++)
84 printf("%d,",*((int*)((char*) *(rec
+ loc
)+fldOffset
)));
89 printf("DISPLAY NODES:END\n");
91 void TreeNode::displayAll(IndexInfo
*indInfo
, void *indexPtr
)
93 HashIndexInfo
*info
= (HashIndexInfo
*) indInfo
;
94 CINDEX
*iptr
= (CINDEX
*)indexPtr
;
95 TreeNode
*start
= (TreeNode
*) iptr
->hashNodeChunk_
;
96 int offset
= info
->fldOffset
;
97 DataType type
= info
->type
;
98 int noOfBuckets
= info
->noOfBuckets
;
99 TreeNode
*iter
=start
;
105 printf("\nDISPLAY NODES:START\n");
108 char **rec
= (char**)((char*) iter
+ sizeof(TreeNode
));
110 for(loc
=0;loc
<iter
->noElements_
;loc
++)
112 printf("%d,",*((int*)((char*) *(rec
+ loc
)+info
->fldOffset
)));
117 printf("DISPLAY NODES:END\n");
119 DbRetVal
TreeNode::insert(Database
*db
, IndexInfo
*indInfo
, void *indexPtr
, void *tuple
)
121 HashIndexInfo
*info
= (HashIndexInfo
*) indInfo
;
122 CINDEX
*iptr
= (CINDEX
*)indexPtr
;
123 TreeNode
*start
= (TreeNode
*) iptr
->hashNodeChunk_
;
124 int offset
= info
->fldOffset
;
125 DataType type
= info
->type
;
126 int noOfBuckets
= info
->noOfBuckets
;
127 TreeNode
*iter
=start
; void *record
= NULL
;
128 TreeNode
*prev
= start
;
129 char *keyVal
= (char*) tuple
+ info
->fldOffset
;
131 bool recordInserted
= false;
132 printDebug(DM_TreeIndex
, "\nInside TreeNode::Insert - 2");
134 int direction
= 0; //0:current,1:right,2:rightLeft,-1:left,-2:leftRight
138 record
= ((char*)iter
->max_
)+ info
->fldOffset
;
139 printDebug(DM_TreeIndex
, "\n%d---%d", *((int*)keyVal
), *((int*)record
));
140 bool result
= AllDataType::compareVal(keyVal
, record
, OpGreaterThan
,
141 info
->type
, info
->compLength
);
152 printDebug(DM_TreeIndex
, "\n2Insert- > ");
155 record
= ((char*)iter
->min_
)+ info
->fldOffset
;
156 result
= AllDataType::compareVal(keyVal
, record
, OpLessThan
,
157 info
->type
, info
->compLength
);
167 printDebug(DM_TreeIndex
, "\n2Insert- < ");
171 printDebug(DM_TreeIndex
, "\n2Insert- = ");
180 //Check the size of the prev node....
181 //if not full then move the iter to prev and call insertLast()
182 //else call insertFirst();
184 if((iter
->prev_
!= NULL
) && (iter
->prev_
->noElements_
< noOfBuckets
) )
186 printDebug(DM_TreeIndex
, "\n2Insert- d=2 if ");
188 rv
= insert(1, db
, indInfo
, iptr
, tuple
, iter
);
192 printDebug(DM_TreeIndex
, "\n2Insert- d=2 else ");
193 rv
= insert(-1, db
, indInfo
, iptr
, tuple
, iter
);
196 else if(direction
== 1)
199 if((iter
->noElements_
>= noOfBuckets
) && (iter
->next_
!= NULL
)
200 && (iter
->next_
->noElements_
< noOfBuckets
) )
202 printDebug(DM_TreeIndex
, "\n2Insert- d=1 if ");
204 rv
= insert(-1, db
, indInfo
, iptr
, tuple
, iter
);
208 printDebug(DM_TreeIndex
, "\n2Insert- d=1 else ");
209 rv
= insert(1, db
, indInfo
, iptr
, tuple
, iter
);
212 else if(direction
== -2)
214 if(iter
->next_
!= NULL
&& iter
->next_
->noElements_
< noOfBuckets
)
216 printDebug(DM_TreeIndex
, "\n2Insert- d=-2 if ");
218 rv
= insert(-1, db
, indInfo
, iptr
, tuple
, iter
);
222 printDebug(DM_TreeIndex
, "\n2Insert- d=-2 else ");
223 rv
= insert(1, db
, indInfo
, iptr
, tuple
, iter
);
226 else if(direction
== -1)
229 if((iter
->noElements_
>= noOfBuckets
) && (iter
->prev_
!= NULL
)
230 && (iter
->prev_
->noElements_
< noOfBuckets
) )
232 printDebug(DM_TreeIndex
, "\n2Insert- d=-1 if ");
234 rv
= insert(1, db
, indInfo
, iptr
, tuple
, iter
);
238 printDebug(DM_TreeIndex
, "\n2Insert- d=-1 else ");
239 rv
= insert(-1, db
, indInfo
, iptr
, tuple
, iter
);
244 printDebug(DM_TreeIndex
, "\n2Insert- d=0 ");
245 rv
= insert(0, db
, indInfo
, iptr
, tuple
, iter
);
247 printDebug(DM_TreeIndex
, "\n %d While ..Exit TreeNode::Insert - 2",count
);
250 DbRetVal
TreeNode::insert(int position
, Database
* db
, IndexInfo
* indInfo
,
251 CINDEX
* iptr
, void * tuple
, TreeNode
* iter
)
253 //position--- -1:First,0:Middle,1:Last
255 HashIndexInfo
*info
= (HashIndexInfo
*) indInfo
;
256 TreeNode
*start
= (TreeNode
*) iptr
->hashNodeChunk_
;
257 int offset
= info
->fldOffset
;
258 DataType type
= info
->type
;
259 int noOfBuckets
= info
->noOfBuckets
;
261 TreeNode
*prev
= start
;
262 TreeNode
*next
= start
;
263 char *keyVal
= (char*) tuple
+ info
->fldOffset
;
265 bool recordInserted
= false;
266 iter
->mutex_
.getLock(db
->procSlot
);
269 if(iter
->noElements_
>= noOfBuckets
)
271 Chunk
*chunk
= (Chunk
*) iptr
->chunkPtr_
;
272 TreeNode
*tnode
= (TreeNode
*) chunk
->allocate(db
, &rc
);
275 printDebug(DM_TreeIndex
, "\nExit TreeNode::Insert Position tnode=NULL");
276 iter
->mutex_
.releaseLock(db
->procSlot
);
279 tnode
->mutex_
.init();
282 tnode
->noElements_
=1;
284 tnode
->prev_
= iter
->prev_
;
287 char **rec
= (char**)((char*)tnode
+ sizeof(TreeNode
));
288 *rec
= (char*) tuple
;
292 printDebug(DM_TreeIndex
, "\n3Insert- p=-1 else ");
293 char **rec
= (char**)((char*)iter
+ sizeof(TreeNode
));
294 char *tmp
= (char *)malloc(sizeof(void **) * iter
->noElements_
);
295 memcpy(tmp
, (char*)rec
, sizeof(void **)* iter
->noElements_
);
296 memcpy((char*)rec
+ sizeof(void **), tmp
, sizeof(void **) * (iter
->noElements_
));
300 *rec
= (char*) tuple
;
303 else if(position
== 1)
305 if(iter
->noElements_
>= noOfBuckets
)
307 printDebug(DM_TreeIndex
, "\n3Insert- p=1 if ");
308 Chunk
*chunk
= (Chunk
*) iptr
->chunkPtr_
;
309 TreeNode
*tnode
= (TreeNode
*) chunk
->allocate(db
, &rc
);
312 printDebug(DM_TreeIndex
, "\nExit TreeNode::Insert Position tnode=NULL");
313 iter
->mutex_
.releaseLock(db
->procSlot
);
316 tnode
->mutex_
.init();
319 tnode
->noElements_
=1;
320 tnode
->next_
= iter
->next_
;
325 tnode
->next_
->prev_
= tnode
;
328 char **rec
= (char**)((char*)tnode
+ sizeof(TreeNode
));
329 *rec
= (char*) tuple
;
333 printDebug(DM_TreeIndex
, "\n3Insert- p=1 else ");
334 char **rec
= (char**)((char*)iter
+ sizeof(TreeNode
));
335 rec
= (char **)((char *)rec
+ (iter
->noElements_
* sizeof(void **)));
338 *rec
= (char*) tuple
;
339 rec
= (char**)((char*)iter
+ sizeof(TreeNode
));
340 rec
= (char**)((char *)rec
+ ((iter
->noElements_
-1) * sizeof(void **)));
345 printDebug(DM_TreeIndex
, "\n3Insert- p=0 ");
348 int end
= iter
->noElements_
- 1;
351 char **rec
= (char**)((char*)iter
+ sizeof(TreeNode
));
354 for(middle
= (start
+ end
) / 2; start
<= end
; middle
= (start
+end
)/2)
357 record
= ((char*)*(rec
+middle
)) + info
->fldOffset
;
358 printDebug(DM_TreeIndex
, "\n3Insert- p=0 get record \n");
359 printDebug(DM_TreeIndex
, "%d-%d\n\n", *((int*)keyVal
), *((int*)record
));
360 bool res
= AllDataType::compareVal(keyVal
, record
, OpEquals
, info
->type
, info
->compLength
);
364 if (info
->isUnique
) {
365 iter
->mutex_
.releaseLock(db
->procSlot
);
366 printError(ErrUnique
, "Unique constraint violation\n");
371 res
= AllDataType::compareVal(keyVal
, record
, OpLessThan
, info
->type
, info
->compLength
);
382 if(iter
->noElements_
>= noOfBuckets
)
384 printDebug(DM_TreeIndex
, "\n3Insert- p=0 if ");
385 Chunk
*chunk
= (Chunk
*) iptr
->chunkPtr_
;
386 TreeNode
*tnode
= (TreeNode
*) chunk
->allocate(db
, &rc
);
389 printDebug(DM_TreeIndex
, "\nExit TreeNode::Insert Position tnode=NULL");
390 iter
->mutex_
.releaseLock(db
->procSlot
);
393 tnode
->mutex_
.init();
394 tnode
->next_
= iter
->next_
;
399 tnode
->next_
->prev_
= tnode
;
402 char **rec
= (char**)((char*)iter
+ sizeof(TreeNode
));
403 char *tmp
= (char *)malloc(sizeof(void *) * (iter
->noElements_
- loc
));
404 memcpy(tmp
, (char*)rec
+ (loc
* sizeof(void *)), sizeof(void *) * (iter
->noElements_
- loc
));///////// Check the type cast char *
405 rec
= (char**)((char *)rec
+ (loc
* sizeof(void *)));
407 tnode
->noElements_
= iter
->noElements_
- loc
;
408 iter
->noElements_
= loc
+ 1;
409 rec
= (char**)((char*)iter
+ sizeof(TreeNode
));
412 rec
= (char**)((char*)tnode
+ sizeof(TreeNode
));
413 memcpy((char*)rec
, tmp
, (tnode
->noElements_
) * sizeof(void *));
415 rec
= (char**)((char *)rec
+ ((tnode
->noElements_
- 1) * sizeof(void *)));
421 printDebug(DM_TreeIndex
, "\n3Insert- p=0 else pos-%d",loc
);
422 char **rec
= (char**)((char*)iter
+ sizeof(TreeNode
));
423 char *tmp
= (char *)malloc(sizeof(void *) * (iter
->noElements_
- loc
));
424 memcpy(tmp
, (char*)rec
+ (loc
* sizeof(void *)), sizeof(void *) * (iter
->noElements_
- loc
));///////// Check the type cast char *
425 memcpy((char*)rec
+ ((loc
+1) * sizeof(void *)), tmp
, sizeof(void *) * (iter
->noElements_
- loc
));
432 rec
= (char **)((char*)rec
+ (loc
* sizeof(void *)));
436 iter
->mutex_
.releaseLock(db
->procSlot
);
440 DbRetVal
TreeIndex::remove(TableImpl
*tbl
, Transaction
*tr
, void *indexPtr
, IndexInfo
*indInfo
, void *tuple
, bool undoFlag
)
442 //printf("Tree index remove called\n");
443 HashIndexInfo
*info
= (HashIndexInfo
*) indInfo
;
444 CINDEX
*iptr
= (CINDEX
*)indexPtr
;
445 TreeNode
*start
= (TreeNode
*) iptr
->hashNodeChunk_
;
446 TreeNode
*iter
= locateNode(start
, tuple
, indInfo
);
447 if (NULL
== iter
) return OK
; //element not found
448 return removeElement(tbl
->getDB(), iter
, tuple
, info
);
450 TreeNode
* TreeIndex::locateNode(TreeNode
*iter
, void *tuple
, IndexInfo
*indInfo
)
452 HashIndexInfo
*info
= (HashIndexInfo
*) indInfo
;
453 void *searchKey
=(void*)((char*)tuple
+ info
->fldOffset
);
456 char *record
= ((char*)iter
->max_
)+ info
->fldOffset
;
457 bool result
= AllDataType::compareVal(searchKey
, record
,
459 info
->type
, info
->compLength
);
465 record
= ((char*)iter
->min_
)+ info
->fldOffset
;
466 result
= AllDataType::compareVal(searchKey
, record
,
468 info
->type
, info
->compLength
);
470 //current node contains the key
482 DbRetVal
TreeIndex::removeElement(Database
*db
, TreeNode
*iter
, void *tuple
, HashIndexInfo
*info
)
484 void *searchKey
=(void*)((char*)tuple
+ info
->fldOffset
);
485 int loc
=0, middle
=0, start
=0, end
=iter
->noElements_
-1;
486 char **rec
= (char**)((char*)iter
+ sizeof(TreeNode
));
487 iter
->mutex_
.getLock(db
->procSlot
);
488 for(middle
= (start
+ end
) / 2; start
<= end
; middle
= (start
+end
)/2)
491 char *record
= ((char*)*(rec
+middle
)) + info
->fldOffset
;
492 bool res
= AllDataType::compareVal(searchKey
, record
, OpEquals
,
493 info
->type
, info
->compLength
);
499 res
= AllDataType::compareVal(searchKey
, record
, OpLessThan
,
500 info
->type
, info
->compLength
);
511 char *tmp
= (char *)malloc(sizeof(void *) * (iter
->noElements_
- loc
));
512 memcpy(tmp
, (char*)rec
+ ((loc
+1) * sizeof(void *)), sizeof(void *) * (iter
->noElements_
- loc
));
513 memcpy((char*)rec
+ ((loc
) * sizeof(void *)), tmp
, sizeof(void *) * (iter
->noElements_
- loc
));
519 iter
->mutex_
.releaseLock(db
->procSlot
);
520 //TODO::if noElement is zero then deallocate the tree node
526 DbRetVal
TreeIndex::update(TableImpl
*tbl
, Transaction
*tr
, void *indexPtr
, IndexInfo
*indInfo
, void *tuple
, bool undoFlag
)
528 CINDEX
*iptr
= (CINDEX
*)indexPtr
;
530 HashIndexInfo
*info
= (HashIndexInfo
*) indInfo
;
531 //check whether the index key is updated or not
532 //if it is not updated return from here
533 bool keyNotUpdated
= false;
534 FieldIterator idxFldIter
= info
->idxFldList
.getIterator();
535 while (idxFldIter
.hasElement())
537 FieldDef
*idef
= idxFldIter
.nextElement();
538 FieldIterator fldIter
= tbl
->fldList_
.getIterator();
539 while (fldIter
.hasElement())
541 FieldDef
*def
= fldIter
.nextElement();
542 if (0 == strcmp(def
->fldName_
, idef
->fldName_
))
544 if (NULL
!= def
->bindVal_
)
549 keyNotUpdated
= true;