18 #include <ndb_global.h>
19 #include "DictCache.hpp"
20 #include "NdbDictionaryImpl.hpp"
22 #include <NdbCondition.h>
28 static int ndb_dict_cache_count = 0;
31 Ndb_local_table_info::create(
NdbTableImpl *table_impl, Uint32 sz)
33 assert(! is_ndb_blob_table(table_impl));
36 void *data= malloc(tot_size);
39 memset(data, 0, tot_size);
49 Ndb_local_table_info::Ndb_local_table_info(
NdbTableImpl *table_impl)
51 assert(! is_ndb_blob_table(table_impl));
52 m_table_impl= table_impl;
53 m_tuple_id_range.reset();
56 Ndb_local_table_info::~Ndb_local_table_info()
60 LocalDictCache::LocalDictCache(){
61 m_tableHash.createHashTable();
64 LocalDictCache::~LocalDictCache(){
65 m_tableHash.releaseHashTable();
69 LocalDictCache::get(
const char *
name){
71 assert(! is_ndb_blob_table(name));
72 const Uint32 len = (Uint32)strlen(name);
73 return m_tableHash.getData(name, len);
79 assert(! is_ndb_blob_table(name));
80 const Uint32
id = tab_info->m_table_impl->m_id;
81 m_tableHash.
insertKey(name, (Uint32)strlen(name),
id, tab_info);
85 LocalDictCache::drop(
const char * name){
87 assert(! is_ndb_blob_table(name));
89 DBUG_ASSERT(info != 0);
90 Ndb_local_table_info::destroy(info);
96 GlobalDictCache::GlobalDictCache(){
97 DBUG_ENTER(
"GlobalDictCache::GlobalDictCache");
98 m_tableHash.createHashTable();
99 m_waitForTableCondition = NdbCondition_Create();
100 if (f_invalid_table == NULL)
102 if (f_altered_table == NULL)
104 ndb_dict_cache_count++;
108 GlobalDictCache::~GlobalDictCache(){
109 DBUG_ENTER(
"GlobalDictCache::~GlobalDictCache");
110 if (--ndb_dict_cache_count == 0)
114 delete f_invalid_table;
119 delete f_altered_table;
126 const unsigned sz = vers->size();
127 for(
unsigned i = 0;
i<sz ;
i++){
128 TableVersion tv= (*vers)[
i];
129 DBUG_PRINT(
" ", (
"vers[%d]: ver: %d, refCount: %d, status: %d",
130 i, tv.m_version, tv.m_refCount, tv.m_status));
133 DBUG_PRINT(
" ", (
"m_impl: internalname: %s",
134 tv.m_impl->m_internalName.c_str()));
135 delete (* vers)[
i].m_impl;
138 delete curr->theData;
140 curr = m_tableHash.getNext(curr);
142 m_tableHash.releaseHashTable();
143 NdbCondition_Destroy(m_waitForTableCondition);
147 void GlobalDictCache::printCache()
149 DBUG_ENTER(
"GlobalDictCache::printCache");
152 DBUG_PRINT(
"curr", (
"len: %d, hash: %d, lk: %d, str: %s",
153 curr->len, curr->hash, curr->localkey1,
157 const unsigned sz = vers->size();
158 for(
unsigned i = 0;
i<sz ;
i++){
159 TableVersion tv= (*vers)[
i];
160 DBUG_PRINT(
" ", (
"impl: %p vers[%d]: ver: %d, refCount: %d, status: %d",
161 tv.m_impl,
i, tv.m_version, tv.m_refCount, tv.m_status));
164 DBUG_PRINT(
" ", (
"m_impl: internalname: %s",
165 tv.m_impl->m_internalName.c_str()));
171 DBUG_PRINT(
" ", (
"NULL"));
173 curr = m_tableHash.getNext(curr);
181 DBUG_ENTER(
"GlobalDictCache::get");
182 DBUG_PRINT(
"enter", (
"name: %s", name));
183 assert(! is_ndb_blob_table(name));
185 const Uint32 len = (Uint32)strlen(name);
187 versions = m_tableHash.getData(name, len);
190 if (versions == NULL)
195 m_tableHash.
insertKey(name, len, 0, versions);
200 bool retreive =
false;
201 while(versions->size() > 0 && !retreive){
202 TableVersion * ver = & versions->back();
203 switch(ver->m_status){
207 ver->m_status = DROPPED;
209 if (ver->m_refCount == 0)
212 versions->erase(versions->size() - 1);
217 DBUG_PRINT(
"info", (
"Table OK tab: %p version=%x.%x refCount=%u",
219 ver->m_impl->m_version & 0xFFFFFF,
220 ver->m_impl->m_version >> 24,
222 DBUG_RETURN(ver->m_impl);
227 DBUG_PRINT(
"info", (
"Wait for retrieving thread"));
228 NdbCondition_WaitTimeout(m_waitForTableCondition, m_mutex, waitTime);
239 tmp.m_status = RETREIVING;
241 if (versions->push_back(tmp))
246 DBUG_PRINT(
"info", (
"No table found"));
251 GlobalDictCache::put(
const char * name,
NdbTableImpl * tab)
253 DBUG_ENTER(
"GlobalDictCache::put");
254 DBUG_PRINT(
"enter", (
"tab: %p name: %s, internal_name: %s version: %x.%x",
256 tab ? tab->m_internalName.
c_str() :
"tab NULL",
257 tab ? tab->m_version & 0xFFFFFF : 0,
258 tab ? tab->m_version >> 24 : 0));
259 assert(! is_ndb_blob_table(name));
261 const Uint32 len = (Uint32)strlen(name);
269 const Uint32 sz = vers->size();
276 TableVersion & ver = vers->back();
277 if(ver.m_status != RETREIVING ||
279 ver.m_impl == f_invalid_table || ver.m_impl == f_altered_table) ||
280 ver.m_version != 0 ||
281 ver.m_refCount == 0){
287 DBUG_PRINT(
"info", (
"No table found in db"));
290 else if (ver.m_impl == 0) {
291 DBUG_PRINT(
"info", (
"Table OK"));
293 ver.m_version = tab->m_version;
296 else if (ver.m_impl == f_invalid_table)
298 DBUG_PRINT(
"info", (
"Table DROPPED invalid"));
300 ver.m_version = tab->m_version;
301 ver.m_status = DROPPED;
304 else if(ver.m_impl == f_altered_table)
306 DBUG_PRINT(
"info", (
"Table DROPPED altered"));
308 ver.m_version = tab->m_version;
309 ver.m_status = DROPPED;
316 NdbCondition_Broadcast(m_waitForTableCondition);
321 GlobalDictCache::get_size()
326 sz += curr->theData->size();
327 curr = m_tableHash.getNext(curr);
337 GlobalDictCache::invalidate_all()
339 DBUG_ENTER(
"GlobalDictCache::invalidate_all");
345 TableVersion * ver = & vers->back();
346 if (ver->m_status != RETREIVING)
349 ver->m_status = DROPPED;
350 if (ver->m_refCount == 0)
353 vers->erase(vers->size() - 1);
357 curr = m_tableHash.getNext(curr);
363 GlobalDictCache::invalidateDb(
const char * name,
size_t len)
365 DBUG_ENTER(
"GlobalDictCache::invalidateDb");
372 TableVersion * ver = & vers->back();
373 if (ver->m_status != RETREIVING)
375 if (ver->m_impl->matchDb(name, len))
378 ver->m_status = DROPPED;
379 if (ver->m_refCount == 0)
382 vers->erase(vers->size() - 1);
387 curr = m_tableHash.getNext(curr);
393 GlobalDictCache::release(
const NdbTableImpl * tab,
int invalidate)
395 DBUG_ENTER(
"GlobalDictCache::release");
396 DBUG_PRINT(
"enter", (
"tab: %p internal_name: %s",
397 tab, tab->m_internalName.
c_str()));
398 assert(! is_ndb_blob_table(tab));
401 const Uint32 len = (Uint32)strlen(tab->m_internalName.
c_str());
403 m_tableHash.getData(tab->m_internalName.
c_str(), len);
410 const Uint32 sz = vers->size();
417 for(i = 0; i < sz; i++){
418 TableVersion & ver = (* vers)[
i];
419 if(ver.m_impl == tab){
420 if(ver.m_refCount == 0 || ver.m_status == RETREIVING ||
421 ver.m_version != tab->m_version){
422 DBUG_PRINT(
"info", (
"Releasing with refCount=%d status=%d impl=%p",
423 ver.m_refCount, ver.m_status, ver.m_impl));
431 ver.m_status = DROPPED;
433 if (ver.m_refCount == 0 && ver.m_status == DROPPED)
435 DBUG_PRINT(
"info", (
"refCount is zero, deleting m_impl"));
443 for(i = 0; i<sz; i++){
444 TableVersion & ver = (* vers)[
i];
445 ndbout_c(
"%d: version: %d refCount: %d status: %d impl: %p",
446 i, ver.m_version, ver.m_refCount,
447 ver.m_status, ver.m_impl);
454 GlobalDictCache::alter_table_rep(
const char * name,
459 DBUG_ENTER(
"GlobalDictCache::alter_table_rep");
460 const Uint32 len = (Uint32)strlen(name);
462 m_tableHash.getData(name, len);
469 assert(! is_ndb_blob_table(name));
470 const Uint32 sz = vers->size();
476 for(Uint32 i = 0; i < sz; i++)
478 TableVersion & ver = (* vers)[
i];
479 if(ver.m_version == tableVersion && ver.m_impl &&
480 (Uint32) ver.m_impl->m_id == tableId)
482 ver.m_status = DROPPED;
483 ver.m_impl->m_status = altered ?
485 if (ver.m_refCount == 0)
493 if(i == sz - 1 && ver.m_status == RETREIVING)
495 ver.m_impl = altered ? f_altered_table : f_invalid_table;
503 GlobalDictCache::chg_ref_count(
const NdbTableImpl * impl,
int value)
505 DBUG_ENTER(
"GlobalDictCache::chg_ref_count");
506 const char * name = impl->m_internalName.
c_str();
507 assert(! is_ndb_blob_table(name));
509 const Uint32 tableId = impl->m_id;
510 const Uint32 tableVersion = impl->m_version;
512 const Uint32 len = (Uint32)strlen(name);
514 m_tableHash.getData(name, len);
521 const Uint32 sz = vers->size();
527 for(Uint32 i = 0; i < sz; i++)
529 TableVersion & ver = (* vers)[
i];
530 if(ver.m_impl == impl)
534 DBUG_PRINT(
"info", (
"%s id=%u ver=0x%x: inc old ref count %u",
535 name, tableId, tableVersion, ver.m_refCount));
538 else if (value == -1)
540 DBUG_PRINT(
"info", (
"%s id=%u ver=0x%x: dec old ref count %u",
541 name, tableId, tableVersion, ver.m_refCount));
542 if (ver.m_refCount == 0)
545 if (ver.m_refCount == 0)