Procmgmt second patch:
[csql.git] / src / server / DatabaseManagerImpl.cxx
blobef36cd9207e75464a04028da028f95d79c21fbb1
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<Database.h>
17 #include<DatabaseManager.h>
18 #include<DatabaseManagerImpl.h>
19 #include<os.h>
20 #include<Table.h>
21 #include<TableImpl.h>
22 #include<Transaction.h>
23 #include<CatalogTables.h>
24 #include<Index.h>
25 #include<Lock.h>
26 #include<Debug.h>
27 #include<Config.h>
28 #include<Process.h>
31 DatabaseManagerImpl::~DatabaseManagerImpl()
33 //Note:Databases are closed by the session interface
34 delete tMgr_;
35 delete lMgr_;
38 void DatabaseManagerImpl::createLockManager()
40 lMgr_ = new LockManager(systemDatabase_);
41 return;
44 void DatabaseManagerImpl::createTransactionManager()
47 tMgr_ = new TransactionManager();
48 tMgr_->setFirstTrans(systemDatabase_->getSystemDatabaseTrans(0));
49 return;
52 DbRetVal DatabaseManagerImpl::openSystemDatabase()
54 DbRetVal rv = openDatabase(SYSTEMDB);
55 if (rv != OK) return rv;
56 systemDatabase_ = db_;
57 db_ = NULL;
58 if (NULL == systemDatabase_)
60 printError(ErrAlready, "Database is already opened");
61 return ErrAlready;
63 printDebug(DM_Database, "Opened system database");
64 logFinest(logger, "Opened system database");
65 return OK;
68 DbRetVal DatabaseManagerImpl::closeSystemDatabase()
70 Database *db = db_;
71 //make them to point to system database file descriptor
72 //and database pointer
73 db_ = systemDatabase_;
74 closeDatabase();
75 db_ = db;
76 printDebug(DM_Database, "Closed system database");
77 logFinest(logger, "Closed System database");
78 return OK;
81 DbRetVal DatabaseManagerImpl::createDatabase(const char *name, size_t size)
83 if (NULL != db_ )
85 printError(ErrAlready, "Database is already created");
86 return ErrAlready;
88 caddr_t rtnAddr = (caddr_t) NULL;
89 shared_memory_id shm_id = 0;
91 char *startaddr = (char*)Conf::config.getMapAddress();
92 shared_memory_key key = 0;
93 if (0 == strcmp(name, SYSTEMDB))
96 key = Conf::config.getSysDbKey();
98 else
100 startaddr = startaddr + Conf::config.getMaxSysDbSize();
101 key = Conf::config.getUserDbKey();
103 shm_id = os::shm_create(key, size, 0666);
104 if (-1 == shm_id)
106 printError(ErrOS, "Shared memory create failed");
107 return ErrOS;
110 void *shm_ptr = os::shm_attach(shm_id, startaddr, SHM_RND);
111 rtnAddr = (caddr_t) shm_ptr;
112 if (rtnAddr < 0 || shm_ptr == (char*)0xffffffff)
114 printError(ErrOS, "Shared memory attach returned -ve value %d", rtnAddr);
115 return ErrOS;
117 memset(shm_ptr, 0, size );
118 db_ = new Database();
119 printDebug(DM_Database, "Creating database:%s",name);
121 //TODO:for user database do not have transtable and processtable mutex
122 db_->setMetaDataPtr((DatabaseMetaData*)rtnAddr);
123 db_->setDatabaseID(1);
124 db_->setName(name);
125 db_->setMaxSize(size);
126 db_->setMaxChunks(MAX_CHUNKS);
127 db_->initAllocDatabaseMutex();
128 db_->initTransTableMutex();
129 db_->initDatabaseMutex();
130 db_->initProcessTableMutex();
132 //compute the first page after book keeping information
133 size_t offset = os::alignLong(sizeof (DatabaseMetaData));
134 //Only for system db chunk array, trans array and proc array will be there
135 if (0 == strcmp(name, SYSTEMDB))
137 offset = offset + os::alignLong( MAX_CHUNKS * sizeof (Chunk));
138 offset = offset + os::alignLong( Conf::config.getMaxTrans() * sizeof(Transaction));
139 offset = offset + os::alignLong( Conf::config.getMaxProcs() * sizeof(ThreadInfo));
140 //offset = offset + os::alignLong( Conf::config.getMaxProcs() *
141 // Conf::config.getMaxThreads() * sizeof(ThreadInfo));
143 int multiple = os::floor(offset / PAGE_SIZE);
144 char *curPage = (((char*)rtnAddr) + ((multiple + 1) * PAGE_SIZE));
146 db_->setCurrentPage(curPage);
147 db_->setFirstPage(curPage);
149 if (0 == strcmp(name, SYSTEMDB)) return OK;
151 //Allocate new chunk to store hash index nodes
152 Chunk *chunkInfo = createUserChunk(sizeof(HashIndexNode));
153 if (NULL == chunkInfo)
155 printError(ErrSysInternal, "Failed to allocate hash index nodes chunk");
156 return ErrSysInternal;
158 printDebug(DM_Database, "Creating Chunk for storing Hash index nodes %x",
159 chunkInfo);
161 db_->setHashIndexChunk(chunkInfo);
162 logFinest(logger, "Created database %s" , name);
164 return OK;
167 DbRetVal DatabaseManagerImpl::deleteDatabase(const char *name)
169 shared_memory_id shm_id = 0;
170 if (0 == strcmp(name, SYSTEMDB))
172 shm_id = os::shm_open(Conf::config.getSysDbKey(), 100, 0666);
173 os::shmctl(shm_id, IPC_RMID);
174 } else {
175 shm_id = os::shm_open(Conf::config.getUserDbKey(), 100, 0666);
176 os::shmctl(shm_id, IPC_RMID);
178 logFinest(logger, "Deleted database %s" , name);
179 return OK;
182 DbRetVal DatabaseManagerImpl::openDatabase(const char *name)
184 long size = Conf::config.getMaxSysDbSize();
185 char *startaddr = (char*)Conf::config.getMapAddress();
186 if (0 == strcmp(name , SYSTEMDB))
188 if (NULL !=systemDatabase_)
190 printError(ErrAlready, "System Database already open");
191 return ErrAlready;
194 else
196 if (NULL ==systemDatabase_)
198 printError(ErrNotOpen, "System Database not open");
199 return ErrNotOpen;
201 size = Conf::config.getMaxDbSize();
202 startaddr = startaddr + Conf::config.getMaxSysDbSize();
204 if (NULL != db_)
206 printError(ErrAlready, "User Database already open");
207 return ErrAlready;
209 caddr_t attAddr;
210 if (0 == strcmp(name, SYSTEMDB))
211 attAddr = ProcessManager::sysAddr;
212 else
213 attAddr = ProcessManager::usrAddr;
215 //system db should be opened before user database files
216 caddr_t rtnAddr = (caddr_t) NULL;
218 shared_memory_id shm_id = 0;
219 shared_memory_key key = 0;
221 if (0 == strcmp(name, SYSTEMDB))
222 key = Conf::config.getSysDbKey();
223 else
224 key = Conf::config.getUserDbKey();
227 int ret = ProcessManager::mutex.tryLock();
228 //If you are not getting lock ret !=0, it means somebody else is there.
229 //he will close the database.
230 if (ret != 0)
232 printError(ErrSysInternal, "Another thread calling open:Wait and then Retry\n");
233 return ErrSysInternal;
235 void *shm_ptr = NULL;
236 if (ProcessManager::noThreads == 0 ) {
237 shm_id = os::shm_open(key, size, 0666);
238 if (shm_id == -1 )
240 printError(ErrOS, "Shared memory open failed");
241 return ErrOS;
243 shm_ptr = os::shm_attach(shm_id, startaddr, SHM_RND);
244 if (0 == strcmp(name, SYSTEMDB))
245 ProcessManager::sysAddr = (char*) shm_ptr;
246 else
247 ProcessManager::usrAddr = (char*) shm_ptr;
248 } else {
249 if (0 == strcmp(name, SYSTEMDB))
250 shm_ptr = ProcessManager::sysAddr;
251 else
252 shm_ptr = ProcessManager::usrAddr;
254 ProcessManager::mutex.releaseLock();
257 rtnAddr = (caddr_t) shm_ptr;
259 if (rtnAddr < 0 || shm_ptr == (char*)0xffffffff)
261 printError(ErrOS, "Shared memory attach returned -ve value %x %d", shm_ptr, errno);
262 return ErrOS;
264 else
266 db_ = new Database();
267 db_->setMetaDataPtr((DatabaseMetaData*)rtnAddr);
268 printDebug(DM_Database, "Opening database: %s", name);
269 logFinest(logger, "Opened database %s" , name);
270 return OK;
272 db_ = new Database();
273 printDebug(DM_Database, "Opening database: %s", name);
274 db_->setMetaDataPtr((DatabaseMetaData*)attAddr);
275 logFinest(logger, "Opened database %s" , name);
276 return OK;
279 DbRetVal DatabaseManagerImpl::closeDatabase()
282 if (NULL == db_)
284 printError(ErrAlready, "Database is already closed\n");
285 return ErrAlready;
287 printDebug(DM_Database, "Closing database: %s",(char*)db_->getName());
288 //check if this is the last thread to be deregistered
289 int ret = ProcessManager::mutex.getLock();
290 //If you are not getting lock ret !=0, it means somebody else is there.
291 //he will close the database.
292 if (ret == 0 && ProcessManager::noThreads == 0)
293 os::shm_detach((char*)db_->getMetaDataPtr());
294 ProcessManager::mutex.releaseLock();
295 logFinest(logger, "Closed database");
297 delete db_;
298 db_ = NULL;
300 //Assumes that system database mutex is taken before calling this.
301 Chunk* DatabaseManagerImpl::createUserChunk(size_t size)
303 //Allocate new node in system database to store
304 Chunk *chunk = getSystemTableChunk(UserChunkTableId);
305 void *ptr = chunk->allocate(systemDatabase_);
306 if (NULL == ptr)
308 printError(ErrNoMemory, "Allocation failed for User chunk catalog table");
309 return NULL;
311 Chunk *chunkInfo = (Chunk*)ptr;
312 chunkInfo->initMutex();
313 if (0 != size) chunkInfo->setSize(size);
314 if (chunkInfo->allocSize_ > PAGE_SIZE)
315 chunkInfo->curPage_ = db_->getFreePage(chunkInfo->allocSize_);
316 else
317 chunkInfo->curPage_ = db_->getFreePage();
318 if ( NULL == chunkInfo->curPage_)
320 chunkInfo->destroyMutex();
321 chunk->free(db_, ptr);
322 printError(ErrNoMemory, "Database full: No space to allocate from database");
323 return NULL;
325 PageInfo* firstPageInfo = ((PageInfo*)chunkInfo->curPage_);
326 if (chunkInfo->allocSize_ > PAGE_SIZE)
328 int multiple = os::floor(chunkInfo->allocSize_ / PAGE_SIZE);
329 int offset = ((multiple + 1) * PAGE_SIZE);
330 firstPageInfo->setPageAsUsed(offset);
332 else
333 firstPageInfo->setPageAsUsed(chunkInfo->allocSize_);
334 if (0 == size)
336 VarSizeInfo *varInfo = (VarSizeInfo*)(((char*)firstPageInfo) + sizeof(PageInfo));
337 varInfo->isUsed_ = 0;
338 varInfo->size_ = PAGE_SIZE - sizeof(PageInfo) - sizeof(VarSizeInfo);
341 chunkInfo->firstPage_ = chunkInfo->curPage_;
343 if (0 == size)
344 chunkInfo->setAllocType(VariableSizeAllocator);
345 else
346 chunkInfo->setAllocType(FixedSizeAllocator);
348 //TODO::Generate chunkid::use tableid
349 chunkInfo->setChunkID(-1);
350 printDebug(DM_Database, "Creating new User chunk chunkID:%d size: %d firstPage:%x",
351 -1, chunkInfo->allocSize_, firstPageInfo);
353 return chunkInfo;
357 //Assumes that system database mutex is taken before calling this.
358 DbRetVal DatabaseManagerImpl::deleteUserChunk(Chunk *chunk)
360 //Go to the pages and set them to notUsed
361 Page *page = chunk->firstPage_;
362 PageInfo* pageInfo = ((PageInfo*)page);
363 //Here...sure that atleast one page will be there even no tuples
364 //are inserted.so not checking if pageInfo == NULL
365 while( pageInfo->nextPage_ != NULL)
367 PageInfo *prev = pageInfo;
368 pageInfo = (PageInfo*)(pageInfo->nextPage_);
369 //sets pageInfo->isUsed_ = 0 and pageInfo->hasFreeSpace_ = 0
370 //and initializes the page content to zero
371 if(NULL == pageInfo->nextPageAfterMerge_)
372 os::memset(prev, 0, PAGE_SIZE);
373 else
375 int size = (char*) pageInfo->nextPageAfterMerge_ - (char*) pageInfo;
376 os::memset(prev, 0, size);
378 printDebug(DM_Database,"deleting user chunk:%x clearing page %x",chunk, prev);
380 //The above loop wont execute for the last page
381 //and for the case where table has only one page
382 if(NULL == pageInfo->nextPageAfterMerge_)
383 os::memset(pageInfo, 0, PAGE_SIZE);
384 else
386 int size = (char*) pageInfo->nextPageAfterMerge_ - (char*) pageInfo;
387 os::memset(pageInfo, 0, size);
389 printDebug(DM_Database,"deleting user chunk:%x clearing page %x",chunk, pageInfo);
390 chunk->chunkID_ = -1;
391 chunk->allocSize_ = 0;
392 chunk->curPage_ = NULL;
393 chunk->firstPage_ = NULL;
394 chunk->destroyMutex();
395 printDebug(DM_Database,"deleting user chunk:%x",chunk);
396 return OK;
399 //-1 -> Unable to create chunk. No memory
400 //-2 -> Unable to update the catalog tables
401 DbRetVal DatabaseManagerImpl::createTable(const char *name, TableDef &def)
403 DbRetVal rv = OK;
404 size_t sizeofTuple = def.getTupleSize();
405 rv = systemDatabase_->getDatabaseMutex();
406 if (OK != rv ) {
407 printError(rv, "Unable to get Database mutex");
408 return rv;
410 //create a chunk to store the tuples
411 Chunk *ptr = createUserChunk(sizeofTuple);
412 if (NULL == ptr)
414 systemDatabase_->releaseDatabaseMutex();
415 printError(ErrNoResource, "Unable to create user chunk");
416 return ErrNoResource;
418 printDebug(DM_Database,"Created UserChunk:%x", ptr);
419 //add row to TABLE
420 CatalogTableTABLE cTable(systemDatabase_);
421 int tblID = ((Chunk*)ptr)->getChunkID();
422 void *tptr = NULL;
423 rv = cTable.insert(name, tblID, sizeofTuple,
424 def.getFieldCount(), ptr, tptr);
425 if (OK != rv)
427 deleteUserChunk(ptr);
428 systemDatabase_->releaseDatabaseMutex();
429 printError(ErrSysInternal, "Unable to update catalog table TABLE");
430 return ErrSysInternal;
432 printDebug(DM_Database,"Inserted into TABLE:%s",name);
433 //add rows to FIELD
434 FieldIterator iter = def.getFieldIterator();
435 CatalogTableFIELD cField(systemDatabase_);
436 rv = cField.insert(iter, tblID ,tptr);
437 if (OK != rv)
439 deleteUserChunk(ptr);
440 void *cptr, *ttptr;//Dummy as remove below needs both these OUT params
441 cTable.remove(name, cptr, ttptr);
442 systemDatabase_->releaseDatabaseMutex();
443 printError(ErrSysInternal, "Unable to update catalog table FIELD");
444 return ErrSysInternal;
446 printDebug(DM_Database,"Inserted into FIELD:%s",name);
447 systemDatabase_->releaseDatabaseMutex();
448 printDebug(DM_Database,"Table Created:%s",name);
449 logFinest(logger, "Table Created %s" , name);
450 return OK;
453 //TODO::If any operation fails in between, then we may have some
454 //dangling tuples, say we have have rows in INDEX table
455 //which will not have any corresponding entries in TABLE
456 //CHANGE the sequence so that it deletes from the bottom as
457 //opposed to start from top as is written now
458 DbRetVal DatabaseManagerImpl::dropTable(const char *name)
460 void *chunk = NULL;
461 void *tptr =NULL;
462 DbRetVal rv = systemDatabase_->getDatabaseMutex();
463 if (OK != rv) {
464 printError(ErrSysInternal, "Unable to get database mutex");
465 return ErrSysInternal;
468 //remove the entry in TABLE
469 CatalogTableTABLE cTable(systemDatabase_);
470 rv = cTable.remove(name, chunk, tptr);
471 if (OK != rv) {
472 systemDatabase_->releaseDatabaseMutex();
473 printError(ErrSysInternal, "Unable to update catalog table TABLE");
474 return ErrSysInternal;
476 printDebug(DM_Database,"Deleted from TABLE:%s",name);
478 //remove the entries in the FIELD table
479 CatalogTableFIELD cField(systemDatabase_);
480 rv = cField.remove(tptr);
481 if (OK != rv) {
482 systemDatabase_->releaseDatabaseMutex();
483 printError(ErrSysInternal, "Unable to update catalog table FIELD");
484 return ErrSysInternal;
486 printDebug(DM_Database,"Deleted from FIELD:%s",name);
488 rv = deleteUserChunk((Chunk*)chunk);
489 if (OK != rv) {
490 systemDatabase_->releaseDatabaseMutex();
491 printError(rv, "Unable to delete the chunk");
492 return rv;
494 printDebug(DM_Database,"Deleted UserChunk:%x", chunk);
496 //TODO::check whether indexes are available and drop that also.
497 CatalogTableINDEX cIndex(systemDatabase_);
498 int noIndexes = cIndex.getNumIndexes(tptr);
499 char *idxName;
500 for (int i =1 ; i<= noIndexes; i++) {
501 idxName = cIndex.getIndexName(tptr, i);
502 dropIndexInt(idxName, false);
504 Chunk *chunkNode = systemDatabase_->getSystemDatabaseChunk(UserChunkTableId);
505 chunkNode->free(systemDatabase_, (Chunk *) chunk);
506 systemDatabase_->releaseDatabaseMutex();
507 printDebug(DM_Database, "Deleted Table %s" , name);
508 logFinest(logger, "Deleted Table %s" , name);
509 return OK;
512 //Return values: NULL for table not found
513 Table* DatabaseManagerImpl::openTable(const char *name)
515 DbRetVal ret = OK;
516 //TODO::store table handles in list so that if it is
517 //not closed by the application. destructor shall close it.
518 TableImpl *table = new TableImpl();
519 table->setDB(db_);
520 table->setSystemDB(systemDatabase_);
521 table->setLockManager(lMgr_);
522 table->setTrans(&(tMgr_->trans));
524 //to store the chunk pointer of table
525 void *chunk = NULL;
527 //to store the tuple pointer of the table
528 void *tptr =NULL;
530 //TODO::need to take shared lock on the table so that
531 //all ddl operation will be denied on that table
532 //which includes index creation, alter table
534 DbRetVal rv = systemDatabase_->getDatabaseMutex();
535 if (OK != rv) {
536 printError(ErrSysInternal, "Unable to get database mutex");
537 return NULL;
539 CatalogTableTABLE cTable(systemDatabase_);
540 ret = cTable.getChunkAndTblPtr(name, chunk, tptr);
541 if ( OK != ret)
543 printError(ErrNotExists, "Table not exists %s", name);
544 return NULL;
546 TABLE *tTuple = (TABLE*)tptr;
547 table->setTableInfo(tTuple->tblName_, tTuple->tblID_, tTuple->length_,
548 tTuple->numFlds_, tTuple->numIndexes_, tTuple->chunkPtr_);
550 //get field information from FIELD table
551 CatalogTableFIELD cField(systemDatabase_);
552 cField.getFieldInfo(tptr, table->fldList_);
554 //get the number of indexes on this table
555 //and populate the indexPtr array
556 CatalogTableINDEX cIndex(systemDatabase_);
557 table->numIndexes_ = cIndex.getNumIndexes(tptr);
558 if (table->numIndexes_)
559 table->indexPtr_ = new char*[table->numIndexes_];
560 else
561 table->indexPtr_ = NULL;
562 cIndex.getIndexPtrs(tptr, table->indexPtr_);
564 //HACK:Below works only for one hash index on table
565 if (table->numIndexes_ == 1)
567 SingleFieldHashIndexInfo *hIdxInfo = new SingleFieldHashIndexInfo();
568 CatalogTableINDEXFIELD cIndexField(systemDatabase_);
569 cIndexField.getFieldNameAndType(table->indexPtr_[0], hIdxInfo->fldName,
570 hIdxInfo->type);
571 ChunkIterator citer = CatalogTableINDEX::getIterator(table->indexPtr_[0]);
572 hIdxInfo->noOfBuckets = CatalogTableINDEX::getNoOfBuckets(table->indexPtr_[0]);
573 hIdxInfo->buckets = (Bucket*)citer.nextElement();
575 table->idxInfo = (IndexInfo*) hIdxInfo;
577 systemDatabase_->releaseDatabaseMutex();
578 printDebug(DM_Database,"Opening table handle name:%s chunk:%x numIndex:%d",
579 name, chunk, table->numIndexes_);
580 logFinest(logger, "Opening Table %s" , name);
582 return table;
587 List DatabaseManagerImpl::getAllTableNames()
589 DbRetVal ret = OK;
590 //to store the tuple pointer of the table
591 void *tptr =NULL;
593 DbRetVal rv = systemDatabase_->getDatabaseMutex();
594 if (OK != rv) {
595 printError(ErrSysInternal, "Unable to get database mutex");
596 List tableList;
597 return tableList;
599 CatalogTableTABLE cTable(systemDatabase_);
600 List tableList = cTable.getTableList();
601 systemDatabase_->releaseDatabaseMutex();
602 return tableList;
608 //Return values: -1 for table not found
609 void DatabaseManagerImpl::closeTable(Table *table)
611 printDebug(DM_Database,"Closing table handle: %x", table);
612 if (NULL == table) return;
613 delete table;
614 logFinest(logger, "Closing Table");
617 DbRetVal DatabaseManagerImpl::createIndex(const char *indName, IndexInitInfo *info)
619 DbRetVal rv = OK;
620 if (info->indType == hashIndex)
622 //Assumes info is of type HashIndexInitInfo
623 HashIndexInitInfo *hInfo = (HashIndexInitInfo*) info;
624 rv = createHashIndex(indName, info->tableName, info->list, hInfo->bucketSize);
626 else
628 //TODO::tree index
630 return rv;
634 //-1 -> Table does not exists
635 //-2 -> Field does not exists
636 //-3 -> bucketSize is not valid
637 DbRetVal DatabaseManagerImpl::createHashIndex(const char *indName, const char *tblName,
638 FieldNameList &fldList, int bucketSize)
640 //validate the bucket size
641 if (bucketSize < 100 || bucketSize > 200000)
643 printError(ErrBadRange, "Index Bucket size %d not in range 100-200000",
644 bucketSize);
645 return ErrBadRange;
647 void *tptr =NULL;
648 void *chunk = NULL;
649 DbRetVal rv = systemDatabase_->getDatabaseMutex();
650 if (OK != rv)
652 printError(ErrSysInternal, "Unable to get database mutex");
653 return ErrSysInternal;
656 //check whether table exists
657 CatalogTableTABLE cTable(systemDatabase_);
658 cTable.getChunkAndTblPtr(tblName, chunk, tptr);
659 if (NULL == tptr)
661 systemDatabase_->releaseDatabaseMutex();
662 printError(ErrNotExists, "Table does not exist %s", tblName);
663 return ErrNotExists;
665 int totFlds = fldList.size();
667 //check whether field exists
668 char **fptr = new char* [totFlds];
669 CatalogTableFIELD cField(systemDatabase_);
670 rv = cField.getFieldPtrs(fldList, tptr, fptr);
671 if (OK != rv)
673 delete[] fptr;
674 systemDatabase_->releaseDatabaseMutex();
675 printError(ErrNotExists, "Field does not exist");
676 return ErrNotExists;
679 //create chunk to store the meta data of the index created
680 //for latches and bucket pointers
681 Chunk* chunkInfo = createUserChunk(bucketSize * sizeof(Bucket));
682 if (NULL == chunkInfo)
684 delete[] fptr;
685 systemDatabase_->releaseDatabaseMutex();
686 printError(ErrSysInternal, "Unable to create chunk");
687 return ErrSysInternal;
689 //create memory for holding the bucket pointers
690 void *buckets = chunkInfo->allocate(db_);
691 if (NULL == buckets)
693 delete[] fptr;
694 deleteUserChunk(chunkInfo);
695 systemDatabase_->releaseDatabaseMutex();
696 printError(ErrNoMemory, "Unable to allocate memory for bucket");
697 return ErrNoMemory;
699 Bucket *buck = (Bucket*) buckets;
700 initHashBuckets(buck, bucketSize);
702 //create chunk to store the hash index nodes
703 Chunk* hChunk = createUserChunk(sizeof(HashIndexNode));
704 if (NULL == hChunk)
706 delete[] fptr;
707 deleteUserChunk(chunkInfo);
708 systemDatabase_->releaseDatabaseMutex();
709 printError(ErrSysInternal, "Unable to create chunk for storing hash index nodes");
710 return ErrSysInternal;
714 //add row to INDEX
715 void *tupleptr = NULL;
716 CatalogTableINDEX cIndex(systemDatabase_);
717 DbRetVal ret = cIndex.insert(indName, tptr, fldList.size(),
718 chunkInfo, bucketSize, hChunk, tupleptr);
719 if (OK != rv)
721 delete[] fptr;
722 deleteUserChunk(hChunk);
723 deleteUserChunk(chunkInfo);
724 systemDatabase_->releaseDatabaseMutex();
725 printError(ErrSysInternal, "Catalog table updation failed in INDEX table");
726 return ErrSysInternal;
728 //add rows to INDEXFIELD
729 CatalogTableINDEXFIELD cIndexField(systemDatabase_);
730 ret = cIndexField.insert(fldList, tupleptr, tptr, fptr);
732 if (OK != rv)
734 delete[] fptr;
735 deleteUserChunk(hChunk);
736 deleteUserChunk(chunkInfo);
737 systemDatabase_->releaseDatabaseMutex();
738 printError(ErrSysInternal, "Catalog table updation failed in INDEXFIELD table");
739 return ErrSysInternal;
741 delete[] fptr;
742 //TODO::If tuples present in this table, then
743 //create hash index nodes and store it
744 //Take table lock
745 systemDatabase_->releaseDatabaseMutex();
746 printDebug(DM_Database, "Creating Hash Index Name:%s tblname:%s buckets:%x",
747 indName, tblName, buckets);
748 logFinest(logger, "Creating HashIndex %s on %s with bucket size %d",
749 indName, tblName, buckets);
750 return OK;
753 void DatabaseManagerImpl::initHashBuckets(Bucket *buck, int bucketSize)
755 os::memset((void*)buck, 0, bucketSize * sizeof(Bucket));
757 for (int i=0; i < bucketSize ; i++)
759 buck[i].mutex_.init();
761 return;
764 DbRetVal DatabaseManagerImpl::dropIndex(const char *name)
766 return dropIndexInt(name, true);
769 DbRetVal DatabaseManagerImpl::dropIndexInt(const char *name, bool takeLock)
771 DbRetVal rv = OK;
772 void *chunk = NULL, *hchunk = NULL;
773 void *tptr =NULL;
774 int ret = 0;
775 if (takeLock) {
776 rv = systemDatabase_->getDatabaseMutex();
777 if (OK != rv)
779 printError(ErrSysInternal, "Unable to get database mutex");
780 return ErrSysInternal;
784 //remove the entry in INDEX
785 CatalogTableINDEX cIndex(systemDatabase_);
786 rv = cIndex.remove(name, chunk, hchunk, tptr);
787 if (OK != rv)
789 if (takeLock) systemDatabase_->releaseDatabaseMutex();
790 printError(ErrSysInternal, "Catalog table updation failed for INDEX table");
791 return ErrSysInternal;
793 printDebug(DM_Database, "Removing from INDEX %s",name);
794 //remove the entries in the INDEXFIELD table
795 CatalogTableINDEXFIELD cIndexField(systemDatabase_);
796 rv = cIndexField.remove(tptr);
797 if (OK != rv)
799 if (takeLock) systemDatabase_->releaseDatabaseMutex();
800 printError(ErrSysInternal, "Catalog table updation failed for INDEX table");
801 return ErrSysInternal;
803 printDebug(DM_Database, "Removing from INDEXFIELD %s",name);
805 //delete the index chunk
806 rv = deleteUserChunk((Chunk*)chunk);
807 if (OK != rv)
809 if (takeLock) systemDatabase_->releaseDatabaseMutex();
810 printError(ErrSysInternal, "Unable to delete the index chunk");
811 return ErrSysInternal;
813 //delete the index hash node chunk
814 rv = deleteUserChunk((Chunk*)hchunk);
815 if (OK != rv)
817 if (takeLock) systemDatabase_->releaseDatabaseMutex();
818 printError(ErrSysInternal, "Unable to delete the index hash node chunk");
819 return ErrSysInternal;
821 if (takeLock) systemDatabase_->releaseDatabaseMutex();
822 Chunk *chunkNode = systemDatabase_->getSystemDatabaseChunk(UserChunkTableId);
823 chunkNode->free(systemDatabase_, (Chunk *) chunk);
824 chunkNode->free(systemDatabase_, (Chunk *) hchunk);
826 //TODO::If tuples present in this table, then
827 //free all hash index nodes for this table.
828 //free all nodes in list of all buckets
829 //Take table lock
831 printDebug(DM_Database, "Dropped hash index %s",name);
832 logFinest(logger, "Deleted Index %s", name);
833 return OK;
836 DbRetVal DatabaseManagerImpl::registerThread()
838 DbRetVal rv = OK;
839 if (pMgr_ != NULL)
841 printError(ErrAlready, "Process already registered\n");
842 return ErrAlready;
844 pMgr_ = new ProcessManager(sysDb());
845 return pMgr_->registerThread();
848 DbRetVal DatabaseManagerImpl::deregisterThread()
850 if (pMgr_ == NULL)
852 printError(ErrBadCall, "Process already deregistered or never registered\n");
853 return ErrBadCall;
855 DbRetVal rv = pMgr_->deregisterThread();
856 delete pMgr_;
857 pMgr_ = NULL;
858 return rv;
861 ChunkIterator DatabaseManagerImpl::getSystemTableIterator(CatalogTableID id)
863 Chunk *fChunk = systemDatabase_->getSystemDatabaseChunk(id);
864 return fChunk->getIterator();
867 Chunk* DatabaseManagerImpl::getSystemTableChunk(CatalogTableID id)
869 return systemDatabase_->getSystemDatabaseChunk(id);