[Commits] 170e04c: Replaced lf-hash element_size hack with initializer function.

svoj at mariadb.org svoj at mariadb.org
Wed Mar 4 09:02:43 EET 2015


revision-id: 170e04c7a848f5d76259d47e74ac46eaf24fdf27
parent(s): 49fd22219ff462f34a524bf66fbf9e1cc1f9b3b2
committer: Sergey Vojtovich
branch nick: 10.1
timestamp: 2015-03-04 11:01:32 +0400
message:

Replaced lf-hash element_size hack with initializer function.

---
 mysys/lf_hash.c         |  1 -
 mysys/waiting_threads.c | 49 ++++++++++++++++++++++++++-----------------------
 sql/table_cache.cc      |  5 ++---
 sql/table_cache.h       |  9 +++++++++
 4 files changed, 37 insertions(+), 27 deletions(-)

diff --git a/mysys/lf_hash.c b/mysys/lf_hash.c
index db84d1f..7bced68 100644
--- a/mysys/lf_hash.c
+++ b/mysys/lf_hash.c
@@ -336,7 +336,6 @@ static void default_initializer(LF_HASH *hash, void *dst, const void *src)
   is expensive to initialize - for example if there is a mutex or
   DYNAMIC_ARRAY. In this case they should be initialize in the
   LF_ALLOCATOR::constructor, and lf_hash_insert should not overwrite them.
-  See wt_init() for example.
 
   The above works well with PODS. For more complex cases (e.g. C++ classes
   with private members) use initializer function.
diff --git a/mysys/waiting_threads.c b/mysys/waiting_threads.c
index 23b4026..ae0ffe7 100644
--- a/mysys/waiting_threads.c
+++ b/mysys/waiting_threads.c
@@ -253,11 +253,7 @@ struct st_wt_resource {
 #ifndef DBUG_OFF
   mysql_mutex_t  *cond_mutex; /* a mutex for the 'cond' below */
 #endif
-  /*
-    before the 'lock' all elements are mutable, after (and including) -
-    immutable in the sense that lf_hash_insert() won't memcpy() over them.
-    See wt_init().
-  */
+
 #ifdef WT_RWLOCKS_USE_MUTEXES
   /*
     we need a special rwlock-like 'lock' to allow readers bypass
@@ -389,10 +385,10 @@ static void rc_unlock(WT_RESOURCE *rc)
   It's called from lf_hash and takes a pointer to an LF_SLIST instance.
   WT_RESOURCE is located at arg+sizeof(LF_SLIST)
 */
-static void wt_resource_init(uchar *arg)
+static void wt_resource_create(uchar *arg)
 {
   WT_RESOURCE *rc= (WT_RESOURCE*)(arg+LF_HASH_OVERHEAD);
-  DBUG_ENTER("wt_resource_init");
+  DBUG_ENTER("wt_resource_create");
 
   bzero(rc, sizeof(*rc));
   rc_rwlock_init(rc);
@@ -419,25 +415,37 @@ static void wt_resource_destroy(uchar *arg)
   DBUG_VOID_RETURN;
 }
 
+/**
+  WT_RESOURCE initializer
+
+  It's called from lf_hash when an element is inserted.
+*/
+static void wt_resource_init(LF_HASH *hash __attribute__((unused)),
+                             WT_RESOURCE *rc, WT_RESOURCE_ID *id)
+{
+  DBUG_ENTER("wt_resource_init");
+  rc->id= *id;
+  rc->waiter_count= 0;
+  rc->state= ACTIVE;
+#ifndef DBUG_OFF
+  rc->cond_mutex= 0;
+#endif
+  DBUG_VOID_RETURN;
+}
+
 static int wt_init_done;
 
 void wt_init()
 {
   DBUG_ENTER("wt_init");
-  DBUG_ASSERT(reshash.alloc.constructor != wt_resource_init);
+  DBUG_ASSERT(reshash.alloc.constructor != wt_resource_create);
 
   lf_hash_init(&reshash, sizeof(WT_RESOURCE), LF_HASH_UNIQUE, 0,
                sizeof_WT_RESOURCE_ID, 0, 0);
-  reshash.alloc.constructor= wt_resource_init;
+  reshash.alloc.constructor= wt_resource_create;
   reshash.alloc.destructor= wt_resource_destroy;
-  /*
-    Note a trick: we initialize the hash with the real element size,
-    but fix it later to a shortened element size. This way
-    the allocator will allocate elements correctly, but
-    lf_hash_insert() will only overwrite part of the element with memcpy().
-    lock, condition, and dynamic array will be intact.
-  */
-  reshash.element_size= offsetof(WT_RESOURCE, lock);
+  reshash.initializer= (lf_hash_initializer) wt_resource_init;
+
   bzero(wt_wait_stats, sizeof(wt_wait_stats));
   bzero(wt_cycle_stats, sizeof(wt_cycle_stats));
   wt_success_stats= 0;
@@ -930,14 +938,9 @@ int wt_thd_will_wait_for(WT_THD *thd, WT_THD *blocker,
 retry:
     while ((rc= lf_hash_search(&reshash, thd->pins, key, keylen)) == 0)
     {
-      WT_RESOURCE tmp;
-
       DBUG_PRINT("wt", ("failed to find rc in hash, inserting"));
-      bzero(&tmp, sizeof(tmp));
-      tmp.id= *resid;
-      tmp.state= ACTIVE;
 
-      if (lf_hash_insert(&reshash, thd->pins, &tmp) == -1) /* if OOM */
+      if (lf_hash_insert(&reshash, thd->pins, resid) == -1) /* if OOM */
         DBUG_RETURN(WT_DEADLOCK);
       /*
         Two cases: either lf_hash_insert() failed - because another thread
diff --git a/sql/table_cache.cc b/sql/table_cache.cc
index 9a75caf..2dd368a 100644
--- a/sql/table_cache.cc
+++ b/sql/table_cache.cc
@@ -432,7 +432,7 @@ void tdc_init(void)
                &my_charset_bin);
   tdc_hash.alloc.constructor= TDC_element::lf_alloc_constructor;
   tdc_hash.alloc.destructor= TDC_element::lf_alloc_destructor;
-  tdc_hash.element_size= offsetof(TDC_element, version);
+  tdc_hash.initializer= (lf_hash_initializer) TDC_element::lf_hash_initializer;
   DBUG_VOID_RETURN;
 }
 
@@ -616,7 +616,7 @@ TABLE_SHARE *tdc_acquire_share(THD *thd, const char *db, const char *table_name,
   while (!(element= (TDC_element*) lf_hash_search_using_hash_value(&tdc_hash,
                     thd->tdc_hash_pins, hash_value, (uchar*) key, key_length)))
   {
-    TDC_element tmp(key, key_length);
+    LEX_STRING tmp= { const_cast<char*>(key), key_length };
     int res= lf_hash_insert(&tdc_hash, thd->tdc_hash_pins, (uchar*) &tmp);
 
     if (res == -1)
@@ -628,7 +628,6 @@ TABLE_SHARE *tdc_acquire_share(THD *thd, const char *db, const char *table_name,
              thd->tdc_hash_pins, hash_value, (uchar*) key, key_length);
     lf_hash_search_unpin(thd->tdc_hash_pins);
     DBUG_ASSERT(element);
-    element->assert_clean_share();
 
     if (!(share= alloc_table_share(db, table_name, key, key_length)))
     {
diff --git a/sql/table_cache.h b/sql/table_cache.h
index b829e4d..2d70e4c 100644
--- a/sql/table_cache.h
+++ b/sql/table_cache.h
@@ -166,6 +166,15 @@ class TDC_element
   }
 
 
+  static void lf_hash_initializer(LF_HASH *hash __attribute__((unused)),
+                                  TDC_element *element, LEX_STRING *key)
+  {
+    memcpy(element->m_key, key->str, key->length);
+    element->m_key_length= key->length;
+    element->assert_clean_share();
+  }
+
+
   static uchar *key(const TDC_element *element, size_t *length,
                     my_bool not_used __attribute__((unused)))
   {


More information about the commits mailing list