~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

  • Committer: Brian Aker
  • Date: 2010-07-28 00:15:41 UTC
  • Revision ID: brian@gaz-20100728001541-p6rs038hko6xqakn
This patch turns the table_cache into boost::unordered_multimap.
This also removes a number of cases where we were using strcmp() on table
name/schema name.

Show diffs side-by-side

added added

removed removed

Lines of Context:
62
62
 
63
63
extern bool volatile shutdown_in_progress;
64
64
 
65
 
/**
66
 
  @defgroup Data_Dictionary Data Dictionary
67
 
  @{
68
 
*/
69
 
 
70
 
 
71
 
HASH &get_open_cache()
 
65
TableOpenCache &get_open_cache()
72
66
{
73
 
  static HASH open_cache;                               /* Used by mysql_test */
 
67
  static TableOpenCache open_cache;                             /* Used by mysql_test */
74
68
 
75
69
  return open_cache;
76
70
}
77
71
 
 
72
static void free_cache_entry(Table *entry);
 
73
 
 
74
void remove_table(Table *arg)
 
75
{
 
76
  TableOpenCacheRange ppp;
 
77
  ppp= get_open_cache().equal_range(arg->getShare()->getCacheKey());
 
78
 
 
79
  for (TableOpenCache::const_iterator iter= ppp.first;
 
80
         iter != ppp.second; ++iter)
 
81
  {
 
82
    Table *found_table= (*iter).second;
 
83
 
 
84
    if (found_table == arg)
 
85
    {
 
86
      free_cache_entry(arg);
 
87
      get_open_cache().erase(iter);
 
88
      return;
 
89
    }
 
90
  }
 
91
}
 
92
 
 
93
static bool add_table(Table *arg)
 
94
{
 
95
  TableOpenCache &open_cache(get_open_cache());
 
96
 
 
97
  TableOpenCache::iterator returnable= open_cache.insert(make_pair(arg->getShare()->getCacheKey(), arg));
 
98
 
 
99
  return not (returnable == open_cache.end());
 
100
}
 
101
 
78
102
class UnusedTables {
79
103
  Table *tables;                                /* Used by mysql_test */
80
104
 
93
117
  void cull()
94
118
  {
95
119
    /* Free cache if too big */
96
 
    while (get_open_cache().records > table_cache_size && getTable())
97
 
      hash_delete(&get_open_cache(), (unsigned char*) getTable());
 
120
    while (cached_open_tables() > table_cache_size && getTable())
 
121
      remove_table(getTable());
98
122
  }
99
123
 
100
124
  void cullByVersion()
101
125
  {
102
126
    while (getTable() && not getTable()->getShare()->getVersion())
103
 
      hash_delete(&get_open_cache(), (unsigned char*) getTable());
 
127
      remove_table(getTable());
104
128
  }
105
129
  
106
130
  void link(Table *table)
154
178
  void clear()
155
179
  {
156
180
    while (getTable())
157
 
      hash_delete(&get_open_cache(), (unsigned char*) getTable());
 
181
      remove_table(getTable());
158
182
  }
159
183
 
160
184
  UnusedTables():
171
195
                             Table *entry,
172
196
                             const char *alias,
173
197
                             TableIdentifier &identifier);
174
 
void free_cache_entry(void *entry);
 
198
 
175
199
unsigned char *table_cache_key(const unsigned char *record,
176
200
                               size_t *length,
177
201
                               bool );
191
215
 
192
216
bool table_cache_init(void)
193
217
{
194
 
  return hash_init(&get_open_cache(), &my_charset_bin,
195
 
                   (size_t) table_cache_size+16,
196
 
                   0, 0, table_cache_key,
197
 
                   free_cache_entry, 0);
 
218
  return false;
 
219
}
 
220
 
 
221
uint32_t cached_open_tables(void)
 
222
{
 
223
  return get_open_cache().size();
198
224
}
199
225
 
200
226
void table_cache_free(void)
202
228
  refresh_version++;                            // Force close of open tables
203
229
 
204
230
  unused_tables.clear();
205
 
 
206
 
  if (not get_open_cache().records)                     // Safety first
207
 
    hash_free(&get_open_cache());
208
 
}
209
 
 
210
 
uint32_t cached_open_tables(void)
211
 
{
212
 
  return get_open_cache().records;
213
 
}
214
 
 
 
231
  get_open_cache().clear();
 
232
}
215
233
 
216
234
/*
217
235
  Close cursor handle, but leave the table in the table cache
281
299
  We need to have a lock on LOCK_open when calling this
282
300
*/
283
301
 
284
 
void free_cache_entry(void *entry)
 
302
void free_cache_entry(Table *table)
285
303
{
286
 
  Table *table= static_cast<Table *>(entry);
287
 
 
288
304
  table->intern_close_table();
289
305
  if (not table->in_use)
290
306
  {
381
397
        after the call to Session::close_old_data_files() i.e. after removal of
382
398
        current thread locks.
383
399
      */
384
 
      for (uint32_t idx=0 ; idx < get_open_cache().records ; idx++)
 
400
      for (TableOpenCache::const_iterator iter= get_open_cache().begin();
 
401
           iter != get_open_cache().end();
 
402
           iter++)
385
403
      {
386
 
        Table *table=(Table*) hash_element(&get_open_cache(),idx);
 
404
        Table *table= (*iter).second;
387
405
        if (table->in_use)
388
406
          table->in_use->some_tables_deleted= false;
389
407
      }
422
440
    while (found && ! session->killed)
423
441
    {
424
442
      found= false;
425
 
      for (uint32_t idx=0 ; idx < get_open_cache().records ; idx++)
 
443
      for (TableOpenCache::const_iterator iter= get_open_cache().begin();
 
444
           iter != get_open_cache().end();
 
445
           iter++)
426
446
      {
427
 
        Table *table=(Table*) hash_element(&get_open_cache(), idx);
 
447
        Table *table= (*iter).second;
428
448
        /* Avoid a self-deadlock. */
429
449
        if (table->in_use == session)
430
450
          continue;
433
453
          not for placeholders with Table::open_placeholder set. Waiting for
434
454
          latter will cause deadlock in the following scenario, for example:
435
455
 
436
 
conn1: lock table t1 write;
437
 
conn2: lock table t2 write;
438
 
conn1: flush tables;
439
 
conn2: flush tables;
 
456
          conn1-> lock table t1 write;
 
457
          conn2-> lock table t2 write;
 
458
          conn1-> flush tables;
 
459
          conn2-> flush tables;
440
460
 
441
 
It also does not make sense to wait for those of placeholders that
442
 
are employed by CREATE TABLE as in this case table simply does not
443
 
exist yet.
 
461
          It also does not make sense to wait for those of placeholders that
 
462
          are employed by CREATE TABLE as in this case table simply does not
 
463
          exist yet.
444
464
        */
445
465
        if (table->needs_reopen_or_name_lock() && (table->db_stat ||
446
466
                                                   (table->open_placeholder && wait_for_placeholders)))
503
523
  if (table->needs_reopen_or_name_lock() ||
504
524
      version != refresh_version || !table->db_stat)
505
525
  {
506
 
    hash_delete(&get_open_cache(), (unsigned char*) table);
 
526
    remove_table(table);
507
527
    found_old_table= true;
508
528
  }
509
529
  else
867
887
      *prev= list->getNext();
868
888
 
869
889
      /* Close table. */
870
 
      hash_delete(&get_open_cache(),(unsigned char*) list); // Close table
 
890
      remove_table(list);
871
891
    }
872
892
    else
873
893
    {
1064
1084
  case of failure.
1065
1085
*/
1066
1086
 
1067
 
Table *Session::table_cache_insert_placeholder(const char *db_name, const char *table_name, const char *, uint32_t)
 
1087
Table *Session::table_cache_insert_placeholder(const char *db_name, const char *table_name)
1068
1088
{
1069
1089
  safe_mutex_assert_owner(&LOCK_open);
1070
1090
 
1076
1096
  TableIdentifier identifier(db_name, table_name, message::Table::INTERNAL);
1077
1097
  TablePlaceholder *table= new TablePlaceholder(this, identifier);
1078
1098
 
1079
 
  if (my_hash_insert(&get_open_cache(), (unsigned char*)table))
 
1099
  if (not add_table(table))
1080
1100
  {
1081
1101
    delete table;
1082
1102
 
1110
1130
*/
1111
1131
bool Session::lock_table_name_if_not_cached(TableIdentifier &identifier, Table **table)
1112
1132
{
1113
 
  return lock_table_name_if_not_cached(identifier.getSchemaName().c_str(), identifier.getTableName().c_str(), table);
1114
 
}
1115
 
 
1116
 
bool Session::lock_table_name_if_not_cached(const char *new_db,
1117
 
                                            const char *table_name, Table **table)
1118
 
{
1119
 
  char key[MAX_DBKEY_LENGTH];
1120
 
  uint32_t key_length;
1121
 
 
1122
 
  key_length= TableIdentifier::createKey(key, new_db, table_name);
 
1133
  const TableIdentifier::Key &key(identifier.getKey());
1123
1134
 
1124
1135
  pthread_mutex_lock(&LOCK_open); /* Obtain a name lock even though table is not in cache (like for create table)  */
1125
1136
 
1126
 
  if (hash_search(&get_open_cache(), (unsigned char *)key, key_length))
 
1137
  TableOpenCache::iterator iter;
 
1138
 
 
1139
  iter= get_open_cache().find(key);
 
1140
 
 
1141
  if (iter != get_open_cache().end())
1127
1142
  {
1128
1143
    pthread_mutex_unlock(&LOCK_open);
1129
1144
    *table= 0;
1130
1145
    return false;
1131
1146
  }
1132
1147
 
1133
 
  if (not (*table= table_cache_insert_placeholder(new_db, table_name, key, key_length)))
 
1148
  if (not (*table= table_cache_insert_placeholder(identifier.getSchemaName().c_str(), identifier.getTableName().c_str())))
1134
1149
  {
1135
1150
    pthread_mutex_unlock(&LOCK_open);
1136
1151
    return true;
1179
1194
Table *Session::openTable(TableList *table_list, bool *refresh, uint32_t flags)
1180
1195
{
1181
1196
  Table *table;
1182
 
  unsigned int key_length;
1183
1197
  const char *alias= table_list->alias;
1184
 
  HASH_SEARCH_STATE state;
1185
1198
 
1186
1199
  /* Parsing of partitioning information from .frm needs session->lex set up. */
1187
1200
  assert(lex->is_lex_started);
1199
1212
 
1200
1213
  TableIdentifier identifier(table_list->db, table_list->table_name);
1201
1214
  const TableIdentifier::Key &key(identifier.getKey());
1202
 
  key_length= key.size();
 
1215
  TableOpenCacheRange ppp;
1203
1216
 
1204
1217
  /*
1205
1218
    Unless requested otherwise, try to resolve this table in the list
1292
1305
    an implicit "pending locks queue" - see
1293
1306
    wait_for_locked_table_names for details.
1294
1307
  */
1295
 
  for (table= (Table*) hash_first(&get_open_cache(), (unsigned char*) &key[0], key_length,
1296
 
                                  &state);
1297
 
       table && table->in_use ;
1298
 
       table= (Table*) hash_next(&get_open_cache(), (unsigned char*) &key[0], key_length,
1299
 
                                 &state))
 
1308
  ppp= get_open_cache().equal_range(key);
 
1309
 
 
1310
  table= NULL;
 
1311
  for (TableOpenCache::const_iterator iter= ppp.first;
 
1312
       iter != ppp.second; ++iter, table= NULL)
1300
1313
  {
 
1314
    table= (*iter).second;
 
1315
 
 
1316
    if (not table->in_use)
 
1317
      break;
1301
1318
    /*
1302
1319
      Here we flush tables marked for flush.
1303
1320
      Normally, table->getShare()->version contains the value of
1311
1328
      need to back off and re-start opening tables.
1312
1329
      If we do not back off now, we may dead lock in case of lock
1313
1330
      order mismatch with some other thread:
1314
 
c1: name lock t1; -- sort of exclusive lock
1315
 
c2: open t2;      -- sort of shared lock
1316
 
c1: name lock t2; -- blocks
1317
 
c2: open t1; -- blocks
 
1331
      c1-> name lock t1; -- sort of exclusive lock
 
1332
      c2-> open t2;      -- sort of shared lock
 
1333
      c1-> name lock t2; -- blocks
 
1334
      c2-> open t1; -- blocks
1318
1335
    */
1319
1336
    if (table->needs_reopen_or_name_lock())
1320
1337
    {
1398
1415
        /*
1399
1416
          Table to be created, so we need to create placeholder in table-cache.
1400
1417
        */
1401
 
        if (!(table= table_cache_insert_placeholder(table_list->db, table_list->table_name, &key[0], key_length)))
 
1418
        if (!(table= table_cache_insert_placeholder(table_list->db, table_list->table_name)))
1402
1419
        {
1403
1420
          pthread_mutex_unlock(&LOCK_open);
1404
1421
          return NULL;
1434
1451
      pthread_mutex_unlock(&LOCK_open);
1435
1452
      return NULL;
1436
1453
    }
1437
 
    my_hash_insert(&get_open_cache(), (unsigned char*) table);
 
1454
    (void)add_table(table);
1438
1455
  }
1439
1456
 
1440
1457
  pthread_mutex_unlock(&LOCK_open);
1593
1610
 
1594
1611
void Session::close_data_files_and_morph_locks(TableIdentifier &identifier)
1595
1612
{
1596
 
  Table *table;
1597
 
 
1598
1613
  safe_mutex_assert_owner(&LOCK_open); /* Adjust locks at the end of ALTER TABLEL */
1599
1614
 
1600
1615
  if (lock)
1612
1627
    for target table name if we process ALTER Table ... RENAME.
1613
1628
    So loop below makes sense even if we are not under LOCK TABLES.
1614
1629
  */
1615
 
  for (table= open_tables; table ; table=table->getNext())
 
1630
  for (Table *table= open_tables; table ; table=table->getNext())
1616
1631
  {
1617
 
    if (!strcmp(table->getMutableShare()->getTableName(), identifier.getTableName().c_str()) &&
1618
 
        !strcasecmp(table->getMutableShare()->getSchemaName(), identifier.getSchemaName().c_str()))
 
1632
    if (table->getShare()->getCacheKey() == identifier.getKey())
1619
1633
    {
1620
1634
      table->open_placeholder= true;
1621
1635
      close_handle_and_leave_table_as_lock(table);
1683
1697
    next= table->getNext();
1684
1698
 
1685
1699
    my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
1686
 
    hash_delete(&get_open_cache(),(unsigned char*) table);
 
1700
    remove_table(table);
1687
1701
    error= 1;
1688
1702
  }
1689
1703
  *prev=0;
1821
1835
  {
1822
1836
    const TableIdentifier::Key &key(table->getShare()->getCacheKey());
1823
1837
 
1824
 
    HASH_SEARCH_STATE state;
1825
 
    for (Table *search= (Table*) hash_first(&get_open_cache(), (unsigned char*) &key[0],
1826
 
                                            key.size(), &state);
1827
 
         search ;
1828
 
         search= (Table*) hash_next(&get_open_cache(), (unsigned char*) &key[0],
1829
 
                                    key.size(), &state))
 
1838
    TableOpenCacheRange ppp;
 
1839
    ppp= get_open_cache().equal_range(key);
 
1840
 
 
1841
    for (TableOpenCache::const_iterator iter= ppp.first;
 
1842
         iter != ppp.second; ++iter)
1830
1843
    {
 
1844
      Table *search= (*iter).second;
1831
1845
      if (search->in_use == table->in_use)
1832
1846
        continue;                               // Name locked by this thread
1833
1847
      /*
1902
1916
*/
1903
1917
 
1904
1918
 
1905
 
Table *drop_locked_tables(Session *session, const char *db, const char *table_name)
 
1919
Table *drop_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
1906
1920
{
1907
1921
  Table *table,*next,**prev, *found= 0;
1908
1922
  prev= &session->open_tables;
1917
1931
  for (table= session->open_tables; table ; table=next)
1918
1932
  {
1919
1933
    next=table->getNext();
1920
 
    if (!strcmp(table->getMutableShare()->getTableName(), table_name) &&
1921
 
        !strcasecmp(table->getMutableShare()->getSchemaName(), db))
 
1934
    if (table->getShare()->getCacheKey() == identifier.getKey())
1922
1935
    {
1923
1936
      mysql_lock_remove(session, table);
1924
1937
 
1935
1948
      else
1936
1949
      {
1937
1950
        /* We already have a name lock, remove copy */
1938
 
        hash_delete(&get_open_cache(),(unsigned char*) table);
 
1951
        remove_table(table);
1939
1952
      }
1940
1953
    }
1941
1954
    else
1958
1971
  other threads trying to get the lock.
1959
1972
*/
1960
1973
 
1961
 
void abort_locked_tables(Session *session,const char *db, const char *table_name)
 
1974
void abort_locked_tables(Session *session, const drizzled::TableIdentifier &identifier)
1962
1975
{
1963
1976
  Table *table;
1964
1977
  for (table= session->open_tables; table ; table= table->getNext())
1965
1978
  {
1966
 
    if (!strcmp(table->getMutableShare()->getTableName(), table_name) &&
1967
 
        !strcmp(table->getMutableShare()->getSchemaName(), db))
 
1979
    if (table->getShare()->getCacheKey() == identifier.getKey())
1968
1980
    {
1969
1981
      /* If MERGE child, forward lock handling to parent. */
1970
1982
      mysql_lock_abort(session, table);
4492
4504
{
4493
4505
  safe_mutex_assert_owner(&LOCK_open);
4494
4506
 
4495
 
  for (uint32_t idx=0 ; idx < get_open_cache().records ; idx++)
 
4507
  for (TableOpenCache::const_iterator iter= get_open_cache().begin();
 
4508
       iter != get_open_cache().end();
 
4509
       iter++)
4496
4510
  {
4497
 
    Table *table=(Table*) hash_element(&get_open_cache(),idx);
 
4511
    Table *table= (*iter).second;
 
4512
 
4498
4513
    if (not schema_identifier.getPath().compare(table->getMutableShare()->getSchemaName()))
4499
4514
    {
4500
4515
      table->getMutableShare()->resetVersion();                 /* Free when thread is ready */
4528
4543
  bool result= false; 
4529
4544
  bool signalled= false;
4530
4545
 
4531
 
  uint32_t key_length= key.size();
4532
 
 
4533
4546
  for (;;)
4534
4547
  {
4535
 
    HASH_SEARCH_STATE state;
4536
 
    Table *table;
4537
4548
    result= signalled= false;
4538
4549
 
4539
 
    for (table= (Table*) hash_first(&get_open_cache(), (unsigned char*) &key[0], key_length,
4540
 
                                    &state);
4541
 
         table;
4542
 
         table= (Table*) hash_next(&get_open_cache(), (unsigned char*) &key[0], key_length,
4543
 
                                   &state))
 
4550
    TableOpenCacheRange ppp;
 
4551
    ppp= get_open_cache().equal_range(key);
 
4552
 
 
4553
    for (TableOpenCache::const_iterator iter= ppp.first;
 
4554
         iter != ppp.second; ++iter)
4544
4555
    {
 
4556
      Table *table= (*iter).second;
4545
4557
      Session *in_use;
4546
4558
 
4547
4559
      table->getMutableShare()->resetVersion();         /* Free when thread is ready */