Below is the list of changes that have just been committed into a local
5.1 repository of tomas. When tomas does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.1871 05/05/24 12:03:33 tomas@stripped +7 -0
removed usage of table map in mysql bin log
added table_map_id on table object instead
changed table mapping to only be id->TABLE*
changed table mapping to use hash insead of linear search
sql/table.h
1.99 05/05/24 12:03:27 tomas@stripped +3 -0
removed usage of table map in mysql bin log
added table_map_id on table object instead
sql/table.cc
1.163 05/05/24 12:03:26 tomas@stripped +4 -0
removed usage of table map in mysql bin log
added table_map_id on table object instead
sql/sql_class.h
1.241 05/05/24 12:03:26 tomas@stripped +17 -10
removed usage of table map in mysql bin log
added table_map_id on table object instead
sql/sql_class.cc
1.188 05/05/24 12:03:26 tomas@stripped +19 -12
removed usage of table map in mysql bin log
added table_map_id on table object instead
sql/rpl_tblmap.h
1.5 05/05/24 12:03:26 tomas@stripped +19 -31
changed table mapping to only be id->TABLE*
changed table mapping to use hash insead of linear search
sql/rpl_tblmap.cc
1.7 05/05/24 12:03:26 tomas@stripped +75 -104
changed table mapping to only be id->TABLE*
changed table mapping to use hash insead of linear search
sql/log.cc
1.168 05/05/24 12:03:26 tomas@stripped +15 -35
removed usage of table map in mysql bin log
added table_map_id on table object instead
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: tomas
# Host: poseidon.ndb.mysql.com
# Root: /home/tomas/wl2325-test
--- 1.167/sql/log.cc 2005-05-09 23:17:23 +02:00
+++ 1.168/sql/log.cc 2005-05-24 12:03:26 +02:00
@@ -349,7 +349,7 @@
:bytes_written(0), last_time(0), query_start(0), name(0),
file_id(1), open_count(1), log_type(LOG_CLOSED), write_error(0), inited(0),
need_start_event(1), prepared_xids(0),
- m_table_map(NULL), m_next_table_id(0),
+ m_next_table_id(0),
description_event_for_exec(0), description_event_for_queue(0)
{
/*
@@ -377,6 +377,7 @@
(void) pthread_mutex_destroy(&LOCK_log);
(void) pthread_mutex_destroy(&LOCK_index);
(void) pthread_cond_destroy(&update_cond);
+ (void) pthread_mutex_destroy(&LOCK_next_table_id);
}
DBUG_VOID_RETURN;
}
@@ -423,6 +424,7 @@
(void) pthread_mutex_init(&LOCK_log,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW);
(void) pthread_cond_init(&update_cond, 0);
+ (void) pthread_mutex_init(&LOCK_next_table_id, MY_MUTEX_INIT_FAST);
}
const char *MYSQL_LOG::generate_name(const char *log_name,
@@ -2277,49 +2279,27 @@
DBUG_ENTER("MYSQL_LOG::get_table_id(TABLE*)");
DBUG_PRINT("enter", ("table=%p", table));
DBUG_ASSERT(table != NULL);
-
- // Have to create it here since it relies on my_malloc, which requires
- // my_init() to have been executed prior to this.
- if (m_table_map == NULL)
- m_table_map = new table_mapping;
-
- DBUG_ASSERT(m_table_map != NULL);
-
- ulong tid = m_table_map->get_table_id(table);
+ ulong tid= table->s->table_map_id;
if (tid == table_mapping::NO_TABLE) {
- // We can't use the number of tables in the list since the highest table
- // id might be larger than the number of elements in the list.
+ pthread_mutex_lock(&LOCK_next_table_id);
+ // need to double check under mutex that no other thread has snuck in
+ // and set the table_map_id
+ if ((tid= table->s->table_map_id) != table_mapping::NO_TABLE)
+ goto get_table_id_set;
+
+ // get next id
tid = m_next_table_id++;
// There is one reserved number that cannot be used.
if (tid == table_mapping::NO_TABLE)
tid = m_next_table_id++;
-
- m_table_map->set_table(tid, table);
+
+ table->s->table_map_id= tid;
+get_table_id_set:
+ pthread_mutex_unlock(&LOCK_next_table_id);
}
DBUG_PRINT("return", ("table_id=%d", tid));
DBUG_RETURN(tid);
-}
-
-int MYSQL_LOG::
-is_table_mapped(TABLE* table) const
-{
- DBUG_ASSERT(table != NULL);
-
- // Have to create it here since it relies on my_malloc, which requires
- // my_init() to have been executed prior to this.
- if (m_table_map == NULL)
- m_table_map = new table_mapping;
-
- DBUG_ASSERT(m_table_map != NULL);
- return m_table_map->get_table_id(table) != table_mapping::NO_TABLE;
-}
-
-void MYSQL_LOG::
-clear_table_mappings()
-{
- DBUG_ASSERT(m_table_map != NULL);
- m_table_map->clear_tables();
}
#endif // !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
--- 1.187/sql/sql_class.cc 2005-05-20 16:20:02 +02:00
+++ 1.188/sql/sql_class.cc 2005-05-24 12:03:26 +02:00
@@ -210,7 +210,7 @@
ull=0;
system_thread= cleanup_done= abort_on_warning= no_warnings_for_error= 0;
peer_port= 0; // For SHOW PROCESSLIST
- transaction.m_pending_rows_event = 0;
+ transaction.m_pending_rows_event= 0;
#ifdef __WIN__
real_id = 0;
#endif
@@ -1836,7 +1836,7 @@
set_pending_event(Rows_log_event* ev)
{
DBUG_ENTER("THD::set_pending_event(Rows_log_event*)");
- transaction.m_pending_rows_event = ev;
+ transaction.m_pending_rows_event= ev;
DBUG_RETURN(0); // Ok
}
@@ -1844,7 +1844,7 @@
get_pending_event() const
{
DBUG_ENTER("THD::get_pending_event()");
- Rows_log_event* ev = transaction.m_pending_rows_event;
+ Rows_log_event* ev= transaction.m_pending_rows_event;
DBUG_RETURN(ev);
}
@@ -1873,13 +1873,13 @@
bool is_transactional)
{
// Fetch the type code for the RowsEventT template parameter
- int const type_code = RowsEventT::TYPE_CODE;
+ int const type_code= RowsEventT::TYPE_CODE;
DBUG_ENTER("THD::prepare_pending<RowsEventT>(TABLE*, ...)");
DBUG_PRINT("enter", ("table=%p (%s), type_code=%d, needed=%d",
table, table->s->table_name,
type_code, needed));
- Rows_log_event* pending = get_pending_event();
+ Rows_log_event* pending= get_pending_event();
if (pending)
{
@@ -1899,16 +1899,17 @@
// Check if the current event is non-NULL and a write-rows event. Also check
// if the table provided is mapped: if it is not, then we have switched to
// writing to a new table.
- bool was_mapped = false;
+ bool was_mapped= false;
+// || pending->m_table != table
if (!pending
|| pending->server_id != server_id
|| pending->get_type_code() != type_code
|| pending->get_data_size() + needed > opt_binlog_rows_event_max_size
|| pending->get_cols() != cols
- || !(was_mapped= mysql_bin_log.is_table_mapped(table)))
+ || !(was_mapped= is_table_mapped(table)))
{
// If not, flush the event and create a new RowsEventT.
- ulong const tid = mysql_bin_log.get_table_id(table);
+ ulong const tid= get_table_id(table);
Rows_log_event* const
ev = new RowsEventT(this, table, tid, cols, is_transactional);
@@ -1955,7 +1956,7 @@
DBUG_ASSERT(opt_binlog_row_level);
DBUG_ASSERT(mysql_bin_log.is_open());
- if (Rows_log_event* pending = get_pending_event()) {
+ if (Rows_log_event* pending= get_pending_event()) {
if (mysql_bin_log.write(pending)) {
DBUG_PRINT("exit", ("1"));
DBUG_RETURN(1); // Something failed
@@ -2264,6 +2265,13 @@
DBUG_RETURN(error);
}
+ulong THD::
+get_new_table_id(TABLE* table)
+{
+ ulong id= mysql_bin_log.get_table_id(table);
+ return id;
+}
+
int THD::
write_table_map(TABLE* table, bool is_transactional)
{
@@ -2273,7 +2281,7 @@
if (!opt_binlog_row_level || !mysql_bin_log.is_open())
DBUG_RETURN(0);
- ulong table_id = mysql_bin_log.get_table_id(table);
+ ulong table_id= get_table_id(table);
Table_map_log_event::enum_flags const
flags = Table_map_log_event::NO_FLAGS;
@@ -2299,11 +2307,10 @@
set.
*/
if (trans_end) {
- if (Rows_log_event* pending = get_pending_event()) {
+ if (Rows_log_event* pending= get_pending_event()) {
pending->set_flag(Rows_log_event::TRANS_END_F);
DBUG_ASSERT(mysql_bin_log.is_open());
- mysql_bin_log.clear_table_mappings();
}
}
--- 1.240/sql/sql_class.h 2005-05-09 23:17:25 +02:00
+++ 1.241/sql/sql_class.h 2005-05-24 12:03:26 +02:00
@@ -240,9 +240,7 @@
pthread_cond_t COND_prep_xids;
friend class Log_event;
- // 'Mutable' needed since this class can not be initialized in the
- // constructor.
- mutable table_mapping* m_table_map;
+ pthread_mutex_t LOCK_next_table_id;
ulong m_next_table_id;
public:
@@ -263,13 +261,6 @@
// This will return a table id for the table. If the table is not known, a
// new table id will be invented and returned.
ulong get_table_id(TABLE* table);
-
- // This will check if the given table is mapped to any table id
- int is_table_mapped(TABLE* table) const;
-
- // This will clear all table mappings
- void clear_table_mappings();
-
#endif // !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
/*
These describe the log's format. This is used only for relay logs.
@@ -1117,6 +1108,22 @@
byte *row_data, size_t max_len, const byte *data) const;
int flush_pending_event(bool transaction_end);
+
+ ulong get_new_table_id(TABLE* table);
+
+ ulong get_table_id(TABLE* table)
+ {
+ ulong id= table->s->table_map_id;
+ if (id != table_mapping::NO_TABLE)
+ return id;
+ return get_new_table_id(table);
+ }
+
+ int is_table_mapped(TABLE* table)
+ {
+ return table->s->table_map_id != table_mapping::NO_TABLE;
+ }
+
int write_table_map(TABLE*,bool);
#endif
--- 1.162/sql/table.cc 2005-05-10 00:58:28 +02:00
+++ 1.163/sql/table.cc 2005-05-24 12:03:26 +02:00
@@ -848,6 +848,10 @@
if (use_hash)
(void) hash_check(&share->name_hash);
#endif
+#ifdef HAVE_REPLICATION
+ share->table_map_id= table_mapping::NO_TABLE;
+#endif
+
DBUG_RETURN (0);
err:
--- 1.98/sql/table.h 2005-05-09 14:26:50 +02:00
+++ 1.99/sql/table.h 2005-05-24 12:03:27 +02:00
@@ -163,6 +163,9 @@
my_bool crashed;
my_bool is_view;
my_bool name_lock, replace_with_name_lock;
+#ifdef HAVE_REPLICATION
+ ulong table_map_id;
+#endif
} TABLE_SHARE;
--- 1.6/sql/rpl_tblmap.cc 2005-05-07 15:11:30 +02:00
+++ 1.7/sql/rpl_tblmap.cc 2005-05-24 12:03:26 +02:00
@@ -4,158 +4,123 @@
#include "my_pthread.h"
#define MAYBE_TABLE_NAME(T) ((T) ? (T)->s->table_name : "<>")
+#define TABLE_ID_HASH_SIZE 32
+#define TABLE_ID_CHUNK 256
table_mapping::
table_mapping()
- : m_array(0), m_count(0), m_reserve(16)
+ : m_array(0), m_free(0), m_reserve(0)
{
- pthread_mutex_init(&m_mutex, NULL);
- sentry sentry(&m_mutex);
-
- // TODO: my_malloc() can fail
- m_array = reinterpret_cast<entry*>(my_malloc(m_reserve * sizeof(*m_array),
- MYF(0)));
+ (void) hash_init(&m_table_ids,&my_charset_bin,TABLE_ID_HASH_SIZE,
+ offsetof(entry,table_id),sizeof(ulong),
+ 0,0,0);
}
table_mapping::
~table_mapping()
{
{
- sentry sentry(&m_mutex);
+ for (int i= 0; i < m_reserve; i++)
+ my_free(reinterpret_cast<char*>(m_array[i]), MYF(MY_ALLOW_ZERO_PTR));
my_free(reinterpret_cast<char*>(m_array), MYF(MY_ALLOW_ZERO_PTR));
m_array = NULL;
}
- pthread_mutex_destroy(&m_mutex);
-}
-
-ulong table_mapping::
-find_pos(ulong table_id) const
-{
- DBUG_ASSERT(m_count <= m_reserve);
- DBUG_ASSERT(m_array != NULL);
- // N.B.: This is a linear search, it will be infeasible to use for larger
- // number of tables in the air at the same time. Switch to a binary search
- // later.
- for (ulong i = 0 ; i < m_count ; ++i) {
- if (m_array[i].table_id == table_id)
- return i;
- }
- return m_count;
-}
-
-ulong table_mapping::
-find_pos(st_table* table) const
-{
- DBUG_ASSERT(m_count <= m_reserve);
- DBUG_ASSERT(m_array != NULL);
- // N.B.: This is a linear search, it will be infeasible to use for larger
- // number of tables in the air at the same time. Switch to a binary search
- // later.
- for (ulong i = 0 ; i < m_count ; ++i) {
- if (m_array[i].table == table)
- return i;
- }
- return m_count;
}
st_table* table_mapping::
get_table(ulong table_id)
{
- sentry sentry(&m_mutex); // Acquire exlusive access
-
DBUG_ENTER("table_mapping::get_table(ulong)");
DBUG_PRINT("enter", ("table_id=%d", table_id));
- pos_type const pos = find_pos(table_id);
- if (pos < m_count)
+ entry *e= find_entry(table_id);
+ if (e)
{
DBUG_PRINT("info", ("tid %d -> table %p (%s)",
- table_id, m_array[pos].table,
- MAYBE_TABLE_NAME(m_array[pos].table)));
- DBUG_RETURN(m_array[pos].table);
+ table_id, e->table,
+ MAYBE_TABLE_NAME(e->table)));
+ DBUG_RETURN(e->table);
}
DBUG_PRINT("info", ("tid %d is not mapped!", table_id));
DBUG_RETURN(NULL);
}
-
-ulong table_mapping::
-get_table_id(st_table* table)
+int table_mapping::
+expand()
{
- sentry sentry(&m_mutex); // Aquire exclusive access
-
- DBUG_ENTER("table_mapping::get_table_id(st_table*)");
- DBUG_PRINT("enter", ("table=%p (%s)", table, MAYBE_TABLE_NAME(table)));
- pos_type const pos = find_pos(table);
- if (pos < m_count)
- {
- DBUG_PRINT("info", ("table %p (%s) -> table id %d",
- m_array[pos].table,
- MAYBE_TABLE_NAME(m_array[pos].table),
- m_array[pos].table_id));
- DBUG_RETURN(m_array[pos].table_id);
- }
- DBUG_PRINT("info", ("table %p (%s) is not mapped!",
- table,
- MAYBE_TABLE_NAME(table)));
- DBUG_RETURN(NO_TABLE);
+ int reserve= m_reserve+1;
+ {
+ entry **array;
+ if (m_array)
+ array= (entry **)my_realloc((char*) m_array,
+ reserve*sizeof(*m_array),
+ MYF(MY_WME));
+ else
+ array= (entry **)my_malloc(reserve*sizeof(*m_array),
+ MYF(MY_WME));
+ if (array == NULL)
+ {
+ return ERR_MEMORY_ALLOCATION; // Memory allocation failed
+ }
+ m_array = array;
+ }
+ {
+ entry *tmp= (entry *)my_malloc(TABLE_ID_CHUNK*sizeof(**m_array),MYF(MY_WME));
+ if (tmp == NULL)
+ {
+ return ERR_MEMORY_ALLOCATION; // Memory allocation failed
+ }
+ m_array[m_reserve]= tmp;
+
+ entry *e_end= tmp+TABLE_ID_CHUNK-1;
+ for (entry *e= tmp; e < e_end; e++)
+ e->next= e;
+ e_end->next= m_free;
+ m_free= tmp;
+ }
+ m_reserve= reserve;
+ return 0;
}
int table_mapping::
set_table(ulong table_id, TABLE* table)
{
- sentry sentry(&m_mutex);
-
DBUG_ENTER("table_mapping::set_table(ulong,TABLE*)");
DBUG_PRINT("enter", ("table_id=%d, table=%p (%s)",
table_id,
table, MAYBE_TABLE_NAME(table)));
- pos_type const pos = find_pos(table_id);
-
- if (pos == m_count && m_reserve == m_count)
+ entry *e= find_entry(table_id);
+ if (e == 0)
{
- // We're adding a new table now, we need to extend the array to make space
- // for the new table data.
- if (m_reserve > ULONG_MAX/2)
- DBUG_RETURN(ERR_LIMIT_EXCEEDED); // Table upper limit exceeded
-
- int const reserve = 2*m_reserve;
- entry* const
- array = (entry*) my_realloc((char*) m_array,
- reserve*sizeof(*m_array),
- MYF(MY_WME));
- if (array == NULL)
- {
- DBUG_RETURN(ERR_MEMORY_ALLOCATION); // Memory allocation failed
- }
- m_reserve = reserve;
- m_array = array;
+ if (m_free == 0 && expand())
+ DBUG_RETURN(ERR_MEMORY_ALLOCATION); // Memory allocation failed
+ e= m_free;
+ m_free= m_free->next;
+ }
+ else
+ {
+ hash_delete(&m_table_ids,(byte *)e);
}
- DBUG_ASSERT(m_count <= m_reserve);
- if (pos == m_count)
- ++m_count;
-
- DBUG_ASSERT(pos < m_count);
- m_array[pos].table_id = table_id;
- m_array[pos].table = table;
+ e->table_id= table_id;
+ e->table= table;
+ my_hash_insert(&m_table_ids,(byte *)e);
+
DBUG_PRINT("info", ("tid %d -> table %p (%s)",
- table_id, m_array[pos].table,
- MAYBE_TABLE_NAME(m_array[pos].table)));
+ table_id, e->table,
+ MAYBE_TABLE_NAME(e->table)));
DBUG_RETURN(0); // All OK
}
int table_mapping::
remove_table(ulong table_id)
{
- sentry sentry(&m_mutex);
-
- ulong pos = find_pos(table_id);
- if (pos < m_count)
+ entry *e= find_entry(table_id);
+ if (e)
{
- while (++pos < m_count)
- m_array[pos-1] = m_array[pos];
- --m_count;
+ hash_delete(&m_table_ids,(byte *)e);
+ e->next= m_free;
+ m_free= e;
return 0; // All OK
}
return 1; // No table to remove
@@ -165,7 +130,13 @@
clear_tables()
{
DBUG_ENTER("table_mapping::clear_tables()");
- m_count = 0;
+ for (uint i= 0; i < m_table_ids.records; i++)
+ {
+ entry *e= (entry *)hash_element(&m_table_ids, i);
+ e->next= m_free;
+ m_free= e;
+ }
+ my_hash_reset(&m_table_ids);
DBUG_VOID_RETURN;
}
--- 1.4/sql/rpl_tblmap.h 2005-05-04 15:59:53 +02:00
+++ 1.5/sql/rpl_tblmap.h 2005-05-24 12:03:26 +02:00
@@ -13,16 +13,13 @@
CLASS table_mapping
RESPONSIBILITIES
- The table mapping is used to map table pointer to table id's and vice
- versa.
+ The table mapping is used to map table id's to table pointers
COLLABORATION
- MYSQL_LOG For mapping tables to table id:s before sending events.
RELAY_LOG For mapping table id:s to tables when receiving events.
*/
class table_mapping {
public:
- typedef ulong pos_type;
enum {
NO_TABLE = ULONG_MAX
@@ -39,42 +36,33 @@
TABLE* get_table(ulong table_id);
- /*
- Return table id for 'table', or NO_TABLE if there is no id mapped for
- table.
- */
- ulong get_table_id(TABLE* table);
-
int set_table(ulong table_id, TABLE* table);
int remove_table(ulong table_id);
void clear_tables();
- ulong count() const { return m_count; }
+ ulong count() const { return m_table_ids.records; }
private:
- pos_type find_pos(ulong table_id) const;
- pos_type find_pos(TABLE* table) const;
-
struct entry {
- ulong table_id;
- TABLE* table;
+ ulong table_id;
+ union {
+ TABLE *table;
+ entry *next;
+ };
};
- entry *m_array;
- ulong m_count, m_reserve;
- class sentry {
- public:
- sentry(pthread_mutex_t *mutex)
- : m_mptr(mutex)
- {
- pthread_mutex_lock(m_mptr);
- }
-
- ~sentry() { pthread_mutex_unlock(m_mptr); }
- private:
- pthread_mutex_t* m_mptr;
- };
+ entry *find_entry(ulong table_id)
+ {
+ return (entry *)hash_search(&m_table_ids,
+ (byte*)&table_id,
+ sizeof(table_id));
+ }
+ int expand();
+
+ entry **m_array;
+ entry *m_free;
+ ulong m_reserve;
- pthread_mutex_t m_mutex;
+ HASH m_table_ids;
};
#endif
| Thread |
|---|
| • bk commit into 5.1 tree (tomas:1.1871) | tomas | 24 May |