~drizzle-trunk/drizzle/development

1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
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 */
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
27
#include "config.h"
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
28
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
29
#include <pthread.h>
30
31
#include <cassert>
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
32
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
33
#include "drizzled/error.h"
34
#include "drizzled/gettext.h"
35
#include "drizzled/sql_base.h"
36
#include "drizzled/hash.h"
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
37
#include "drizzled/pthread_globals.h"
1241.9.64 by Monty Taylor
Moved remaining non-public portions of mysys and mystrings to drizzled/internal.
38
#include "drizzled/internal/my_pthread.h"
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
39
40
using namespace std;
41
1241.9.33 by Monty Taylor
Moved most of the global vars to set_var where they belong.
42
extern size_t table_def_size;
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
43
typedef drizzled::hash_map<string, TableShare *> TableDefCache;
44
TableDefCache table_def_cache;
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
45
static pthread_mutex_t LOCK_table_share;
46
bool table_def_inited= false;
47
48
/*****************************************************************************
49
  Functions to handle table definition cach (TableShare)
50
 *****************************************************************************/
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
51
52
53
void TableShare::cacheStart(void)
54
{
55
  pthread_mutex_init(&LOCK_table_share, MY_MUTEX_INIT_FAST);
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
56
  table_def_inited= true;
1223.3.2 by Monty Taylor
Added init-time rehash to the table_def_cache.
57
  /* 
58
   * This is going to overalloc a bit - as rehash sets the number of
59
   * buckets, not the number of elements. BUT, it'll allow us to not need
60
   * to rehash later on as the hash_map grows.
61
   */
62
  table_def_cache.rehash(table_def_size);
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
63
}
64
65
66
void TableShare::cacheStop(void)
67
{
68
  if (table_def_inited)
69
  {
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
70
    table_def_inited= false;
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
71
    pthread_mutex_destroy(&LOCK_table_share);
72
  }
73
}
74
75
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
76
/**
77
 * @TODO: This should return size_t
78
 */
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
79
uint32_t cached_table_definitions(void)
80
{
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
81
  return static_cast<uint32_t>(table_def_cache.size());
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
82
}
83
84
85
/*
86
  Mark that we are not using table share anymore.
87
88
  SYNOPSIS
89
  release()
90
  share		Table share
91
92
  IMPLEMENTATION
93
  If ref_count goes to zero and (we have done a refresh or if we have
94
  already too many open table shares) then delete the definition.
95
*/
96
97
void TableShare::release(TableShare *share)
98
{
99
  bool to_be_deleted= false;
100
  safe_mutex_assert_owner(&LOCK_open);
101
102
  pthread_mutex_lock(&share->mutex);
103
  if (!--share->ref_count)
104
    to_be_deleted= true;
105
106
  if (to_be_deleted)
107
  {
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
108
    const string key_string(share->table_cache_key.str,
109
                            share->table_cache_key.length);
110
    TableDefCache::iterator iter= table_def_cache.find(key_string);
111
    if (iter != table_def_cache.end())
112
    {
113
      (*iter).second->free_table_share();
114
      table_def_cache.erase(iter);
115
    }
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
116
    return;
117
  }
118
  pthread_mutex_unlock(&share->mutex);
119
}
120
121
void TableShare::release(const char *key, uint32_t key_length)
122
{
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
123
  const string key_string(key, key_length);
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
124
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
125
  TableDefCache::iterator iter= table_def_cache.find(key_string);
126
  if (iter != table_def_cache.end())
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
127
  {
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
128
    TableShare *share= (*iter).second;
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
129
    share->version= 0;                          // Mark for delete
130
    if (share->ref_count == 0)
131
    {
132
      pthread_mutex_lock(&share->mutex);
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
133
      share->free_table_share();
134
      table_def_cache.erase(key_string);
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
135
    }
136
  }
137
}
138
139
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
140
static TableShare *foundTableShare(TableShare *share)
141
{
142
  /*
143
    We found an existing table definition. Return it if we didn't get
144
    an error when reading the table definition from file.
145
  */
146
147
  /* We must do a lock to ensure that the structure is initialized */
148
  (void) pthread_mutex_lock(&share->mutex);
149
  if (share->error)
150
  {
151
    /* Table definition contained an error */
152
    share->open_table_error(share->error, share->open_errno, share->errarg);
153
    (void) pthread_mutex_unlock(&share->mutex);
154
155
    return NULL;
156
  }
157
158
  share->ref_count++;
159
  (void) pthread_mutex_unlock(&share->mutex);
160
161
  return share;
162
}
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
163
164
/*
165
  Get TableShare for a table.
166
167
  get_table_share()
168
  session			Thread handle
169
  table_list		Table that should be opened
170
  key			Table cache key
171
  key_length		Length of key
172
  error			out: Error code from open_table_def()
173
174
  IMPLEMENTATION
175
  Get a table definition from the table definition cache.
176
  If it doesn't exist, create a new from the table definition file.
177
178
  NOTES
179
  We must have wrlock on LOCK_open when we come here
180
  (To be changed later)
181
182
  RETURN
183
  0  Error
184
#  Share for table
185
*/
186
187
TableShare *TableShare::getShare(Session *session, 
188
                                 TableList *table_list, char *key,
189
                                 uint32_t key_length, uint32_t, int *error)
190
{
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
191
  const string key_string(key, key_length);
192
  TableShare *share= NULL;
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
193
194
  *error= 0;
195
196
  /* Read table definition from cache */
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
197
  TableDefCache::iterator iter= table_def_cache.find(key_string);
198
  if (iter != table_def_cache.end())
199
  {
200
    share= (*iter).second;
201
    return foundTableShare(share);
202
  }
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
203
204
  if (!(share= alloc_table_share(table_list, key, key_length)))
205
  {
206
    return NULL;
207
  }
208
209
  /*
210
    Lock mutex to be able to read table definition from file without
211
    conflicts
212
  */
213
  (void) pthread_mutex_lock(&share->mutex);
214
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
215
  /**
216
   * @TODO: we need to eject something if we exceed table_def_size
217
   */
218
  pair<TableDefCache::iterator, bool> ret=
219
    table_def_cache.insert(make_pair(key_string, share));
220
  if (ret.second == false)
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
221
  {
222
    share->free_table_share();
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
223
    return NULL;
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
224
  }
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
225
  
1183.1.29 by Brian Aker
Clean up interface so that Truncate sets the propper engine when
226
  if (open_table_def(*session, share))
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
227
  {
228
    *error= share->error;
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
229
    table_def_cache.erase(key_string);
230
    share->free_table_share();
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
231
    return NULL;
232
  }
233
  share->ref_count++;				// Mark in use
234
  (void) pthread_mutex_unlock(&share->mutex);
235
  return share;
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
236
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
237
}
238
239
240
/*
241
  Check if table definition exits in cache
242
243
  SYNOPSIS
244
  get_cached_table_share()
245
  db			Database name
246
  table_name		Table name
247
248
  RETURN
249
  0  Not cached
250
#  TableShare for table
251
*/
252
253
TableShare *TableShare::getShare(const char *db, const char *table_name)
254
{
255
  char key[NAME_LEN*2+2];
256
  uint32_t key_length;
257
  safe_mutex_assert_owner(&LOCK_open);
258
259
  key_length= TableShare::createKey(key, db, table_name);
260
1223.3.1 by Monty Taylor
Replace HASH in table_share with drizzled::hash_map
261
  const string key_string(key, key_length);
262
  TableDefCache::iterator iter= table_def_cache.find(key_string);
263
  if (iter != table_def_cache.end())
264
  {
265
    return (*iter).second;
266
  }
267
  else
268
  {
269
    return NULL;
270
  }
1093.6.1 by Brian Aker
Refactor TableShare has to be behind class.
271
}