1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2009 Sun Microsystems
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.
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.
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
22
This class is shared between different table objects. There is one
23
instance of table share per one table in the database.
26
/* Basic functions needed by many modules */
33
#include "drizzled/error.h"
34
#include "drizzled/gettext.h"
35
#include "drizzled/sql_base.h"
36
#include "drizzled/hash.h"
37
#include "drizzled/pthread_globals.h"
38
#include "drizzled/internal/my_pthread.h"
45
extern size_t table_def_size;
46
TableDefinitionCache table_def_cache;
47
static pthread_mutex_t LOCK_table_share;
48
bool table_def_inited= false;
50
/*****************************************************************************
51
Functions to handle table definition cach (TableShare)
52
*****************************************************************************/
55
void TableShare::cacheStart(void)
57
pthread_mutex_init(&LOCK_table_share, MY_MUTEX_INIT_FAST);
58
table_def_inited= true;
60
* This is going to overalloc a bit - as rehash sets the number of
61
* buckets, not the number of elements. BUT, it'll allow us to not need
62
* to rehash later on as the hash_map grows.
64
table_def_cache.rehash(table_def_size);
68
void TableShare::cacheStop(void)
72
table_def_inited= false;
73
pthread_mutex_destroy(&LOCK_table_share);
79
* @TODO: This should return size_t
81
uint32_t cached_table_definitions(void)
83
return static_cast<uint32_t>(table_def_cache.size());
88
Mark that we are not using table share anymore.
95
If ref_count goes to zero and (we have done a refresh or if we have
96
already too many open table shares) then delete the definition.
99
void TableShare::release(TableShare *share)
101
bool to_be_deleted= false;
102
safe_mutex_assert_owner(&LOCK_open);
104
pthread_mutex_lock(&share->mutex);
105
if (!--share->ref_count)
110
const string key_string(share->table_cache_key.str,
111
share->table_cache_key.length);
112
TableDefinitionCache::iterator iter= table_def_cache.find(key_string);
113
if (iter != table_def_cache.end())
115
(*iter).second->free_table_share();
116
table_def_cache.erase(iter);
120
pthread_mutex_unlock(&share->mutex);
123
void TableShare::release(const char *key, uint32_t key_length)
125
const string key_string(key, key_length);
127
TableDefinitionCache::iterator iter= table_def_cache.find(key_string);
128
if (iter != table_def_cache.end())
130
TableShare *share= (*iter).second;
131
share->version= 0; // Mark for delete
132
if (share->ref_count == 0)
134
pthread_mutex_lock(&share->mutex);
135
share->free_table_share();
136
table_def_cache.erase(key_string);
142
static TableShare *foundTableShare(TableShare *share)
145
We found an existing table definition. Return it if we didn't get
146
an error when reading the table definition from file.
149
/* We must do a lock to ensure that the structure is initialized */
150
(void) pthread_mutex_lock(&share->mutex);
153
/* Table definition contained an error */
154
share->open_table_error(share->error, share->open_errno, share->errarg);
155
(void) pthread_mutex_unlock(&share->mutex);
161
(void) pthread_mutex_unlock(&share->mutex);
167
Get TableShare for a table.
170
session Thread handle
171
table_list Table that should be opened
173
key_length Length of key
174
error out: Error code from open_table_def()
177
Get a table definition from the table definition cache.
178
If it doesn't exist, create a new from the table definition file.
181
We must have wrlock on LOCK_open when we come here
182
(To be changed later)
189
TableShare *TableShare::getShare(Session *session,
190
TableList *table_list, char *key,
191
uint32_t key_length, uint32_t, int *error)
193
const string key_string(key, key_length);
194
TableShare *share= NULL;
198
/* Read table definition from cache */
199
TableDefinitionCache::iterator iter= table_def_cache.find(key_string);
200
if (iter != table_def_cache.end())
202
share= (*iter).second;
203
return foundTableShare(share);
206
if (not (share= alloc_table_share(table_list, key, key_length)))
212
Lock mutex to be able to read table definition from file without
215
(void) pthread_mutex_lock(&share->mutex);
218
* @TODO: we need to eject something if we exceed table_def_size
220
pair<TableDefinitionCache::iterator, bool> ret=
221
table_def_cache.insert(make_pair(key_string, share));
222
if (ret.second == false)
224
share->free_table_share();
228
TableIdentifier identifier(share->getSchemaName(), share->getTableName());
229
if (open_table_def(*session, identifier, share))
231
*error= share->error;
232
table_def_cache.erase(key_string);
233
share->free_table_share();
236
share->ref_count++; // Mark in use
237
(void) pthread_mutex_unlock(&share->mutex);
244
Check if table definition exits in cache
247
get_cached_table_share()
249
table_name Table name
253
# TableShare for table
255
TableShare *TableShare::getShare(TableIdentifier &identifier)
257
char key[MAX_DBKEY_LENGTH];
259
safe_mutex_assert_owner(&LOCK_open);
261
key_length= TableShare::createKey(key, identifier);
263
const string key_string(key, key_length);
265
TableDefinitionCache::iterator iter= table_def_cache.find(key_string);
266
if (iter != table_def_cache.end())
268
return (*iter).second;
279
* Precache this stuff....
281
bool TableShare::fieldInPrimaryKey(Field *in_field) const
283
assert(table_proto != NULL);
285
size_t num_indexes= table_proto->indexes_size();
287
for (size_t x= 0; x < num_indexes; ++x)
289
const message::Table::Index &index= table_proto->indexes(x);
290
if (index.is_primary())
292
size_t num_parts= index.index_part_size();
293
for (size_t y= 0; y < num_parts; ++y)
295
if (index.index_part(y).fieldnr() == in_field->field_index)
303
TableDefinitionCache &TableShare::getCache()
305
return table_def_cache;
308
} /* namespace drizzled */