cwUi.cpp : Added use of a hash table to speed _findElementUuId()
and improved _find_and_available_element_slot() by first guessing at an available slot before resorting to a search.
This commit is contained in:
parent
14a6a9b2d1
commit
bf3317a4e7
73
cwUi.cpp
73
cwUi.cpp
@ -75,6 +75,15 @@ namespace cw
|
|||||||
bool destroyFl; // used by the deleteElement() algorithm
|
bool destroyFl; // used by the deleteElement() algorithm
|
||||||
} ele_t;
|
} ele_t;
|
||||||
|
|
||||||
|
|
||||||
|
const unsigned hashN = 0xffff;
|
||||||
|
|
||||||
|
typedef struct bucket_str
|
||||||
|
{
|
||||||
|
ele_t* ele;
|
||||||
|
struct bucket_str* link;
|
||||||
|
} bucket_t;
|
||||||
|
|
||||||
typedef struct ui_str
|
typedef struct ui_str
|
||||||
{
|
{
|
||||||
unsigned eleAllocN; // size of eleA[]
|
unsigned eleAllocN; // size of eleA[]
|
||||||
@ -108,11 +117,59 @@ namespace cw
|
|||||||
unsigned sentMsgN;
|
unsigned sentMsgN;
|
||||||
unsigned recvMsgN;
|
unsigned recvMsgN;
|
||||||
|
|
||||||
|
bucket_t hashA[ hashN ];
|
||||||
|
|
||||||
} ui_t;
|
} ui_t;
|
||||||
|
|
||||||
ui_t* _handleToPtr( handle_t h )
|
ui_t* _handleToPtr( handle_t h )
|
||||||
{ return handleToPtr<handle_t,ui_t>(h); }
|
{ return handleToPtr<handle_t,ui_t>(h); }
|
||||||
|
|
||||||
|
unsigned short _gen_hash_index( unsigned parentUuId, unsigned appId )
|
||||||
|
{
|
||||||
|
assert( parentUuId != kInvalidId && appId != kInvalidId );
|
||||||
|
unsigned hc = parentUuId + cwSwap32(appId);
|
||||||
|
|
||||||
|
return (unsigned short)(((hc & 0xffff0000)>>16) + (hc & 0x0000ffff));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void _store_ele_in_hash_table( ui_t* p, ele_t* e )
|
||||||
|
{
|
||||||
|
unsigned parentUuId = e->logical_parent == nullptr ? kInvalidIdx : e->logical_parent->uuId;
|
||||||
|
|
||||||
|
if( parentUuId == kInvalidId || e->appId == kInvalidId )
|
||||||
|
return;
|
||||||
|
|
||||||
|
unsigned short hash_idx = _gen_hash_index( parentUuId, e->appId );
|
||||||
|
|
||||||
|
if( p->hashA[ hash_idx ].ele == nullptr )
|
||||||
|
p->hashA[ hash_idx ].ele = e;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bucket_t* b = mem::allocZ<bucket_t>();
|
||||||
|
b->link = p->hashA[ hash_idx ].link;
|
||||||
|
b->ele = e;
|
||||||
|
p->hashA[hash_idx].link = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned _find_ele_in_hash_table( ui_t* p, unsigned parentUuId, unsigned appId, unsigned chanId )
|
||||||
|
{
|
||||||
|
if( parentUuId != kInvalidId && appId != kInvalidId )
|
||||||
|
{
|
||||||
|
unsigned hash_idx = _gen_hash_index(parentUuId,appId);
|
||||||
|
bucket_t* b = p->hashA + hash_idx;
|
||||||
|
|
||||||
|
for(; b!=nullptr; b=b->link)
|
||||||
|
if( b->ele->appId==appId && b->ele->logical_parent->uuId==parentUuId && (chanId==kInvalidId || b->ele->chanId==chanId) )
|
||||||
|
return b->ele->uuId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kInvalidId;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void _print_eles( ui_t* p )
|
void _print_eles( ui_t* p )
|
||||||
{
|
{
|
||||||
for(unsigned i=0; i<p->eleN; ++i)
|
for(unsigned i=0; i<p->eleN; ++i)
|
||||||
@ -306,12 +363,20 @@ namespace cw
|
|||||||
if( appId == kRootAppId )
|
if( appId == kRootAppId )
|
||||||
return kRootUuId;
|
return kRootUuId;
|
||||||
|
|
||||||
|
// try looking up the result in the hash table
|
||||||
|
unsigned uuid;
|
||||||
|
if((uuid = _find_ele_in_hash_table(p,parentUuId,appId,chanId)) != kInvalidId )
|
||||||
|
return uuid;
|
||||||
|
|
||||||
|
// if the result could not be found in the hash table (possibly because parentUuId is set to the wildcard i.e. kInvalidId)
|
||||||
|
// then do an exhaustive search
|
||||||
for(unsigned i=0; i<p->eleN; ++i)
|
for(unsigned i=0; i<p->eleN; ++i)
|
||||||
if( p->eleA[i] != nullptr
|
if( p->eleA[i] != nullptr
|
||||||
&& p->eleA[i]->appId == appId
|
&& p->eleA[i]->appId == appId
|
||||||
&& ( parentUuId == kInvalidId || (p->eleA[i]->logical_parent!=nullptr && p->eleA[i]->logical_parent->uuId == parentUuId) )
|
&& ( parentUuId == kInvalidId || (p->eleA[i]->logical_parent!=nullptr && p->eleA[i]->logical_parent->uuId == parentUuId) )
|
||||||
&& ( chanId == kInvalidId || p->eleA[i]->chanId == chanId ) )
|
&& ( chanId == kInvalidId || p->eleA[i]->chanId == chanId ) )
|
||||||
{
|
{
|
||||||
|
|
||||||
return p->eleA[i]->uuId;
|
return p->eleA[i]->uuId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -549,6 +614,9 @@ namespace cw
|
|||||||
|
|
||||||
unsigned _find_and_available_element_slot( ui_t* p )
|
unsigned _find_and_available_element_slot( ui_t* p )
|
||||||
{
|
{
|
||||||
|
if( p->eleN < p->eleAllocN && p->eleA[ p->eleN ] == nullptr )
|
||||||
|
return p->eleN;
|
||||||
|
|
||||||
for(unsigned i=0; i<p->eleN; ++i)
|
for(unsigned i=0; i<p->eleN; ++i)
|
||||||
if( p->eleA[i] == nullptr )
|
if( p->eleA[i] == nullptr )
|
||||||
return i;
|
return i;
|
||||||
@ -634,6 +702,8 @@ namespace cw
|
|||||||
e->appId = m->appId;
|
e->appId = m->appId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_store_ele_in_hash_table(p, e );
|
||||||
|
|
||||||
//printf("uuid:%i appId:%i par-uuid:%i %s\n", e->uuId,e->appId,e->parent==nullptr ? -1 : e->parent->uuId, cwStringNullGuard(e->eleName));
|
//printf("uuid:%i appId:%i par-uuid:%i %s\n", e->uuId,e->appId,e->parent==nullptr ? -1 : e->parent->uuId, cwStringNullGuard(e->eleName));
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
@ -2021,6 +2091,7 @@ cw::rc_t cw::ui::destroyElement( handle_t h, unsigned uuId )
|
|||||||
if( p->eleA[i] != nullptr && p->eleA[i]->destroyFl )
|
if( p->eleA[i] != nullptr && p->eleA[i]->destroyFl )
|
||||||
{
|
{
|
||||||
_destroy_element( p->eleA[i] );
|
_destroy_element( p->eleA[i] );
|
||||||
|
|
||||||
p->eleA[i] = nullptr;
|
p->eleA[i] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2498,7 +2569,7 @@ cw::rc_t cw::ui::srv::create( handle_t& h,
|
|||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((rc = thread::create( p->thH, _threadCallback, p )) != kOkRC )
|
if((rc = thread::create( p->thH, _threadCallback, p, "ui", thread::kDefaultStateTimeOutMicros, thread::kDefaultPauseMicros )) != kOkRC )
|
||||||
{
|
{
|
||||||
cwLogError(rc,"The websock UI server thread create failed.");
|
cwLogError(rc,"The websock UI server thread create failed.");
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
Loading…
Reference in New Issue
Block a user