DictCache.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:8k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <ndb_global.h>
  14. #include "DictCache.hpp"
  15. #include "NdbDictionaryImpl.hpp"
  16. #include <NdbTick.h>
  17. #include <NdbCondition.h>
  18. #include <NdbSleep.h>
  19. static NdbTableImpl f_invalid_table;
  20. static NdbTableImpl f_altered_table;
  21. Ndb_local_table_info *
  22. Ndb_local_table_info::create(NdbTableImpl *table_impl, Uint32 sz)
  23. {
  24.   Uint32 tot_size= sizeof(Ndb_local_table_info) - sizeof(Uint64)
  25.     + ((sz+7) & ~7); // round to Uint64
  26.   void *data= malloc(tot_size);
  27.   if (data == 0)
  28.     return 0;
  29.   memset(data, 0, tot_size);
  30.   new (data) Ndb_local_table_info(table_impl);
  31.   return (Ndb_local_table_info *) data;
  32. }
  33. void Ndb_local_table_info::destroy(Ndb_local_table_info *info)
  34. {
  35.   free((void *)info);
  36. }
  37. Ndb_local_table_info::Ndb_local_table_info(NdbTableImpl *table_impl)
  38. {
  39.   m_table_impl= table_impl;
  40. }
  41. Ndb_local_table_info::~Ndb_local_table_info()
  42. {
  43. }
  44. LocalDictCache::LocalDictCache(){
  45.   m_tableHash.createHashTable();
  46. }
  47. LocalDictCache::~LocalDictCache(){
  48.   m_tableHash.releaseHashTable();
  49. }
  50. Ndb_local_table_info * 
  51. LocalDictCache::get(const char * name){
  52.   const Uint32 len = strlen(name);
  53.   return m_tableHash.getData(name, len);
  54. }
  55. void 
  56. LocalDictCache::put(const char * name, Ndb_local_table_info * tab_info){
  57.   const Uint32 id = tab_info->m_table_impl->m_tableId;
  58.   
  59.   m_tableHash.insertKey(name, strlen(name), id, tab_info);
  60. }
  61. void
  62. LocalDictCache::drop(const char * name){
  63.   Ndb_local_table_info *info= m_tableHash.deleteKey(name, strlen(name));
  64.   DBUG_ASSERT(info != 0);
  65.   Ndb_local_table_info::destroy(info);
  66. }
  67. /*****************************************************************
  68.  * Global cache
  69.  */
  70. GlobalDictCache::GlobalDictCache(){
  71.   m_tableHash.createHashTable();
  72.   m_waitForTableCondition = NdbCondition_Create();
  73. }
  74. GlobalDictCache::~GlobalDictCache(){
  75.   NdbElement_t<Vector<TableVersion> > * curr = m_tableHash.getNext(0);
  76.   while(curr != 0){
  77.     Vector<TableVersion> * vers = curr->theData;
  78.     const unsigned sz = vers->size();
  79.     for(unsigned i = 0; i<sz ; i++){
  80.       if((* vers)[i].m_impl != 0)
  81. delete (* vers)[i].m_impl;
  82.     }
  83.     delete curr->theData;
  84.     curr = m_tableHash.getNext(curr);
  85.   }
  86.   
  87.   m_tableHash.releaseHashTable();
  88.   NdbCondition_Destroy(m_waitForTableCondition);
  89. }
  90. #include <NdbOut.hpp>
  91. NdbTableImpl * 
  92. GlobalDictCache::get(const char * name)
  93. {
  94.   const Uint32 len = strlen(name);
  95.   Vector<TableVersion> * versions = 0;  
  96.   versions = m_tableHash.getData(name, len);
  97.   if(versions == 0){
  98.     versions = new Vector<TableVersion>(2);
  99.     m_tableHash.insertKey(name, len, 0, versions);
  100.   }
  101.   int waitTime = 100;
  102.   bool retreive = false;
  103.   while(versions->size() > 0 && !retreive){
  104.     TableVersion * ver = & versions->back();
  105.     switch(ver->m_status){
  106.     case OK:
  107.       ver->m_refCount++;
  108.       return ver->m_impl;
  109.     case DROPPED:
  110.       retreive = true; // Break loop
  111.       break;
  112.     case RETREIVING:
  113.       NdbCondition_WaitTimeout(m_waitForTableCondition, m_mutex, waitTime);
  114.       continue;
  115.     }
  116.   }
  117.   
  118.   /**
  119.    * Create new...
  120.    */
  121.   TableVersion tmp;
  122.   tmp.m_version = 0;
  123.   tmp.m_impl = 0;
  124.   tmp.m_status = RETREIVING;
  125.   tmp.m_refCount = 1; // The one retreiving it
  126.   versions->push_back(tmp);
  127.   return 0;
  128. }
  129. NdbTableImpl *
  130. GlobalDictCache::put(const char * name, NdbTableImpl * tab)
  131. {
  132.   const Uint32 len = strlen(name);
  133.   Vector<TableVersion> * vers = m_tableHash.getData(name, len);
  134.   if(vers == 0){
  135.     // Should always tried to retreive it first 
  136.     // and then there should be a record
  137.     abort(); 
  138.   }
  139.   const Uint32 sz = vers->size();
  140.   if(sz == 0){
  141.     // Should always tried to retreive it first 
  142.     // and then there should be a record
  143.     abort(); 
  144.   }
  145.   
  146.   TableVersion & ver = vers->back();
  147.   if(ver.m_status != RETREIVING || 
  148.      !(ver.m_impl == 0 || 
  149.        ver.m_impl == &f_invalid_table || ver.m_impl == &f_altered_table) || 
  150.      ver.m_version != 0 || 
  151.      ver.m_refCount == 0){
  152.     abort();
  153.   }
  154.   
  155.   if(tab == 0)
  156.   {
  157.     // No table found in db
  158.     vers->erase(sz - 1);
  159.   } 
  160.   else if (ver.m_impl == 0) {
  161.     ver.m_impl = tab;
  162.     ver.m_version = tab->m_version;
  163.     ver.m_status = OK;
  164.   } 
  165.   else if (ver.m_impl == &f_invalid_table) 
  166.   {
  167.     ver.m_impl = tab;
  168.     ver.m_version = tab->m_version;
  169.     ver.m_status = DROPPED;
  170.     ver.m_impl->m_status = NdbDictionary::Object::Invalid;    
  171.   }
  172.   else if(ver.m_impl == &f_altered_table)
  173.   {
  174.     ver.m_impl = tab;
  175.     ver.m_version = tab->m_version;
  176.     ver.m_status = DROPPED;
  177.     ver.m_impl->m_status = NdbDictionary::Object::Altered;    
  178.   }
  179.   else
  180.   {
  181.     abort();
  182.   }
  183.   NdbCondition_Broadcast(m_waitForTableCondition);
  184.   return tab;
  185. void
  186. GlobalDictCache::drop(NdbTableImpl * tab)
  187. {
  188.   unsigned i;
  189.   const Uint32 len = strlen(tab->m_internalName.c_str());
  190.   Vector<TableVersion> * vers = 
  191.     m_tableHash.getData(tab->m_internalName.c_str(), len);
  192.   if(vers == 0){
  193.     // Should always tried to retreive it first 
  194.     // and then there should be a record
  195.     abort(); 
  196.   }
  197.   const Uint32 sz = vers->size();
  198.   if(sz == 0){
  199.     // Should always tried to retreive it first 
  200.     // and then there should be a record
  201.     abort(); 
  202.   }
  203.   
  204.   for(i = 0; i < sz; i++){
  205.     TableVersion & ver = (* vers)[i];
  206.     if(ver.m_impl == tab){
  207.       if(ver.m_refCount == 0 || ver.m_status == RETREIVING || 
  208.  ver.m_version != tab->m_version){
  209. ndbout_c("Dropping with refCount=%d status=%d impl=%p",
  210.  ver.m_refCount, ver.m_status, ver.m_impl);
  211. break;
  212.       }
  213.       
  214.       ver.m_refCount--;
  215.       ver.m_status = DROPPED;
  216.       if(ver.m_refCount == 0){
  217. delete ver.m_impl;
  218. vers->erase(i);
  219.       }
  220.       return;
  221.     }
  222.   }
  223.   
  224.   for(i = 0; i<sz; i++){
  225.     TableVersion & ver = (* vers)[i];
  226.     ndbout_c("%d: version: %d refCount: %d status: %d impl: %p",
  227.      i, ver.m_version, ver.m_refCount, ver.m_status, ver.m_impl);
  228.   }
  229.   
  230.   abort();
  231. }
  232. void
  233. GlobalDictCache::release(NdbTableImpl * tab){
  234.   unsigned i;
  235.   const Uint32 len = strlen(tab->m_internalName.c_str());
  236.   Vector<TableVersion> * vers = 
  237.     m_tableHash.getData(tab->m_internalName.c_str(), len);
  238.   if(vers == 0){
  239.     // Should always tried to retreive it first 
  240.     // and then there should be a record
  241.     abort(); 
  242.   }
  243.   const Uint32 sz = vers->size();
  244.   if(sz == 0){
  245.     // Should always tried to retreive it first 
  246.     // and then there should be a record
  247.     abort(); 
  248.   }
  249.   
  250.   for(i = 0; i < sz; i++){
  251.     TableVersion & ver = (* vers)[i];
  252.     if(ver.m_impl == tab){
  253.       if(ver.m_refCount == 0 || ver.m_status == RETREIVING || 
  254.  ver.m_version != tab->m_version){
  255. ndbout_c("Releasing with refCount=%d status=%d impl=%p",
  256.  ver.m_refCount, ver.m_status, ver.m_impl);
  257. break;
  258.       }
  259.       
  260.       ver.m_refCount--;
  261.       return;
  262.     }
  263.   }
  264.   
  265.   for(i = 0; i<sz; i++){
  266.     TableVersion & ver = (* vers)[i];
  267.     ndbout_c("%d: version: %d refCount: %d status: %d impl: %p",
  268.      i, ver.m_version, ver.m_refCount, ver.m_status, ver.m_impl);
  269.   }
  270.   
  271.   abort();
  272. }
  273. void
  274. GlobalDictCache::alter_table_rep(const char * name, 
  275.  Uint32 tableId, 
  276.  Uint32 tableVersion,
  277.  bool altered)
  278. {
  279.   const Uint32 len = strlen(name);
  280.   Vector<TableVersion> * vers = 
  281.     m_tableHash.getData(name, len);
  282.   
  283.   if(vers == 0)
  284.   {
  285.     return;
  286.   }
  287.   const Uint32 sz = vers->size();
  288.   if(sz == 0)
  289.   {
  290.     return;
  291.   }
  292.   
  293.   for(Uint32 i = 0; i < sz; i++)
  294.   {
  295.     TableVersion & ver = (* vers)[i];
  296.     if(ver.m_version == tableVersion && ver.m_impl && 
  297.        ver.m_impl->m_tableId == tableId)
  298.     {
  299.       ver.m_status = DROPPED;
  300.       ver.m_impl->m_status = altered ? 
  301. NdbDictionary::Object::Altered : NdbDictionary::Object::Invalid;
  302.       return;
  303.     }
  304.     if(i == sz - 1 && ver.m_status == RETREIVING)
  305.     {
  306.       ver.m_impl = altered ? &f_altered_table : &f_invalid_table;
  307.       return;
  308.     } 
  309.   }
  310. }
  311. template class Vector<GlobalDictCache::TableVersion>;