===== sql/sql_base.cc 1.422 vs edited ===== --- 1.422/sql/sql_base.cc 2007-12-21 15:15:39 +08:00 +++ edited/sql/sql_base.cc 2007-12-05 15:53:35 +08:00 @@ -843,6 +843,17 @@ } check_unused(); // consisty check } + + if(table->hash_head == table){ + TABLE *t; + for(t=table->hash_next;t!=table;t=t->hash_next){ + t->hash_head = table->hash_next; + } + } + + table->hash_next->hash_prev=table->hash_prev; + table->hash_prev->hash_next=table->hash_next; + my_free((uchar*) table,MYF(0)); DBUG_VOID_RETURN; } @@ -1284,6 +1295,26 @@ /* Free memory and reset for next loop */ table->file->ha_reset(); table->in_use=0; + + if(table != table->hash_head){ + + /* removed from the list (hash_next,hash_prev)*/ + table->hash_prev->hash_next=table->hash_next; + table->hash_next->hash_prev=table->hash_prev; + + + /* insert into the list prev the hash_head */ + TABLE *head; + head= table->hash_head; + + head->hash_prev->hash_next=table; + + table->hash_prev=head->hash_prev; + table->hash_next=head; + + head->hash_prev=table; + } + if (unused_tables) { table->next=unused_tables; /* Link in last */ @@ -2032,6 +2063,10 @@ table->next= orig_table.next; } + table->hash_head=orig_table.hash_head; + table->hash_next=orig_table.hash_next; + table->hash_prev=orig_table.hash_prev; + table->tablenr=thd->current_tablenr++; table->used_fields=0; table->const_table=0; @@ -2082,12 +2117,28 @@ table->in_use= thd; table->locked_by_name=1; + TABLE *find_table=(TABLE *)hash_search(&open_cache,(const uchar *)key,key_length); + if (my_hash_insert(&open_cache, (uchar*)table)) { my_free((uchar*) table, MYF(0)); DBUG_RETURN(NULL); } + if(find_table){ + TABLE * head; + head= find_table->hash_head; + head->hash_next->hash_prev=table; + + table->hash_next=head->hash_next; + table->hash_prev=head; + table->hash_head=head; + + head->hash_next=table; + }else{ + table->hash_head = table->hash_next = table->hash_prev = table; + } + DBUG_RETURN(table); } @@ -2484,6 +2535,15 @@ an implicit "pending locks queue" - see wait_for_locked_table_names for details. */ + table = (TABLE *)hash_search(&open_cache,(uchar *)key,key_length); + + if(table){ + table = table->hash_head; + } + + + if(table && table->needs_reopen_or_name_lock()){ + for (table= (TABLE*) hash_first(&open_cache, (uchar*) key, key_length, &state); table && table->in_use ; @@ -2572,6 +2632,18 @@ DBUG_RETURN(0); } } + }else if(table && table->in_use){ + if(table->hash_prev){ + if(table->hash_prev->in_use) + table=NULL; + else + table=table->hash_prev; + }else{ + table=NULL; + } + } + + if (table) { /* Unlink the table from "unused_tables" list. */ @@ -2584,6 +2656,22 @@ table->prev->next=table->next; /* Remove from unused list */ table->next->prev=table->prev; table->in_use= thd; + if(table != table->hash_head){ + table->hash_prev->hash_next=table->hash_next; + table->hash_next->hash_prev=table->hash_prev; + + TABLE *head; + + head= table->hash_head; + + head->hash_next->hash_prev=table; + + table->hash_next=head->hash_next; + table->hash_prev=head; + table->hash_head=head; + + head->hash_next=table; + } } else { @@ -2656,7 +2744,21 @@ DBUG_RETURN(0); // VIEW } DBUG_PRINT("info", ("inserting table 0x%lx into the cache", (long) table)); + TABLE * find_table=(TABLE *)hash_search(&open_cache,(const uchar *)key,key_length); VOID(my_hash_insert(&open_cache,(uchar*) table)); + if(find_table){ + TABLE * head; + head= find_table->hash_head; + head->hash_next->hash_prev=table; + + table->hash_next=head->hash_next; + table->hash_prev=head; + table->hash_head=head; + + head->hash_next=table; + }else{ + table->hash_head = table->hash_next = table->hash_prev=table; + } } check_unused(); // Debugging call @@ -2787,6 +2889,10 @@ /* Replace table in open list */ tmp.next= table->next; tmp.prev= table->prev; + + tmp.hash_head = table->hash_head; + tmp.hash_next = table->hash_next; + tmp.hash_prev = table->hash_prev; delete table->triggers; if (table->file) ===== sql/table.h 1.181 vs edited ===== --- 1.181/sql/table.h 2007-12-21 15:15:40 +08:00 +++ edited/sql/table.h 2007-12-05 15:31:09 +08:00 @@ -455,6 +455,8 @@ #endif struct st_table *next, *prev; + struct st_table *hash_head, *hash_next, *hash_prev; /* Link to instances */ + THD *in_use; /* Which thread uses this */ Field **field; /* Pointer to fields */