~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/csv/ha_tina.cc

Fix for spare (from Monty).

Show diffs side-by-side

added added

removed removed

Lines of Context:
47
47
#include <drizzled/error.h>
48
48
#include <drizzled/table.h>
49
49
#include <drizzled/session.h>
50
 
#include "drizzled/memory/multi_malloc.h"
51
50
 
52
51
#include "ha_tina.h"
53
52
 
54
53
#include <string>
 
54
#include <map>
55
55
 
56
56
using namespace std;
57
57
 
69
69
#define CSM_EXT ".CSM"               // Meta file
70
70
 
71
71
 
72
 
static TINA_SHARE *get_share(const char *table_name, Table *table);
73
 
static int free_share(TINA_SHARE *share);
74
72
static int read_meta_file(File meta_file, ha_rows *rows);
75
73
static int write_meta_file(File meta_file, ha_rows rows, bool dirty);
76
74
 
80
78
 
81
79
/* Stuff for shares */
82
80
pthread_mutex_t tina_mutex;
83
 
static HASH tina_open_tables;
84
81
 
85
82
/*****************************************************************************
86
83
 ** TINA tables
98
95
  return ( a->begin > b->begin ? 1 : ( a->begin < b->begin ? -1 : 0 ) );
99
96
}
100
97
 
101
 
static unsigned char* tina_get_key(TINA_SHARE *share, size_t *length, bool)
102
 
{
103
 
  *length=share->table_name_length;
104
 
  return (unsigned char*) share->table_name;
105
 
}
106
 
 
107
98
 
108
99
/*
109
100
  If frm_error() is called in table.cc this is called to find out what file
117
108
 
118
109
class Tina : public drizzled::plugin::StorageEngine
119
110
{
 
111
  typedef std::map<string, TinaShare*> TinaMap;
 
112
  TinaMap tina_open_tables;
120
113
public:
121
114
  Tina(const string& name_arg)
122
115
   : drizzled::plugin::StorageEngine(name_arg,
124
117
                                     HTON_NO_AUTO_INCREMENT |
125
118
                                     HTON_HAS_DATA_DICTIONARY |
126
119
                                     HTON_SKIP_STORE_LOCK |
127
 
                                     HTON_FILE_BASED) {}
 
120
                                     HTON_FILE_BASED),
 
121
    tina_open_tables()
 
122
  {}
128
123
  virtual Cursor *create(TableShare &table,
129
124
                          MEM_ROOT *mem_root)
130
125
  {
151
146
  void doGetTableNames(CachedDirectory &, string& , set<string>&) { };
152
147
 
153
148
  int doDropTable(Session&, const string table_path);
 
149
  TinaShare *findOpenTable(const string table_name);
 
150
  void addOpenTable(const string &table_name, TinaShare *);
 
151
  void deleteOpenTable(const string &table_name);
 
152
 
154
153
 
155
154
  uint32_t max_keys()          const { return 0; }
156
155
  uint32_t max_key_parts()     const { return 0; }
189
188
  return error;
190
189
}
191
190
 
 
191
TinaShare *Tina::findOpenTable(const string table_name)
 
192
{
 
193
  TinaMap::iterator find_iter=
 
194
    tina_open_tables.find(table_name);
 
195
 
 
196
  if (find_iter != tina_open_tables.end())
 
197
    return (*find_iter).second;
 
198
  else
 
199
    return NULL;
 
200
}
 
201
 
 
202
void Tina::addOpenTable(const string &table_name, TinaShare *share)
 
203
{
 
204
  tina_open_tables[table_name]= share;
 
205
}
 
206
 
 
207
void Tina::deleteOpenTable(const string &table_name)
 
208
{
 
209
  tina_open_tables.erase(table_name);
 
210
}
 
211
 
 
212
 
192
213
int Tina::doGetTableDefinition(Session&,
193
214
                               const char* path,
194
215
                               const char *,
223
244
  registry.add(tina_engine);
224
245
 
225
246
  pthread_mutex_init(&tina_mutex,MY_MUTEX_INIT_FAST);
226
 
  (void) hash_init(&tina_open_tables,system_charset_info,32,0,0,
227
 
                   (hash_get_key) tina_get_key,0,0);
228
247
  return 0;
229
248
}
230
249
 
233
252
  registry.remove(tina_engine);
234
253
  delete tina_engine;
235
254
 
236
 
  hash_free(&tina_open_tables);
237
255
  pthread_mutex_destroy(&tina_mutex);
238
256
 
239
257
  return 0;
240
258
}
241
259
 
242
260
 
 
261
TinaShare::TinaShare(const char *table_name_arg)
 
262
  : table_name(table_name_arg), use_count(0), saved_data_file_length(0),
 
263
    update_file_opened(false), tina_write_opened(false),
 
264
    crashed(false), rows_recorded(0), data_file_version(0)
 
265
{
 
266
  thr_lock_init(&lock);
 
267
  fn_format(data_file_name, table_name_arg, "", CSV_EXT,
 
268
            MY_REPLACE_EXT|MY_UNPACK_FILENAME);
 
269
}
 
270
 
 
271
TinaShare::~TinaShare()
 
272
{
 
273
  thr_lock_delete(&lock);
 
274
  pthread_mutex_destroy(&mutex);
 
275
}
 
276
 
243
277
/*
244
278
  Simple lock controls.
245
279
*/
246
 
static TINA_SHARE *get_share(const char *table_name, Table *)
 
280
TinaShare *ha_tina::get_share(const char *table_name)
247
281
{
248
 
  TINA_SHARE *share;
 
282
  pthread_mutex_lock(&tina_mutex);
 
283
 
 
284
  Tina *a_tina= static_cast<Tina *>(engine);
 
285
  share= a_tina->findOpenTable(table_name);
 
286
 
249
287
  char meta_file_name[FN_REFLEN];
250
288
  struct stat file_stat;
251
 
  char *tmp_name;
252
 
  uint32_t length;
253
 
 
254
 
  pthread_mutex_lock(&tina_mutex);
255
 
  length=(uint) strlen(table_name);
256
289
 
257
290
  /*
258
291
    If share is not present in the hash, create a new share and
259
292
    initialize its members.
260
293
  */
261
 
  if (!(share=(TINA_SHARE*) hash_search(&tina_open_tables,
262
 
                                        (unsigned char*) table_name,
263
 
                                       length)))
 
294
  if (! share)
264
295
  {
265
 
    if (!drizzled::memory::multi_malloc(true,
266
 
                         &share, sizeof(*share),
267
 
                         &tmp_name, length+1,
268
 
                         NULL))
 
296
    share= new TinaShare(table_name);
 
297
 
 
298
    if (share == NULL)
269
299
    {
270
300
      pthread_mutex_unlock(&tina_mutex);
271
301
      return NULL;
272
302
    }
273
303
 
274
 
    share->use_count= 0;
275
 
    share->table_name_length= length;
276
 
    share->table_name= tmp_name;
277
 
    share->crashed= false;
278
 
    share->rows_recorded= 0;
279
 
    share->update_file_opened= false;
280
 
    share->tina_write_opened= false;
281
 
    share->data_file_version= 0;
282
 
    strcpy(share->table_name, table_name);
283
 
    fn_format(share->data_file_name, table_name, "", CSV_EXT,
284
 
              MY_REPLACE_EXT|MY_UNPACK_FILENAME);
285
304
    fn_format(meta_file_name, table_name, "", CSM_EXT,
286
305
              MY_REPLACE_EXT|MY_UNPACK_FILENAME);
287
306
 
288
307
    if (stat(share->data_file_name, &file_stat))
289
 
      goto error;
 
308
    {
 
309
      pthread_mutex_unlock(&tina_mutex);
 
310
      delete share;
 
311
      return NULL;
 
312
    }
 
313
  
290
314
    share->saved_data_file_length= file_stat.st_size;
291
315
 
292
 
    if (my_hash_insert(&tina_open_tables, (unsigned char*) share))
293
 
      goto error;
294
 
    thr_lock_init(&share->lock);
 
316
    a_tina->addOpenTable(share->table_name, share);
 
317
 
295
318
    pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
296
319
 
297
320
    /*
315
338
  pthread_mutex_unlock(&tina_mutex);
316
339
 
317
340
  return share;
318
 
 
319
 
error:
320
 
  pthread_mutex_unlock(&tina_mutex);
321
 
  free((unsigned char*) share);
322
 
 
323
 
  return NULL;
324
341
}
325
342
 
326
343
 
449
466
/*
450
467
  Free lock controls.
451
468
*/
452
 
static int free_share(TINA_SHARE *share)
 
469
int ha_tina::free_share()
453
470
{
454
471
  pthread_mutex_lock(&tina_mutex);
455
472
  int result_code= 0;
466
483
      share->tina_write_opened= false;
467
484
    }
468
485
 
469
 
    hash_delete(&tina_open_tables, (unsigned char*) share);
470
 
    thr_lock_delete(&share->lock);
471
 
    pthread_mutex_destroy(&share->mutex);
472
 
    free((unsigned char*) share);
 
486
    Tina *a_tina= static_cast<Tina *>(engine);
 
487
    a_tina->deleteOpenTable(share->table_name);
 
488
    delete share;
473
489
  }
474
490
  pthread_mutex_unlock(&tina_mutex);
475
491
 
865
881
*/
866
882
int ha_tina::open(const char *name, int, uint32_t)
867
883
{
868
 
  if (!(share= get_share(name, table)))
 
884
  if (!(share= get_share(name)))
869
885
    return(ENOENT);
870
886
 
871
887
  if (share->crashed)
872
888
  {
873
 
    free_share(share);
 
889
    free_share();
874
890
    return(HA_ERR_CRASHED_ON_USAGE);
875
891
  }
876
892
 
902
918
{
903
919
  int rc= 0;
904
920
  rc= my_close(data_file, MYF(0));
905
 
  return(free_share(share) || rc);
 
921
  return(free_share() || rc);
906
922
}
907
923
 
908
924
/*
951
967
  if (!share->update_file_opened)
952
968
  {
953
969
    if ((update_temp_file=
954
 
           my_create(fn_format(updated_fname, share->table_name,
 
970
           my_create(fn_format(updated_fname, share->table_name.c_str(),
955
971
                               "", CSN_EXT,
956
972
                               MY_REPLACE_EXT | MY_UNPACK_FILENAME),
957
973
                     0, O_RDWR | O_TRUNC, MYF(MY_WME))) < 0)
1292
1308
      of the old datafile.
1293
1309
    */
1294
1310
    if (my_close(data_file, MYF(0)) ||
1295
 
        my_rename(fn_format(updated_fname, share->table_name, "", CSN_EXT,
 
1311
        my_rename(fn_format(updated_fname, share->table_name.c_str(),
 
1312
                            "", CSN_EXT,
1296
1313
                            MY_REPLACE_EXT | MY_UNPACK_FILENAME),
1297
1314
                  share->data_file_name, MYF(0)))
1298
1315
      return(-1);