Drizzled Public API Documentation

shared.cc
1 /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2011 Brian Aker
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <config.h>
22 
23 #include <drizzled/definition/cache.h>
24 #include <drizzled/error.h>
25 #include <drizzled/message/schema.h>
26 #include <drizzled/plugin/event_observer.h>
27 #include <drizzled/table/instance/shared.h>
28 #include <drizzled/plugin/storage_engine.h>
29 
30 namespace drizzled {
31 namespace table {
32 namespace instance {
33 
34 Shared::Shared(const identifier::Table::Type type_arg,
35  const identifier::Table &identifier,
36  char *path_arg, uint32_t path_length_arg) :
37  TableShare(type_arg, identifier, path_arg, path_length_arg),
38  event_observers(NULL)
39 {
40 }
41 
42 Shared::Shared(const identifier::Table &identifier,
43  message::schema::shared_ptr schema_message) :
44  TableShare(message::Table::STANDARD, identifier, NULL, 0),
45  _schema(schema_message),
46  event_observers(NULL)
47 {
48 }
49 
50 Shared::Shared(const identifier::Table &identifier) :
51  TableShare(identifier, identifier.getKey()),
52  event_observers(NULL)
53 {
54 }
55 
56 bool Shared::is_replicated() const
57 {
58  if (_schema)
59  {
60  if (not message::is_replicated(*_schema))
61  return false;
62  }
63 
64  assert(getTableMessage());
65  return message::is_replicated(*getTableMessage());
66 }
67 
68 
69 Shared::shared_ptr Shared::foundTableShare(Shared::shared_ptr share)
70 {
71  /*
72  We found an existing table definition. Return it if we didn't get
73  an error when reading the table definition from file.
74  */
75  if (share->error)
76  {
77  /* Table definition contained an error */
78  share->open_table_error(share->error, share->open_errno, share->errarg);
79 
80  return Shared::shared_ptr();
81  }
82 
83  share->incrementTableCount();
84 
85  return share;
86 }
87 
88 
89 
90 /*
91  Get a shared instance for a table.
92 
93  get_table_share()
94  session Thread handle
95  table_list Table that should be opened
96  key Table cache key
97  key_length Length of key
98  error out: Error code from open_table_def()
99 
100  IMPLEMENTATION
101  Get a table definition from the table definition cache.
102  If it doesn't exist, create a new from the table definition file.
103 
104  NOTES
105  We must have wrlock on table::Cache::mutex() when we come here
106  (To be changed later)
107 
108  RETURN
109  0 Error
110 # Share for table
111 */
112 
113 Shared::shared_ptr Shared::make_shared(Session *session,
114  const identifier::Table &identifier,
115  int &in_error)
116 {
117  Shared::shared_ptr share;
118 
119  in_error= 0;
120 
121  /* Read table definition from cache */
122  if ((share= definition::Cache::find(identifier.getKey())))
123  return foundTableShare(share);
124 
125  drizzled::message::schema::shared_ptr schema_message_ptr= plugin::StorageEngine::getSchemaDefinition(identifier);
126 
127  if (not schema_message_ptr)
128  {
129  drizzled::my_error(ER_SCHEMA_DOES_NOT_EXIST, identifier);
130  return Shared::shared_ptr();
131  }
132 
133  share.reset(new Shared(identifier, schema_message_ptr));
134 
135  if (share->open_table_def(*session, identifier))
136  {
137  in_error= share->error;
138 
139  return Shared::shared_ptr();
140  }
141  share->incrementTableCount(); // Mark in use
142 
143  plugin::EventObserver::registerTableEvents(*share);
144 
145  bool ret= definition::Cache::insert(identifier.getKey(), share);
146 
147  if (not ret)
148  {
149  drizzled::my_error(ER_UNKNOWN_ERROR);
150  return Shared::shared_ptr();
151  }
152 
153  return share;
154 }
155 
156 Shared::~Shared()
157 {
158  assert(getTableCount() == 0);
159  plugin::EventObserver::deregisterTableEvents(*this);
160 }
161 
162 
163 /*****************************************************************************
164  Functions to handle table definition cach (TableShare)
165  *****************************************************************************/
166 
167 /*
168  Mark that we are not using table share anymore.
169 
170  SYNOPSIS
171  release()
172  share Table share
173 
174  IMPLEMENTATION
175  If ref_count goes to zero and (we have done a refresh or if we have
176  already too many open table shares) then delete the definition.
177 */
178 
179 void release(TableShare *share)
180 {
181  bool to_be_deleted= false;
182  //safe_mutex_assert_owner(table::Cache::mutex().native_handle);
183 
184  share->lock();
185  if (not share->decrementTableCount())
186  {
187  to_be_deleted= true;
188  }
189  share->unlock();
190 
191  if (to_be_deleted)
192  {
193  definition::Cache::erase(share->getCacheKey());
194  }
195 }
196 
197 void release(TableShare::shared_ptr &share)
198 {
199  bool to_be_deleted= false;
200 #if 0
201  safe_mutex_assert_owner(table::Cache::mutex().native_handle);
202 #endif
203 
204  share->lock();
205  if (not share->decrementTableCount())
206  {
207  to_be_deleted= true;
208  }
209  share->unlock();
210 
211  if (to_be_deleted)
212  {
213  definition::Cache::erase(share->getCacheKey());
214  }
215 }
216 
217 void release(const identifier::Table &identifier)
218 {
219  TableShare::shared_ptr share= definition::Cache::find(identifier.getKey());
220  if (share)
221  {
222  share->resetVersion();
223  if (share->getTableCount() == 0)
224  {
225  definition::Cache::erase(identifier.getKey());
226  }
227  }
228 }
229 
230 
231 } /* namespace instance */
232 } /* namespace table */
233 } /* namespace drizzled */