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
|
||||
} ele_t;
|
||||
|
||||
|
||||
const unsigned hashN = 0xffff;
|
||||
|
||||
typedef struct bucket_str
|
||||
{
|
||||
ele_t* ele;
|
||||
struct bucket_str* link;
|
||||
} bucket_t;
|
||||
|
||||
typedef struct ui_str
|
||||
{
|
||||
unsigned eleAllocN; // size of eleA[]
|
||||
@ -108,11 +117,59 @@ namespace cw
|
||||
unsigned sentMsgN;
|
||||
unsigned recvMsgN;
|
||||
|
||||
bucket_t hashA[ hashN ];
|
||||
|
||||
} ui_t;
|
||||
|
||||
ui_t* _handleToPtr( handle_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 )
|
||||
{
|
||||
for(unsigned i=0; i<p->eleN; ++i)
|
||||
@ -306,12 +363,20 @@ namespace cw
|
||||
if( appId == kRootAppId )
|
||||
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)
|
||||
if( p->eleA[i] != nullptr
|
||||
&& p->eleA[i]->appId == appId
|
||||
&& ( parentUuId == kInvalidId || (p->eleA[i]->logical_parent!=nullptr && p->eleA[i]->logical_parent->uuId == parentUuId) )
|
||||
&& ( chanId == kInvalidId || p->eleA[i]->chanId == chanId ) )
|
||||
{
|
||||
|
||||
return p->eleA[i]->uuId;
|
||||
}
|
||||
|
||||
@ -549,6 +614,9 @@ namespace cw
|
||||
|
||||
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)
|
||||
if( p->eleA[i] == nullptr )
|
||||
return i;
|
||||
@ -634,6 +702,8 @@ namespace cw
|
||||
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));
|
||||
|
||||
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 )
|
||||
{
|
||||
_destroy_element( p->eleA[i] );
|
||||
|
||||
p->eleA[i] = nullptr;
|
||||
}
|
||||
|
||||
@ -2498,7 +2569,7 @@ cw::rc_t cw::ui::srv::create( handle_t& h,
|
||||
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.");
|
||||
goto errLabel;
|
||||
|
Loading…
Reference in New Issue
Block a user