mirror of
https://github.com/MariaDB/server.git
synced 2025-08-11 09:43:05 +03:00
Replaced lf-hash element_size hack with initializer function.
This commit is contained in:
@@ -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
|
is expensive to initialize - for example if there is a mutex or
|
||||||
DYNAMIC_ARRAY. In this case they should be initialize in the
|
DYNAMIC_ARRAY. In this case they should be initialize in the
|
||||||
LF_ALLOCATOR::constructor, and lf_hash_insert should not overwrite them.
|
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
|
The above works well with PODS. For more complex cases (e.g. C++ classes
|
||||||
with private members) use initializer function.
|
with private members) use initializer function.
|
||||||
|
@@ -253,11 +253,7 @@ struct st_wt_resource {
|
|||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
mysql_mutex_t *cond_mutex; /* a mutex for the 'cond' below */
|
mysql_mutex_t *cond_mutex; /* a mutex for the 'cond' below */
|
||||||
#endif
|
#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
|
#ifdef WT_RWLOCKS_USE_MUTEXES
|
||||||
/*
|
/*
|
||||||
we need a special rwlock-like 'lock' to allow readers bypass
|
we need a special rwlock-like 'lock' to allow readers bypass
|
||||||
@@ -389,10 +385,10 @@ static LF_HASH reshash;
|
|||||||
It's called from lf_hash and takes a pointer to an LF_SLIST instance.
|
It's called from lf_hash and takes a pointer to an LF_SLIST instance.
|
||||||
WT_RESOURCE is located at arg+sizeof(LF_SLIST)
|
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);
|
WT_RESOURCE *rc= (WT_RESOURCE*)(arg+LF_HASH_OVERHEAD);
|
||||||
DBUG_ENTER("wt_resource_init");
|
DBUG_ENTER("wt_resource_create");
|
||||||
|
|
||||||
bzero(rc, sizeof(*rc));
|
bzero(rc, sizeof(*rc));
|
||||||
rc_rwlock_init(rc);
|
rc_rwlock_init(rc);
|
||||||
@@ -419,25 +415,37 @@ static void wt_resource_destroy(uchar *arg)
|
|||||||
DBUG_VOID_RETURN;
|
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;
|
static int wt_init_done;
|
||||||
|
|
||||||
void wt_init()
|
void wt_init()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("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,
|
lf_hash_init(&reshash, sizeof(WT_RESOURCE), LF_HASH_UNIQUE, 0,
|
||||||
sizeof_WT_RESOURCE_ID, 0, 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;
|
reshash.alloc.destructor= wt_resource_destroy;
|
||||||
/*
|
reshash.initializer= (lf_hash_initializer) wt_resource_init;
|
||||||
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);
|
|
||||||
bzero(wt_wait_stats, sizeof(wt_wait_stats));
|
bzero(wt_wait_stats, sizeof(wt_wait_stats));
|
||||||
bzero(wt_cycle_stats, sizeof(wt_cycle_stats));
|
bzero(wt_cycle_stats, sizeof(wt_cycle_stats));
|
||||||
wt_success_stats= 0;
|
wt_success_stats= 0;
|
||||||
@@ -930,14 +938,9 @@ int wt_thd_will_wait_for(WT_THD *thd, WT_THD *blocker,
|
|||||||
retry:
|
retry:
|
||||||
while ((rc= lf_hash_search(&reshash, thd->pins, key, keylen)) == 0)
|
while ((rc= lf_hash_search(&reshash, thd->pins, key, keylen)) == 0)
|
||||||
{
|
{
|
||||||
WT_RESOURCE tmp;
|
|
||||||
|
|
||||||
DBUG_PRINT("wt", ("failed to find rc in hash, inserting"));
|
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);
|
DBUG_RETURN(WT_DEADLOCK);
|
||||||
/*
|
/*
|
||||||
Two cases: either lf_hash_insert() failed - because another thread
|
Two cases: either lf_hash_insert() failed - because another thread
|
||||||
|
@@ -432,7 +432,7 @@ void tdc_init(void)
|
|||||||
&my_charset_bin);
|
&my_charset_bin);
|
||||||
tdc_hash.alloc.constructor= TDC_element::lf_alloc_constructor;
|
tdc_hash.alloc.constructor= TDC_element::lf_alloc_constructor;
|
||||||
tdc_hash.alloc.destructor= TDC_element::lf_alloc_destructor;
|
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;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -616,7 +616,7 @@ retry:
|
|||||||
while (!(element= (TDC_element*) lf_hash_search_using_hash_value(&tdc_hash,
|
while (!(element= (TDC_element*) lf_hash_search_using_hash_value(&tdc_hash,
|
||||||
thd->tdc_hash_pins, hash_value, (uchar*) key, key_length)))
|
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);
|
int res= lf_hash_insert(&tdc_hash, thd->tdc_hash_pins, (uchar*) &tmp);
|
||||||
|
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
@@ -628,7 +628,6 @@ retry:
|
|||||||
thd->tdc_hash_pins, hash_value, (uchar*) key, key_length);
|
thd->tdc_hash_pins, hash_value, (uchar*) key, key_length);
|
||||||
lf_hash_search_unpin(thd->tdc_hash_pins);
|
lf_hash_search_unpin(thd->tdc_hash_pins);
|
||||||
DBUG_ASSERT(element);
|
DBUG_ASSERT(element);
|
||||||
element->assert_clean_share();
|
|
||||||
|
|
||||||
if (!(share= alloc_table_share(db, table_name, key, key_length)))
|
if (!(share= alloc_table_share(db, table_name, key, key_length)))
|
||||||
{
|
{
|
||||||
|
@@ -166,6 +166,15 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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,
|
static uchar *key(const TDC_element *element, size_t *length,
|
||||||
my_bool not_used __attribute__((unused)))
|
my_bool not_used __attribute__((unused)))
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user