MT#62181 RegisterCache: refactor contact_idx

Provide a proper class for key matching/ordering instead of
hand-crafting a key to be used as index in several places. Use a simple
ordered map instead of the bucket-based approach.

Change-Id: I9e1918a48e103b655caac160c125a0393d261fca
mr13.4
Richard Fuchs 1 year ago
parent 11dd04891d
commit d068c60112

@ -139,29 +139,30 @@ void AliasHash::dump_elmt(const string& alias, AliasEntry* const& p_ae) const
p_ae ? p_ae->contact_uri.c_str() : "NULL");
}
string ContactBucket::getAlias(const string& contact_uri,
string ContactHash::getAlias(const string& contact_uri,
const string& remote_ip,
unsigned short remote_port)
{
string key = contact_uri + "/" + remote_ip + ":" + int2str(remote_port);
value_map::iterator it = find(key);
if(it == elmts.end())
auto it = find(ContactKey(contact_uri, remote_ip, remote_port));
if(it == end())
return string();
return *it->second;
}
void ContactBucket::remove(const string& contact_uri, const string& remote_ip,
void ContactHash::remove(const string& contact_uri, const string& remote_ip,
unsigned short remote_port)
{
string k = contact_uri + "/" + remote_ip + ":" + int2str(remote_port);
elmts.erase(k);
auto it = find(ContactKey(contact_uri, remote_ip, remote_port));
if (it != end()) {
delete it->second;
erase(it);
}
}
void ContactBucket::dump_elmt(const string& key, const string* alias) const
void ContactHash::dump_elmt(const ContactKey& key, string* const& alias) const
{
DBG("'%s' -> %s", key.c_str(), alias? alias->c_str() : "NULL");
DBG("'%s/%s:%u' -> %s", key.uri.c_str(), key.ip.c_str(), key.port, alias? alias->c_str() : "NULL");
}
struct RegCacheLogHandler
@ -186,8 +187,7 @@ struct RegCacheLogHandler
_RegisterCache::_RegisterCache()
: contact_idx(REG_CACHE_TABLE_ENTRIES),
shutdown_flag(false)
: shutdown_flag(false)
{
// debug register cache WRITE operations
setStorageHandler(new RegCacheLogHandler());
@ -278,11 +278,10 @@ _RegisterCache::compute_alias_hash(const string& aor, const string& contact_uri,
return int2hex(h1,true) + int2hex(h2,true);
}
void ContactBucket::insert(const string& contact_uri, const string& remote_ip,
void ContactHash::insert(const string& contact_uri, const string& remote_ip,
unsigned short remote_port, const string& alias)
{
string k = contact_uri + "/" + remote_ip + ":" + int2str(remote_port);
insert(k,new string(alias));
insert(make_pair(ContactKey(contact_uri, remote_ip, remote_port), new string(alias)));
}
bool _RegisterCache::getAlias(const string& canon_aor, const string& uri,
@ -308,14 +307,6 @@ bool _RegisterCache::getAlias(const string& canon_aor, const string& uri,
return alias_found;
}
ContactBucket* _RegisterCache::getContactBucket(const string& contact_uri,
const string& remote_ip,
unsigned short remote_port)
{
unsigned int h = hash_2str_1int(contact_uri,remote_ip,remote_port);
return contact_idx.get_bucket(h);
}
void _RegisterCache::setAliasUATimer(AliasEntry* alias_e)
{
if(!alias_e->ua_expire)
@ -387,12 +378,9 @@ void _RegisterCache::update(const string& alias, long int reg_expires,
// inc stats
active_regs++;
ContactBucket* ct_bucket = getContactBucket(uri,alias_update.source_ip,
alias_update.source_port);
ct_bucket->lock();
ct_bucket->insert(uri,alias_update.source_ip,
alias_update.source_port,alias);
ct_bucket->unlock();
lock_guard<AmMutex> _cl(contact_idx);
contact_idx.insert(uri, alias_update.source_ip,
alias_update.source_port, alias);
}
else {
DBG("updating existing binding: '%s' -> '%s'",
@ -467,16 +455,9 @@ void _RegisterCache::update(long int reg_expires, const AliasEntry& alias_update
if(findAliasEntry(alias,ae)) {
// change contact index
ContactBucket* ct_bucket =
getContactBucket(ae.contact_uri,ae.source_ip,ae.source_port);
ct_bucket->lock();
ct_bucket->remove(ae.contact_uri,ae.source_ip,ae.source_port);
ct_bucket->unlock();
ct_bucket = getContactBucket(uri,public_ip,alias_update.source_port);
ct_bucket->lock();
ct_bucket->insert(uri,public_ip,alias_update.source_port,alias);
ct_bucket->unlock();
lock_guard<AmMutex> _cl(contact_idx);
contact_idx.remove(ae.contact_uri, ae.source_ip, ae.source_port);
contact_idx.insert(uri, public_ip, alias_update.source_port, alias);
}
// relink binding with the new index
@ -510,12 +491,9 @@ void _RegisterCache::update(long int reg_expires, const AliasEntry& alias_update
DBG("inserted new binding: '%s' -> '%s'",
idx.c_str(), binding->alias.c_str());
ContactBucket* ct_bucket = getContactBucket(uri,alias_update.source_ip,
alias_update.source_port);
ct_bucket->lock();
ct_bucket->insert(uri,alias_update.source_ip,
alias_update.source_port,binding->alias);
ct_bucket->unlock();
lock_guard<AmMutex> _cl(contact_idx);
contact_idx.insert(uri, alias_update.source_ip,
alias_update.source_port, binding->alias);
}
else {
DBG("updating existing binding: '%s' -> '%s'",
@ -669,12 +647,10 @@ void _RegisterCache::removeAlias(const string& alias, bool generate_event)
SBCEventLog::instance()->logEvent(ae->alias,"reg-expired",ev);
}
ContactBucket* ct_bucket = getContactBucket(ae->contact_uri,
ae->source_ip,
ae->source_port);
ct_bucket->lock();
ct_bucket->remove(ae->contact_uri,ae->source_ip,ae->source_port);
ct_bucket->unlock();
{
lock_guard<AmMutex> _cl(contact_idx);
contact_idx.remove(ae->contact_uri, ae->source_ip, ae->source_port);
}
// dec stats
active_regs--;
@ -738,11 +714,11 @@ bool _RegisterCache::findAEByContact(const string& contact_uri,
{
bool res = false;
ContactBucket* ct_bucket = getContactBucket(contact_uri,remote_ip,
remote_port);
ct_bucket->lock();
string alias = ct_bucket->getAlias(contact_uri,remote_ip,remote_port);
ct_bucket->unlock();
string alias;
{
lock_guard<AmMutex> _cl(contact_idx);
alias = contact_idx.getAlias(contact_uri, remote_ip, remote_port);
}
if(alias.empty())
return false;

@ -89,36 +89,6 @@ struct RegCacheStorageHandler
virtual void onUpdate(const string& alias, long int ua_expires) {}
};
class ContactBucket
: public ht_map_bucket<string,string>
{
typedef ht_map_bucket<string,string> Bucket;
bool insert(const string& k, string* v) {
return Bucket::insert(k,v);
}
bool remove(const string& k) {
return Bucket::remove(k);
}
public:
ContactBucket(unsigned long int id)
: ht_map_bucket<string,string>(id)
{}
void insert(const string& contact_uri, const string& remote_ip,
unsigned short remote_port, const string& alias);
string getAlias(const string& contact_uri, const string& remote_ip,
unsigned short remote_port);
void remove(const string& contact_uri, const string& remote_ip,
unsigned short remote_port);
void dump_elmt(const string& key, const string* alias) const;
};
/**
* Registrar/Reg-Caching
* parsing/processing context
@ -191,12 +161,62 @@ public:
void dump_elmt(const string& aor, AorEntry* const& p_aor_entry) const;
};
class ContactKey
{
public:
string uri;
string ip;
unsigned short port;
ContactKey(string _uri, string _ip, unsigned short _port)
: uri(_uri),
ip(_ip),
port(_port)
{}
};
template<> struct std::hash<ContactKey> {
size_t operator()(const ContactKey& k) const {
return std::hash<string>{}(k.uri) ^ std::hash<string>{}(k.ip) ^ std::hash<unsigned int>{}(k.port);
}
};
template<> struct std::equal_to<ContactKey> {
size_t operator()(const ContactKey& a, const ContactKey& b) const {
return a.uri == b.uri
&& a.ip == b.ip
&& a.port == b.port;
}
};
class ContactHash
: public unordered_hash_map<ContactKey, string*>
{
public:
~ContactHash() {
for (auto it = begin(); it != end(); it++)
delete it->second;
}
using unordered_hash_map<ContactKey, string*>::insert;
void insert(const string& contact_uri, const string& remote_ip,
unsigned short remote_port, const string& alias);
string getAlias(const string& contact_uri, const string& remote_ip,
unsigned short remote_port);
void remove(const string& contact_uri, const string& remote_ip,
unsigned short remote_port);
void dump_elmt(const ContactKey& key, string* const& alias) const;
};
class _RegisterCache
: public AmThread
{
AorHash reg_cache_ht;
AliasHash id_idx;
hash_table<ContactBucket> contact_idx;
ContactHash contact_idx;
unique_ptr<RegCacheStorageHandler> storage_handler;
@ -226,13 +246,6 @@ protected:
sleep_cond.notify_all();
}
/**
* Returns the bucket associated with the contact-URI given
*/
ContactBucket* getContactBucket(const string& contact_uri,
const string& remote_ip,
unsigned short remote_port);
int parseAoR(RegisterCacheCtx& ctx, const AmSipRequest& req, msg_logger *logger);
int parseContacts(RegisterCacheCtx& ctx, const AmSipRequest& req, msg_logger *logger);
int parseExpires(RegisterCacheCtx& ctx, const AmSipRequest& req, msg_logger *logger);

Loading…
Cancel
Save