Drizzled Public API Documentation

shared.cc
00001 /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2011 Brian Aker
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 #include <config.h>
00022 
00023 #include <drizzled/definition/cache.h>
00024 #include <drizzled/error.h>
00025 #include <drizzled/message/schema.h>
00026 #include <drizzled/plugin/event_observer.h>
00027 #include <drizzled/table/instance/shared.h>
00028 #include <drizzled/plugin/storage_engine.h>
00029 
00030 namespace drizzled {
00031 namespace table {
00032 namespace instance {
00033 
00034 Shared::Shared(const identifier::Table::Type type_arg,
00035                const identifier::Table &identifier,
00036                char *path_arg, uint32_t path_length_arg) :
00037   TableShare(type_arg, identifier, path_arg, path_length_arg),
00038   event_observers(NULL)
00039 {
00040 }
00041 
00042 Shared::Shared(const identifier::Table &identifier,
00043                message::schema::shared_ptr schema_message) :
00044   TableShare(message::Table::STANDARD, identifier, NULL, 0),
00045   _schema(schema_message),
00046   event_observers(NULL)
00047 {
00048 }
00049 
00050 Shared::Shared(const identifier::Table &identifier) :
00051   TableShare(identifier, identifier.getKey()),
00052   event_observers(NULL)
00053 {
00054 }
00055 
00056 bool Shared::is_replicated() const
00057 {
00058   if (_schema)
00059   {
00060     if (not message::is_replicated(*_schema))
00061       return false;
00062   }
00063 
00064   assert(getTableMessage());
00065   return message::is_replicated(*getTableMessage());
00066 }
00067 
00068 
00069 Shared::shared_ptr Shared::foundTableShare(Shared::shared_ptr share)
00070 {
00071   /*
00072     We found an existing table definition. Return it if we didn't get
00073     an error when reading the table definition from file.
00074   */
00075   if (share->error)
00076   {
00077     /* Table definition contained an error */
00078     share->open_table_error(share->error, share->open_errno, share->errarg);
00079 
00080     return Shared::shared_ptr();
00081   }
00082 
00083   share->incrementTableCount();
00084 
00085   return share;
00086 }
00087 
00088 
00089 
00090 /*
00091   Get a shared instance for a table.
00092 
00093   get_table_share()
00094   session     Thread handle
00095   table_list    Table that should be opened
00096   key     Table cache key
00097   key_length    Length of key
00098   error     out: Error code from open_table_def()
00099 
00100   IMPLEMENTATION
00101   Get a table definition from the table definition cache.
00102   If it doesn't exist, create a new from the table definition file.
00103 
00104   NOTES
00105   We must have wrlock on table::Cache::mutex() when we come here
00106   (To be changed later)
00107 
00108   RETURN
00109   0  Error
00110 #  Share for table
00111 */
00112 
00113 Shared::shared_ptr Shared::make_shared(Session *session, 
00114                                        const identifier::Table &identifier,
00115                                        int &in_error)
00116 {
00117   Shared::shared_ptr share;
00118 
00119   in_error= 0;
00120 
00121   /* Read table definition from cache */
00122   if ((share= definition::Cache::find(identifier.getKey())))
00123     return foundTableShare(share);
00124   
00125   drizzled::message::schema::shared_ptr schema_message_ptr= plugin::StorageEngine::getSchemaDefinition(identifier);
00126 
00127   if (not schema_message_ptr)
00128   {
00129     drizzled::my_error(ER_SCHEMA_DOES_NOT_EXIST, identifier);
00130     return Shared::shared_ptr();
00131   }
00132 
00133   share.reset(new Shared(identifier, schema_message_ptr));
00134 
00135   if (share->open_table_def(*session, identifier))
00136   {
00137     in_error= share->error;
00138 
00139     return Shared::shared_ptr();
00140   }
00141   share->incrementTableCount();       // Mark in use
00142   
00143   plugin::EventObserver::registerTableEvents(*share);
00144 
00145   bool ret= definition::Cache::insert(identifier.getKey(), share);
00146 
00147   if (not ret)
00148   {
00149     drizzled::my_error(ER_UNKNOWN_ERROR);
00150     return Shared::shared_ptr();
00151   }
00152 
00153   return share;
00154 }
00155 
00156 Shared::~Shared()
00157 {
00158   assert(getTableCount() == 0);
00159   plugin::EventObserver::deregisterTableEvents(*this);
00160 }
00161 
00162 
00163 /*****************************************************************************
00164   Functions to handle table definition cach (TableShare)
00165  *****************************************************************************/
00166 
00167 /*
00168   Mark that we are not using table share anymore.
00169 
00170   SYNOPSIS
00171   release()
00172   share   Table share
00173 
00174   IMPLEMENTATION
00175   If ref_count goes to zero and (we have done a refresh or if we have
00176   already too many open table shares) then delete the definition.
00177 */
00178 
00179 void release(TableShare *share)
00180 {
00181   bool to_be_deleted= false;
00182   //safe_mutex_assert_owner(table::Cache::mutex().native_handle);
00183 
00184   share->lock();
00185   if (not share->decrementTableCount())
00186   {
00187     to_be_deleted= true;
00188   }
00189   share->unlock();
00190 
00191   if (to_be_deleted)
00192   {
00193     definition::Cache::erase(share->getCacheKey());
00194   }
00195 }
00196 
00197 void release(TableShare::shared_ptr &share)
00198 {
00199   bool to_be_deleted= false;
00200 #if 0
00201   safe_mutex_assert_owner(table::Cache::mutex().native_handle);
00202 #endif
00203 
00204   share->lock();
00205   if (not share->decrementTableCount())
00206   {
00207     to_be_deleted= true;
00208   }
00209   share->unlock();
00210 
00211   if (to_be_deleted)
00212   {
00213     definition::Cache::erase(share->getCacheKey());
00214   }
00215 }
00216 
00217 void release(const identifier::Table &identifier)
00218 {
00219   TableShare::shared_ptr share= definition::Cache::find(identifier.getKey());
00220   if (share)
00221   {
00222     share->resetVersion(); 
00223     if (share->getTableCount() == 0)
00224     {
00225       definition::Cache::erase(identifier.getKey());
00226     }
00227   }
00228 }
00229 
00230 
00231 } /* namespace instance */
00232 } /* namespace table */
00233 } /* namespace drizzled */