~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_share.cc

  • Committer: Brian Aker
  • Date: 2009-07-27 04:14:30 UTC
  • mfrom: (1093.6.2 table_share)
  • Revision ID: brian@gaz-20090727041430-kmxsnb2ep1cqsy05
Merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2009 Sun Microsystems
 
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
/*
 
22
  This class is shared between different table objects. There is one
 
23
  instance of table share per one table in the database.
 
24
*/
 
25
 
 
26
/* Basic functions needed by many modules */
 
27
#include <drizzled/server_includes.h>
 
28
#include <assert.h>
 
29
 
 
30
#include <drizzled/error.h>
 
31
#include <drizzled/gettext.h>
 
32
#include <drizzled/sql_base.h>
 
33
 
 
34
using namespace std;
 
35
 
 
36
static HASH table_def_cache;
 
37
static pthread_mutex_t LOCK_table_share;
 
38
bool table_def_inited= false;
 
39
 
 
40
/*****************************************************************************
 
41
  Functions to handle table definition cach (TableShare)
 
42
 *****************************************************************************/
 
43
 
 
44
extern "C"
 
45
{
 
46
  unsigned char *table_def_key(const unsigned char *record,
 
47
                               size_t *length,
 
48
                               bool );
 
49
}
 
50
 
 
51
unsigned char *table_def_key(const unsigned char *record,
 
52
                             size_t *length,
 
53
                             bool )
 
54
{
 
55
  TableShare *entry=(TableShare*) record;
 
56
  *length= entry->table_cache_key.length;
 
57
  return (unsigned char*) entry->table_cache_key.str;
 
58
}
 
59
 
 
60
 
 
61
static void table_def_free_entry(TableShare *share)
 
62
{
 
63
  share->free_table_share();
 
64
}
 
65
 
 
66
 
 
67
bool TableShare::cacheStart(void)
 
68
{
 
69
  table_def_inited= true;
 
70
  pthread_mutex_init(&LOCK_table_share, MY_MUTEX_INIT_FAST);
 
71
 
 
72
  return hash_init(&table_def_cache, &my_charset_bin, (size_t)table_def_size,
 
73
                   0, 0, table_def_key,
 
74
                   (hash_free_key) table_def_free_entry, 0);
 
75
}
 
76
 
 
77
 
 
78
void TableShare::cacheStop(void)
 
79
{
 
80
  if (table_def_inited)
 
81
  {
 
82
    table_def_inited= 0;
 
83
    pthread_mutex_destroy(&LOCK_table_share);
 
84
    hash_free(&table_def_cache);
 
85
  }
 
86
}
 
87
 
 
88
 
 
89
uint32_t cached_table_definitions(void)
 
90
{
 
91
  return table_def_cache.records;
 
92
}
 
93
 
 
94
 
 
95
/*
 
96
  Mark that we are not using table share anymore.
 
97
 
 
98
  SYNOPSIS
 
99
  release()
 
100
  share         Table share
 
101
 
 
102
  IMPLEMENTATION
 
103
  If ref_count goes to zero and (we have done a refresh or if we have
 
104
  already too many open table shares) then delete the definition.
 
105
*/
 
106
 
 
107
void TableShare::release(TableShare *share)
 
108
{
 
109
  bool to_be_deleted= false;
 
110
  safe_mutex_assert_owner(&LOCK_open);
 
111
 
 
112
  pthread_mutex_lock(&share->mutex);
 
113
  if (!--share->ref_count)
 
114
    to_be_deleted= true;
 
115
 
 
116
  if (to_be_deleted)
 
117
  {
 
118
    hash_delete(&table_def_cache, (unsigned char*) share);
 
119
    return;
 
120
  }
 
121
  pthread_mutex_unlock(&share->mutex);
 
122
}
 
123
 
 
124
void TableShare::release(const char *key, uint32_t key_length)
 
125
{
 
126
  TableShare *share;
 
127
 
 
128
  if ((share= (TableShare*) hash_search(&table_def_cache,(unsigned char*) key,
 
129
                                        key_length)))
 
130
  {
 
131
    share->version= 0;                          // Mark for delete
 
132
    if (share->ref_count == 0)
 
133
    {
 
134
      pthread_mutex_lock(&share->mutex);
 
135
      hash_delete(&table_def_cache, (unsigned char*) share);
 
136
    }
 
137
  }
 
138
}
 
139
 
 
140
 
 
141
 
 
142
/*
 
143
  Get TableShare for a table.
 
144
 
 
145
  get_table_share()
 
146
  session                       Thread handle
 
147
  table_list            Table that should be opened
 
148
  key                   Table cache key
 
149
  key_length            Length of key
 
150
  error                 out: Error code from open_table_def()
 
151
 
 
152
  IMPLEMENTATION
 
153
  Get a table definition from the table definition cache.
 
154
  If it doesn't exist, create a new from the table definition file.
 
155
 
 
156
  NOTES
 
157
  We must have wrlock on LOCK_open when we come here
 
158
  (To be changed later)
 
159
 
 
160
  RETURN
 
161
  0  Error
 
162
#  Share for table
 
163
*/
 
164
 
 
165
TableShare *TableShare::getShare(Session *session, 
 
166
                                 TableList *table_list, char *key,
 
167
                                 uint32_t key_length, uint32_t, int *error)
 
168
{
 
169
  TableShare *share;
 
170
 
 
171
  *error= 0;
 
172
 
 
173
  /* Read table definition from cache */
 
174
  if ((share= (TableShare*) hash_search(&table_def_cache,(unsigned char*) key,
 
175
                                        key_length)))
 
176
    goto found;
 
177
 
 
178
  if (!(share= alloc_table_share(table_list, key, key_length)))
 
179
  {
 
180
    return NULL;
 
181
  }
 
182
 
 
183
  /*
 
184
    Lock mutex to be able to read table definition from file without
 
185
    conflicts
 
186
  */
 
187
  (void) pthread_mutex_lock(&share->mutex);
 
188
 
 
189
  if (my_hash_insert(&table_def_cache, (unsigned char*) share))
 
190
  {
 
191
    share->free_table_share();
 
192
    return NULL;                                // return error
 
193
  }
 
194
  if (open_table_def(session, share))
 
195
  {
 
196
    *error= share->error;
 
197
    (void) hash_delete(&table_def_cache, (unsigned char*) share);
 
198
    return NULL;
 
199
  }
 
200
  share->ref_count++;                           // Mark in use
 
201
  (void) pthread_mutex_unlock(&share->mutex);
 
202
  return(share);
 
203
 
 
204
found:
 
205
  /*
 
206
    We found an existing table definition. Return it if we didn't get
 
207
    an error when reading the table definition from file.
 
208
  */
 
209
 
 
210
  /* We must do a lock to ensure that the structure is initialized */
 
211
  (void) pthread_mutex_lock(&share->mutex);
 
212
  if (share->error)
 
213
  {
 
214
    /* Table definition contained an error */
 
215
    share->open_table_error(share->error, share->open_errno, share->errarg);
 
216
    (void) pthread_mutex_unlock(&share->mutex);
 
217
 
 
218
    return NULL;
 
219
  }
 
220
 
 
221
  share->ref_count++;
 
222
  (void) pthread_mutex_unlock(&share->mutex);
 
223
 
 
224
  return share;
 
225
}
 
226
 
 
227
 
 
228
/*
 
229
  Check if table definition exits in cache
 
230
 
 
231
  SYNOPSIS
 
232
  get_cached_table_share()
 
233
  db                    Database name
 
234
  table_name            Table name
 
235
 
 
236
  RETURN
 
237
  0  Not cached
 
238
#  TableShare for table
 
239
*/
 
240
 
 
241
TableShare *TableShare::getShare(const char *db, const char *table_name)
 
242
{
 
243
  char key[NAME_LEN*2+2];
 
244
  uint32_t key_length;
 
245
  safe_mutex_assert_owner(&LOCK_open);
 
246
 
 
247
  key_length= TableShare::createKey(key, db, table_name);
 
248
 
 
249
  return (TableShare*) hash_search(&table_def_cache,(unsigned char*) key, key_length);
 
250
}