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 long long TreeNode::getTotalElements()
28 TreeNode
*iter
= (TreeNode
*) this ;
30 long long totalElement
=0;
33 for(int i
=0;i
< iter
->noElements_
;i
++)
35 tnode
= (TreeNode
*)*((char**)((char*)((char*)iter
+ sizeof(TreeNode
))+ ((i
)*sizeof(void *))));
36 totalElement
+= tnode
->noElements_
;
43 void TreeNode::displayAll(int fldOffset
)
46 TreeNode
*iter
= (TreeNode
*) this ;
48 TreeNode
*prev
= iter
;
50 printf("<TreeNode Info>\n");
55 tnode
= (TreeNode
*)*((char**)((char*)((char*)iter
+ sizeof(TreeNode
))+ ((iter
->noElements_
-1)*sizeof(void *))));
56 char *record
= ((char*)tnode
->max_
)+ fldOffset
;
57 TreeNode
*needremovetnode
= (TreeNode
*)*((char**)((char*)((char*)iter
+ sizeof(TreeNode
))));
58 printf(" <First level > node:%d noElements:%d </First level>\n",i
, iter
->noElements_
);
59 for(int i
=0;i
< iter
->noElements_
;i
++)
61 tnode
= (TreeNode
*)*((char**)((char*)((char*)iter
+ sizeof(TreeNode
))+ ((i
)*sizeof(void *))));
62 printf(" <Second Level Node> Node:%d Elements:%d Min:%d Max:%d </Second Level Node>\n ",i
, tnode
->noElements_
, *(int*)((char*)tnode
->min_
+fldOffset
), *(int*)((char*)tnode
->max_
+ fldOffset
));
63 char **rec
= (char**)((char*)tnode
+ sizeof(TreeNode
));
64 for(int j
=0; j
< tnode
->noElements_
; j
++){
65 printf("%d,",*((int*)((char*) *(rec
+ j
)+fldOffset
)));
72 printf("</TreeNode Info>\n");
75 void TreeNode::displayAll()
78 TreeNode
*iter
= (TreeNode
*) this ;
80 long long totalElement
=0;
82 printf("<TreeNode count>\n");
85 printf(" <First Level Node> %d <Total Elements> %d </Total Elements> <Mutex> %x %d </Mutex></First Level Node>\n", count
, iter
->noElements_
, &iter
->mutex_
, iter
->mutex_
.getLockVal());
86 for(int i
=0;i
< iter
->noElements_
;i
++)
88 tnode
= (TreeNode
*)*((char**)((char*)((char*)iter
+ sizeof(TreeNode
))+ ((i
)*sizeof(void *))));
89 printf(" <Second Level Node %d> %d <Mutex> %x %d</Mutex> </Second Level Node>\n",i
, tnode
->noElements_
, &tnode
->mutex_
, tnode
->mutex_
.getLockVal());
90 totalElement
+= tnode
->noElements_
;
95 printf(" <Total Records> %lld </Total Records>\n",totalElement
);
96 printf("</TreeNode count>\n");
99 DbRetVal
TreeNode::insertNodeIntoFirstLevel(Database
* db
, IndexInfo
* indInfo
, void* indexPtr
, TreeNode
* newNode
,int nodepos
)
102 TreeNode
*start
= (TreeNode
*) this;
103 HashIndexInfo
*info
= (HashIndexInfo
*) indInfo
;
104 CINDEX
*iptr
= (CINDEX
*)indexPtr
;
105 int offset
= info
->fldOffset
;
106 DataType type
= info
->type
;
107 int noOfBuckets
= info
->noOfBuckets
;
111 TreeNode
*tempNode
= start
;
112 if(start
->noElements_
< noOfBuckets
)
114 printDebug(DM_TreeIndex
,"insertNodeIntoFirstLevel after node insert manage first level node");
115 if(start
->noElements_
<= nodepos
)
117 node
= (char **)((char*)start
+ sizeof(TreeNode
) + (nodepos
* sizeof(void *)));
118 start
->noElements_
++;
119 *node
= (char*)newNode
;
122 node
= (char**)((char*)start
+ sizeof(TreeNode
));
123 tmp
= (char *)malloc(sizeof(void *) * (start
->noElements_
- nodepos
));
124 memcpy(tmp
, (char*)node
+ (nodepos
* sizeof(void *)), sizeof(void *) * (start
->noElements_
- nodepos
));
125 memcpy((char*)node
+ ((nodepos
+1) * sizeof(void *)), tmp
, sizeof(void *) * (start
->noElements_
- nodepos
));
127 node
= (char **)((char*)node
+ (nodepos
* sizeof(void *)));
128 *node
= (char*)newNode
;
129 start
->noElements_
++;
134 node
= (char**)((char*)start
+ sizeof(TreeNode
));
135 if(start
->noElements_
> nodepos
)
137 tmpnode
= *(char **)((char*)node
+ ((start
->noElements_
-1) * sizeof(void *)));//store last one
138 tmp
= (char *)malloc(sizeof(void *) * (start
->noElements_
- nodepos
));
139 memcpy(tmp
, (char*)node
+ (nodepos
* sizeof(void *)), sizeof(void *) * (start
->noElements_
- nodepos
-1));
140 memcpy((char*)node
+ ((nodepos
+1) * sizeof(void *)), tmp
, sizeof(void *) * (start
->noElements_
- nodepos
-1));
142 node
= (char **)((char*)node
+ (nodepos
* sizeof(void *)));
143 *node
= (char*)newNode
;
146 tmpnode
=(char*)newNode
;
149 if( start
->next_
!= NULL
&& start
->next_
->noElements_
< noOfBuckets
)
151 start
= start
->next_
;
153 node
= (char**)((char*)start
+ sizeof(TreeNode
));
154 tmp
= (char *)malloc(sizeof(void *) * (start
->noElements_
- nodepos
));
155 memcpy(tmp
, (char*)node
+ (nodepos
* sizeof(void *)), sizeof(void *) * (start
->noElements_
- nodepos
));
156 memcpy((char*)node
+ ((nodepos
+1) * sizeof(void *)), tmp
, sizeof(void *) * (start
->noElements_
- nodepos
));
158 node
= (char **)((char*)node
+ (nodepos
* sizeof(void *)));
159 *node
= (char*)tmpnode
;
160 start
->noElements_
++;
161 start
->mutex_
.releaseShareLock(db
->procSlot
);
164 printDebug(DM_TreeIndex
, "Check if full and start->next_ ==NULL then create new one");
165 Chunk
*ftchunk
= (Chunk
*) iptr
->chunkPtr_
;
166 TreeNode
*ftnode
= (TreeNode
*) ftchunk
->allocate(db
, &rv
);
169 printError(rv
, "Exit TreeNode firstlevel allocate fail");
170 tempNode
->mutex_
.releaseShareLock(db
->procSlot
);
173 ftnode
->mutex_
.init("TNODE-I");
176 ftnode
->noElements_
=1;
177 ftnode
->balance_
= 0;
178 char **tn
=(char**)((char*) ftnode
+sizeof(TreeNode
));
179 *tn
= (char*)tmpnode
;
180 ftnode
->next_
= start
->next_
;
181 ftnode
->prev_
= start
;
182 start
->next_
= ftnode
;
185 tempNode
->mutex_
.releaseShareLock(db
->procSlot
);
186 printDebug(DM_TreeIndex
," Mutex Release on %x\n",tempNode
);
190 DbRetVal
TreeNode::insertRecordIntoNodeAndArrangeFirstLevel(Database
* db
, IndexInfo
* indInfo
, void* indexPtr
, void * tuple
, TreeNode
* fstLevel
, int nodePos
)
192 TreeNode
*iter
= (TreeNode
*) this;
193 HashIndexInfo
*info
= (HashIndexInfo
*) indInfo
;
194 CINDEX
*iptr
= (CINDEX
*)indexPtr
;
195 int offset
= info
->fldOffset
;
196 DataType type
= info
->type
;
197 int noOfBuckets
= info
->noOfBuckets
;
199 char *keyVal
= (char*) tuple
+ info
->fldOffset
;
201 bool recordInserted
= false;
202 TreeNode
*tmpNode
=NULL
;
203 int ret
= iter
->mutex_
.getExclusiveLock(db
->procSlot
);
205 printError(ErrLockTimeOut
,"Unable to lock the tree node. Retry...");
206 fstLevel
->mutex_
.releaseShareLock(db
->procSlot
); //release here 1st level
207 return ErrLockTimeOut
;
209 if(iter
->noElements_
>= noOfBuckets
)
212 //Decide new record should go in left or right of second level
213 //if it is inside then create new memcpy all address from location to next node
214 //if left check prev_ node has free space or not if yes insert at end else create new
215 //if right check next_ node has free space or not if yes insert at Ist loc nad do memcpy else create new
216 //create node and link to prevous node and link to the Fistlevel
217 record
= ((char*)iter
->max_
)+ info
->fldOffset
;
218 bool result
= AllDataType::compareVal(keyVal
, record
, OpGreaterThan
, info
->type
, info
->compLength
);
221 printDebug(DM_TreeIndex
,"locateed Node full new node create at iright");
222 //check right for free space if not create node right
223 tmpNode
= iter
->next_
;
224 if(tmpNode
!=NULL
&& tmpNode
->noElements_
< noOfBuckets
)
226 //insert at beginning
227 ret
= tmpNode
->mutex_
.getExclusiveLock(db
->procSlot
);
229 printError(ErrLockTimeOut
,"Unable to lock the tree node. Retry...");
230 iter
->mutex_
.releaseShareLock(db
->procSlot
);
231 fstLevel
->mutex_
.releaseShareLock(db
->procSlot
); //release here 1st level
232 return ErrLockTimeOut
;
235 char **rec
= (char**)((char*)tmpNode
+ sizeof(TreeNode
));
236 tmp
= (char *)malloc(sizeof(void *) * (tmpNode
->noElements_
));
237 memcpy(tmp
, (char*)rec
, sizeof(void *) * (iter
->noElements_
));
238 memcpy((char*)rec
+ (1*sizeof(void *)), tmp
, sizeof(void *) * (iter
->noElements_
));
241 tmpNode
->noElements_
++;
243 iter
->mutex_
.releaseShareLock(db
->procSlot
);
244 tmpNode
->mutex_
.releaseShareLock(db
->procSlot
);
245 fstLevel
->mutex_
.releaseShareLock(db
->procSlot
);
246 printDebug(DM_TreeIndex
," Mutex Release on %x\n",fstLevel
);
250 //allocate new node here
251 Chunk
*chunk
= (Chunk
*) iptr
->chunkPtr_
;
252 TreeNode
*tnode
= (TreeNode
*) chunk
->allocate(db
, &rc
);
255 printError(rc
, "Exit TreeNode create fail after node full");
256 iter
->mutex_
.releaseShareLock(db
->procSlot
);
257 fstLevel
->mutex_
.releaseShareLock(db
->procSlot
);
258 printDebug(DM_TreeIndex
," Mutex Release on %x\n",fstLevel
);
261 if( fstLevel
->next_
!=NULL
&& fstLevel
->noElements_
>= noOfBuckets
&& fstLevel
->next_
->noElements_
< noOfBuckets
)
263 ret
= fstLevel
->next_
->mutex_
.getExclusiveLock(db
->procSlot
);
265 printError(ErrLockTimeOut
,"Unable to lock the tree node. Retry...");
266 chunk
->free(db
, tnode
);
267 iter
->mutex_
.releaseShareLock(db
->procSlot
);
268 fstLevel
->mutex_
.releaseShareLock(db
->procSlot
); //release here 1st level
269 return ErrLockTimeOut
;
272 tnode
->mutex_
.init();
273 strcpy(tnode
->mutex_
.name
, "Tree");
276 tnode
->noElements_
=1;
280 char **rec
= (char**)((char*) tnode
+ sizeof(TreeNode
));
281 *rec
= (char*) tuple
;
282 if(iter
->next_
!=NULL
){
283 if( 0 !=Mutex::CASL((long*)&iter
->next_
->prev_
, (long)iter
->next_
->prev_
, (long)tnode
))
285 printError(ErrLockTimeOut
, "Lock timeout..retry Tree");
286 chunk
->free(db
, tnode
);
287 iter
->mutex_
.releaseShareLock(db
->procSlot
);
288 fstLevel
->mutex_
.releaseShareLock(db
->procSlot
);
289 return ErrLockTimeOut
;
292 tnode
->next_
= iter
->next_
;
296 iter
->mutex_
.releaseShareLock(db
->procSlot
);
297 fstLevel
->insertNodeIntoFirstLevel(db
, indInfo
, indexPtr
, tnode
, nodePos
);
301 record
= ((char*)iter
->min_
)+ info
->fldOffset
;
302 bool result
= AllDataType::compareVal(keyVal
, record
, OpLessThan
, info
->type
, info
->compLength
);
305 printDebug(DM_TreeIndex
,"\nlocateed Node full new node create at left");
306 //check left for free space if not create node left
307 tmpNode
= iter
->prev_
;
308 if(tmpNode
!=NULL
&& tmpNode
->noElements_
< noOfBuckets
)
311 ret
= tmpNode
->mutex_
.getExclusiveLock(db
->procSlot
);
313 printError(ErrLockTimeOut
,"Unable to lock the tree node. Retry...");
314 iter
->mutex_
.releaseShareLock(db
->procSlot
);
315 fstLevel
->mutex_
.releaseShareLock(db
->procSlot
); //release here 1st level
316 return ErrLockTimeOut
;
318 char **rec
= (char**)((char*)tmpNode
+ sizeof(TreeNode
));
319 rec
= (char **)((char *)rec
+ (tmpNode
->noElements_
* sizeof(void *)));
321 tmpNode
->max_
= tuple
;
322 tmpNode
->noElements_
++;
323 iter
->mutex_
.releaseShareLock(db
->procSlot
);
324 tmpNode
->mutex_
.releaseShareLock(db
->procSlot
);
325 fstLevel
->mutex_
.releaseShareLock(db
->procSlot
);
326 printDebug(DM_TreeIndex
," Mutex Release on %x\n",fstLevel
);
330 Chunk
*chunk
= (Chunk
*) iptr
->chunkPtr_
;
331 TreeNode
*tnode
= (TreeNode
*) chunk
->allocate(db
, &rc
);
334 printError(rc
, "Exit TreeNode create fail after node full");
335 iter
->mutex_
.releaseShareLock(db
->procSlot
);
336 fstLevel
->mutex_
.releaseShareLock(db
->procSlot
);
337 printDebug(DM_TreeIndex
," Mutex Release on %x\n",fstLevel
);
340 if( fstLevel
->next_
!=NULL
&& fstLevel
->noElements_
>= noOfBuckets
&& fstLevel
->next_
->noElements_
< noOfBuckets
)
342 ret
= fstLevel
->next_
->mutex_
.getExclusiveLock(db
->procSlot
);
344 printError(ErrLockTimeOut
,"Unable to lock the tree node. Retry...");
345 chunk
->free(db
, tnode
);
346 iter
->mutex_
.releaseShareLock(db
->procSlot
);
347 fstLevel
->mutex_
.releaseShareLock(db
->procSlot
); //release here 1st level
348 return ErrLockTimeOut
;
351 tnode
->mutex_
.init();
352 strcpy(tnode
->mutex_
.name
, "Tree");
355 tnode
->noElements_
=1;
359 char **rec
= (char**)((char*) tnode
+ sizeof(TreeNode
));
360 printDebug(DM_TreeIndex
, "Storing first record at %x\n", rec
);
361 *rec
= (char*) tuple
;
362 if(iter
->prev_
!=NULL
) {
363 if( 0 !=Mutex::CASL((long*)&iter
->prev_
->next_
, (long)iter
->prev_
->next_
, (long)tnode
))
365 printError(ErrLockTimeOut
, "Lock timeout..retry Tree");
366 chunk
->free(db
, tnode
);
367 iter
->mutex_
.releaseShareLock(db
->procSlot
);
368 fstLevel
->mutex_
.releaseShareLock(db
->procSlot
);
369 return ErrLockTimeOut
;
372 tnode
->prev_
= iter
->prev_
;
376 iter
->mutex_
.releaseShareLock(db
->procSlot
);
377 fstLevel
->insertNodeIntoFirstLevel(db
, indInfo
, indexPtr
, tnode
, nodePos
);
382 //locate position shift node
384 char **rec
= (char**)((char*) iter
+ sizeof(TreeNode
));
387 int end
= iter
->noElements_
- 1;
392 for(middle
= (start
+ end
) / 2; start
<= end
; middle
= (start
+end
)/2)
395 record
= ((char*)*(rec
+middle
)) + info
->fldOffset
;
396 printDebug(DM_TreeIndex
, "%d-%d\n\n", *((int*)keyVal
), *((int*)record
));
397 bool res
= AllDataType::compareVal(keyVal
, record
,
398 OpLessThan
, info
->type
, info
->compLength
);
405 res
= AllDataType::compareVal(keyVal
, record
,
406 OpGreaterThan
, info
->type
, info
->compLength
);
412 if (info
->isUnique
) {
413 iter
->mutex_
.releaseShareLock(db
->procSlot
);
414 fstLevel
->mutex_
.releaseShareLock(db
->procSlot
);
415 printError(ErrUnique
, "Unique constraint violation");
423 Chunk
*chunk
= (Chunk
*) iptr
->chunkPtr_
;
424 TreeNode
*tnode
= (TreeNode
*) chunk
->allocate(db
, &rc
);
427 printError(rc
, "Exit TreeNode create fail after node full");
428 iter
->mutex_
.releaseShareLock(db
->procSlot
);
429 fstLevel
->mutex_
.releaseShareLock(db
->procSlot
);
430 printDebug(DM_TreeIndex
," Mutex Release on %x\n",fstLevel
);
433 if( fstLevel
->next_
!=NULL
&& fstLevel
->noElements_
>= noOfBuckets
&& fstLevel
->next_
->noElements_
< noOfBuckets
)
435 ret
= fstLevel
->next_
->mutex_
.getExclusiveLock(db
->procSlot
);
437 printError(ErrLockTimeOut
,"Unable to lock the tree node. Retry...");
438 chunk
->free(db
, tnode
);
439 iter
->mutex_
.releaseShareLock(db
->procSlot
);
440 fstLevel
->mutex_
.releaseShareLock(db
->procSlot
); //release here 1st level
441 return ErrLockTimeOut
;
444 tnode
->mutex_
.init();
445 strcpy(tnode
->mutex_
.name
, "Tree");
448 tnode
->noElements_
=1;
453 //shift all element from the location to next node
454 char **fstRec
= (char**)((char*)iter
+ sizeof(TreeNode
));
455 tmp
= (char *)malloc(sizeof(void *) * (iter
->noElements_
- loc
));
456 memcpy(tmp
, (char*)fstRec
+ (loc
* sizeof(void *)), sizeof(void *) * (iter
->noElements_
- loc
));
457 rec
= (char **)((char*)fstRec
+ (loc
* sizeof(void *)));
460 fstRec
= (char**)((char*) tnode
+ sizeof(TreeNode
));
461 memcpy((char*)fstRec
, tmp
, sizeof(void *) * (iter
->noElements_
- loc
));
463 tnode
->noElements_
= iter
->noElements_
- loc
;
465 tnode
->min_
= *fstRec
;
466 iter
->noElements_
= loc
+ 1;
472 if(iter
->next_
!=NULL
){
473 if( 0 !=Mutex::CASL((long*)&iter
->next_
->prev_
, (long)iter
->next_
->prev_
, (long)tnode
))
475 printError(ErrLockTimeOut
, "Lock timeout..retry Tree");
476 chunk
->free(db
, tnode
);
477 iter
->mutex_
.releaseShareLock(db
->procSlot
);
478 fstLevel
->mutex_
.releaseShareLock(db
->procSlot
);
479 return ErrLockTimeOut
;
482 tnode
->next_
= iter
->next_
;
484 iter
->next_
=tnode
; //TODO::need here CASL
486 //shift right done after this block
487 printDebug(DM_TreeIndex
,"located Node full new node create at right position %d shift node",loc
);
489 iter
->mutex_
.releaseShareLock(db
->procSlot
);
490 fstLevel
->insertNodeIntoFirstLevel(db
, indInfo
, indexPtr
, tnode
, nodePos
);
495 if(iter
->noElements_
< noOfBuckets
)
497 fstLevel
->mutex_
.releaseShareLock(db
->procSlot
);
498 printDebug(DM_TreeIndex
,"located Node not full insert in same node");
500 record
= ((char*)iter
->max_
)+ info
->fldOffset
;
501 printDebug(DM_TreeIndex
, "\n%d---%d", *((int*)keyVal
), *((int*)record
));
502 bool result
= AllDataType::compareVal(keyVal
, record
, OpGreaterThan
, info
->type
, info
->compLength
);
505 char **rec
= (char**)((char*)iter
+ sizeof(TreeNode
));
506 rec
= (char **)((char *)rec
+ (iter
->noElements_
* sizeof(void **)));
509 *rec
= (char*) tuple
;
514 int end
= iter
->noElements_
- 1;
517 char **rec
= (char**)((char*)iter
+ sizeof(TreeNode
));
520 for(middle
= (start
+ end
) / 2; start
<= end
; middle
= (start
+end
)/2)
523 record
= ((char*)*(rec
+middle
)) + info
->fldOffset
;
524 printDebug(DM_TreeIndex
, "%d-%d\n\n", *((int*)keyVal
), *((int*)record
));
525 bool res
= AllDataType::compareVal(keyVal
, record
, OpLessThan
, info
->type
, info
->compLength
);
532 res
= AllDataType::compareVal(keyVal
, record
, OpGreaterThan
, info
->type
, info
->compLength
);
540 iter
->mutex_
.releaseShareLock(db
->procSlot
);
541 //fstLevel->mutex_.releaseShareLock(db->procSlot);
542 printError(ErrUnique
, "Unique constraint violation");
549 printDebug(DM_TreeIndex
, "\nInsert pos-%d",loc
);
550 rec
= (char**)((char*)iter
+ sizeof(TreeNode
));
551 tmp
= (char *)malloc(sizeof(void *) * (iter
->noElements_
- loc
));
552 memcpy(tmp
, (char*)rec
+ (loc
* sizeof(void *)), sizeof(void *) * (iter
->noElements_
- loc
));///////// Check the type cast char *
553 memcpy((char*)rec
+ ((loc
+1) * sizeof(void *)), tmp
, sizeof(void *) * (iter
->noElements_
- loc
));
560 rec
= (char **)((char*)rec
+ (loc
* sizeof(void *)));
563 //first level mutex release
564 iter
->mutex_
.releaseShareLock(db
->procSlot
);
569 DbRetVal
TreeNode::insert(Database
*db
,IndexInfo
*indInfo
,void *indexPtr
,void *tuple
)
572 TreeNode
*iter
= (TreeNode
*) this ;
573 HashIndexInfo
*info
= (HashIndexInfo
*) indInfo
;
574 CINDEX
*iptr
= (CINDEX
*)indexPtr
;
575 void *searchKey
=(void*)((char*)tuple
+ info
->fldOffset
);
576 TreeNode
*tnode
=NULL
;
577 TreeNode
*prev
= iter
;
579 DbRetVal ret
= TreeIndex::getTreeNodeMutex(iter
, db
->procSlot
, true);
581 printError(ErrLockTimeOut
,"Unable to lock the tree node. Retry...");
582 return ErrLockTimeOut
;
584 printDebug(DM_TreeIndex
," Tree I Level Mutex Taken on %x\n",iter
);
588 //get the second level last node as min and max are not stored in first level tree node
589 tnode
= (TreeNode
*)*((char**)((char*)((char*)iter
+ sizeof(TreeNode
))+ ((iter
->noElements_
-1)*sizeof(void *))));
590 char *record
= ((char*)tnode
->max_
)+ info
->fldOffset
;
591 result
= AllDataType::compareVal(searchKey
, record
,OpLessThanEquals
,info
->type
, info
->compLength
);
597 if(tnode
->noElements_
>= info
->noOfBuckets
)
599 if(iter
->next_
!=NULL
)
601 DbRetVal ret
= TreeIndex::getTreeNodeMutex(iter
->next_
, db
->procSlot
, true);
604 printError(ErrLockTimeOut
,"Unable to lock the tree node. Retry...");
605 iter
->mutex_
.releaseShareLock(db
->procSlot
);
606 printDebug(DM_TreeIndex
," Tree I Level Mutex Release on %x\n",iter
);
607 return ErrLockTimeOut
;
609 printDebug(DM_TreeIndex
," Tree I Level Mutex Taken on %x\n",iter
->next_
);
612 prev
->mutex_
.releaseShareLock(db
->procSlot
);
613 printDebug(DM_TreeIndex
," Tree I Level Mutex Release on %x\n",prev
);
620 if(iter
->next_
!=NULL
)
622 tnode
= (TreeNode
*)*((char**)((char*)((char*)iter
->next_
+ sizeof(TreeNode
))));
623 char *record
= ((char*)tnode
->min_
)+ info
->fldOffset
;
624 result
= AllDataType::compareVal(searchKey
, record
,OpLessThan
,info
->type
, info
->compLength
);
630 //if(iter->next_!=NULL)
632 DbRetVal ret
= TreeIndex::getTreeNodeMutex(iter
->next_
,
636 printError(ErrLockTimeOut
,"Unable to lock the tree node. Retry...");
637 iter
->mutex_
.releaseShareLock(db
->procSlot
);
638 printDebug(DM_TreeIndex
," Mutex Release on %x\n",iter
);
639 return ErrLockTimeOut
;
641 printDebug(DM_TreeIndex
," Mutex Taken on %x\n",iter
);
644 prev
->mutex_
.releaseShareLock(db
->procSlot
);
645 printDebug(DM_TreeIndex
," Mutex Release on %x\n",prev
);
659 //iter will be null if the value being inserted is greater
660 //than the last I-level node's II-level last node's max
661 if( iter
== NULL
&& prev
->noElements_
< info
->noOfBuckets
)
667 //TODO::Put this is another function and use the same from 1st record insert
668 //create Ist level node then leaf node ,insert record and return
669 printDebug(DM_TreeIndex
, "iter =NULL create Ist level node then leaf node ,insert record and return");
670 Chunk
*chunk
= (Chunk
*) iptr
->chunkPtr_
;
671 TreeNode
*tnode
= (TreeNode
*) chunk
->allocate(db
, &rv
);
674 printError(rv
, "Exit TreeNode allocate fail");
677 tnode
->mutex_
.init();
678 strcpy(tnode
->mutex_
.name
, "Tree");
681 tnode
->noElements_
=1;
685 char **rec
= (char**)((char*) tnode
+ sizeof(TreeNode
));
686 printDebug(DM_TreeIndex
, "Storing first record at %x\n", rec
);
687 *rec
= (char*) tuple
;
688 TreeNode
*prevNode
= (TreeNode
*)*(char**)((char*) prev
+sizeof(TreeNode
)+((prev
->noElements_
-1)* sizeof(void*)));
689 prevNode
->next_
= tnode
;
690 tnode
->prev_
= prevNode
;
692 Chunk
*ftchunk
= (Chunk
*) iptr
->chunkPtr_
;
693 TreeNode
*ftnode
= (TreeNode
*) ftchunk
->allocate(db
, &rv
);
696 printDebug(DM_TreeIndex
, "Exit TreeNode firstlevel allocate fail");
699 ftnode
->mutex_
.init("TNODE-I");
702 ftnode
->noElements_
=1;
703 ftnode
->next_
= NULL
;
704 ftnode
->balance_
= 0;
705 char **tn
=(char**)((char*) ftnode
+sizeof(TreeNode
));
709 prev
->mutex_
.releaseShareLock(db
->procSlot
);
710 printDebug(DM_TreeIndex
," Mutex Release on %x\n",prev
);
713 //Get second level node and node position from the
714 //first level node identified above as 'iter'
716 tnode
= locateNodeFromFirstLevel(iter
, indInfo
, tuple
, &nodepos
);
717 //first level mutex is taken and it is released in the below function
718 //This is because in case arrangement in first level node when it is full
719 //then subsequent first level node mutex is taken and current first level node
721 rv
= tnode
->insertRecordIntoNodeAndArrangeFirstLevel(db
, indInfo
, indexPtr
, tuple
, iter
, nodepos
);
725 TreeNode
* TreeNode::locateNode(Database
*db
, TreeNode
*iter
, void *tuple
, IndexInfo
*indInfo
,DbRetVal
&rv
)
727 if(iter
== NULL
) return NULL
;
728 HashIndexInfo
*info
= (HashIndexInfo
*) indInfo
;
729 void *searchKey
=(void*)((char*)tuple
+ info
->fldOffset
);
730 TreeNode
*tnode
=NULL
;
731 DbRetVal ret
= TreeIndex::getTreeNodeMutex(iter
, db
->procSlot
, true);
733 printError(ErrLockTimeOut
,"Unable to lock the tree node. Retry...");
737 printDebug(DM_TreeIndex
," Mutex Taken on %x\n",iter
);
738 TreeNode
*tmpNode
=NULL
;
739 while(iter
->noElements_
>= info
->noOfBuckets
&& iter
!= NULL
)
741 tnode
= (TreeNode
*)*((char**)((char*)iter
+ sizeof(TreeNode
)+ ((iter
->noElements_
-1)*sizeof(void *))));
742 char *record
= ((char*)tnode
->max_
)+ info
->fldOffset
;
743 bool result
= AllDataType::compareVal(searchKey
, record
,OpLessThanEquals
,info
->type
, info
->compLength
);
749 if(iter
->next_
!=NULL
)
751 DbRetVal ret
= TreeIndex::getTreeNodeMutex(iter
->next_
, db
->procSlot
, true);
754 printError(ErrLockTimeOut
,"Unable to lock the tree node. Retry...");
755 iter
->mutex_
.releaseShareLock(db
->procSlot
);
756 printDebug(DM_TreeIndex
," Mutex Release on %x\n",iter
);
760 printDebug(DM_TreeIndex
," Mutex Taken on %x\n",iter
->next_
);
763 tmpNode
->mutex_
.releaseShareLock(db
->procSlot
);
764 printDebug(DM_TreeIndex
," Mutex Release on %x\n",tmpNode
);
766 iter
->mutex_
.releaseShareLock(db
->procSlot
);
767 printDebug(DM_TreeIndex
," Mutex Release on %x\n",iter
);
777 TreeNode
*TreeNode::locateNodeFromFirstLevel(TreeNode
*ftnode
, IndexInfo
*indInfo
,void *tuple
, int *pos
)
779 HashIndexInfo
*info
= (HashIndexInfo
*) indInfo
;
780 int fldOffset
= info
->fldOffset
;
781 DataType type
= info
->type
;
782 int length
= info
->compLength
;
783 void *searchKey
=(void*)((char*)tuple
+ info
->fldOffset
);
784 int loc
=0, middle
= 0, start
= 0, end
= ftnode
->noElements_
-1;
785 char **node
= (char**)((char*)ftnode
+ sizeof(TreeNode
));
787 for(middle
= (start
+ end
) / 2; start
<= end
; middle
= (start
+end
)/2)
790 char *record
=(char *)(((TreeNode
*) *(char**)((char*)node
+ (loc
* sizeof(void *))))->max_
)+fldOffset
;
792 bool res
= AllDataType::compareVal(searchKey
, record
, OpLessThan
,type
, length
);
799 res
= AllDataType::compareVal(searchKey
, record
, OpGreaterThan
, type
, length
);
802 if(start
<= (ftnode
->noElements_
-1)) loc
= start
;
809 printDebug(DM_TreeIndex
, "inside locateNodeFromFirstLevel loc=%d",loc
);
811 tNode
= ((TreeNode
*)*(char**)((char*)node
+ (loc
* sizeof(void *))));