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 {
00032 
00033 namespace table
00034 {
00035 
00036 namespace instance
00037 {
00038 
00039 Shared::Shared(const identifier::Table::Type type_arg,
00040                const identifier::Table &identifier,
00041                char *path_arg, uint32_t path_length_arg) :
00042   TableShare(type_arg, identifier, path_arg, path_length_arg),
00043   event_observers(NULL)
00044 {
00045 }
00046 
00047 Shared::Shared(const identifier::Table &identifier,
00048                message::schema::shared_ptr schema_message) :
00049   TableShare(message::Table::STANDARD, identifier, NULL, 0),
00050   _schema(schema_message),
00051   event_observers(NULL)
00052 {
00053 }
00054 
00055 Shared::Shared(const identifier::Table &identifier) :
00056   TableShare(identifier, identifier.getKey()),
00057   event_observers(NULL)
00058 {
00059 }
00060 
00061 bool Shared::is_replicated() const
00062 {
00063   if (_schema)
00064   {
00065     if (not message::is_replicated(*_schema))
00066       return false;
00067   }
00068 
00069   assert(getTableMessage());
00070   return message::is_replicated(*getTableMessage());
00071 }
00072 
00073 
00074 Shared::shared_ptr Shared::foundTableShare(Shared::shared_ptr share)
00075 {
00076   /*
00077     We found an existing table definition. Return it if we didn't get
00078     an error when reading the table definition from file.
00079   */
00080   if (share->error)
00081   {
00082     /* Table definition contained an error */
00083     share->open_table_error(share->error, share->open_errno, share->errarg);
00084 
00085     return Shared::shared_ptr();
00086   }
00087 
00088   share->incrementTableCount();
00089 
00090   return share;
00091 }
00092 
00093 
00094 
00095 /*
00096   Get a shared instance for a table.
00097 
00098   get_table_share()
00099   session     Thread handle
00100   table_list    Table that should be opened
00101   key     Table cache key
00102   key_length    Length of key
00103   error     out: Error code from open_table_def()
00104 
00105   IMPLEMENTATION
00106   Get a table definition from the table definition cache.
00107   If it doesn't exist, create a new from the table definition file.
00108 
00109   NOTES
00110   We must have wrlock on table::Cache::singleton().mutex() when we come here
00111   (To be changed later)
00112 
00113   RETURN
00114   0  Error
00115 #  Share for table
00116 */
00117 
00118 Shared::shared_ptr Shared::make_shared(Session *session, 
00119                                        const identifier::Table &identifier,
00120                                        int &in_error)
00121 {
00122   Shared::shared_ptr share;
00123 
00124   in_error= 0;
00125 
00126   /* Read table definition from cache */
00127   if ((share= definition::Cache::singleton().find(identifier.getKey())))
00128     return foundTableShare(share);
00129   
00130   drizzled::message::schema::shared_ptr schema_message_ptr= plugin::StorageEngine::getSchemaDefinition(identifier);
00131 
00132   if (not schema_message_ptr)
00133   {
00134     drizzled::my_error(ER_SCHEMA_DOES_NOT_EXIST, identifier);
00135     return Shared::shared_ptr();
00136   }
00137 
00138   share.reset(new Shared(identifier, schema_message_ptr));
00139 
00140   if (share->open_table_def(*session, identifier))
00141   {
00142     in_error= share->error;
00143 
00144     return Shared::shared_ptr();
00145   }
00146   share->incrementTableCount();       // Mark in use
00147   
00148   plugin::EventObserver::registerTableEvents(*share);
00149 
00150   bool ret= definition::Cache::singleton().insert(identifier.getKey(), share);
00151 
00152   if (not ret)
00153   {
00154     drizzled::my_error(ER_UNKNOWN_ERROR);
00155     return Shared::shared_ptr();
00156   }
00157 
00158   return share;
00159 }
00160 
00161 Shared::~Shared()
00162 {
00163   assert(getTableCount() == 0);
00164   plugin::EventObserver::deregisterTableEvents(*this);
00165 }
00166 
00167 
00168 /*****************************************************************************
00169   Functions to handle table definition cach (TableShare)
00170  *****************************************************************************/
00171 
00172 /*
00173   Mark that we are not using table share anymore.
00174 
00175   SYNOPSIS
00176   release()
00177   share   Table share
00178 
00179   IMPLEMENTATION
00180   If ref_count goes to zero and (we have done a refresh or if we have
00181   already too many open table shares) then delete the definition.
00182 */
00183 
00184 void release(TableShare *share)
00185 {
00186   bool to_be_deleted= false;
00187   //safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle);
00188 
00189   share->lock();
00190   if (not share->decrementTableCount())
00191   {
00192     to_be_deleted= true;
00193   }
00194   share->unlock();
00195 
00196   if (to_be_deleted)
00197   {
00198     definition::Cache::singleton().erase(share->getCacheKey());
00199   }
00200 }
00201 
00202 void release(TableShare::shared_ptr &share)
00203 {
00204   bool to_be_deleted= false;
00205 #if 0
00206   safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle);
00207 #endif
00208 
00209   share->lock();
00210   if (not share->decrementTableCount())
00211   {
00212     to_be_deleted= true;
00213   }
00214   share->unlock();
00215 
00216   if (to_be_deleted)
00217   {
00218     definition::Cache::singleton().erase(share->getCacheKey());
00219   }
00220 }
00221 
00222 void release(const identifier::Table &identifier)
00223 {
00224   TableShare::shared_ptr share= definition::Cache::singleton().find(identifier.getKey());
00225   if (share)
00226   {
00227     share->resetVersion(); 
00228     if (share->getTableCount() == 0)
00229     {
00230       definition::Cache::singleton().erase(identifier.getKey());
00231     }
00232   }
00233 }
00234 
00235 
00236 } /* namespace instance */
00237 } /* namespace table */
00238 } /* namespace drizzled */