reSIProcate/DialogUsageManager  9694
Public Member Functions | Private Types | Private Attributes
resip::InMemorySyncRegDb Class Reference

Implementation of a persistence manager. More...

#include <InMemorySyncRegDb.hxx>

Inheritance diagram for resip::InMemorySyncRegDb:
Inheritance graph
[legend]
Collaboration diagram for resip::InMemorySyncRegDb:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 InMemorySyncRegDb (unsigned int removeLingerSecs=0)
virtual ~InMemorySyncRegDb ()
virtual void setHandler (InMemorySyncRegDbHandler *handler)
virtual void initialSync (unsigned int connectionId)
virtual void addAor (const Uri &aor, const ContactList &contacts)
virtual void removeAor (const Uri &aor)
virtual bool aorIsRegistered (const Uri &aor)
virtual void lockRecord (const Uri &aor)
virtual void unlockRecord (const Uri &aor)
virtual update_status_t updateContact (const resip::Uri &aor, const ContactInstanceRecord &rec)
virtual void removeContact (const Uri &aor, const ContactInstanceRecord &rec)
virtual void getContacts (const Uri &aor, ContactList &container)
virtual void getContactsFull (const Uri &aor, ContactList &container)
virtual void getAors (UriList &container)
 return all the AOR in the DB

Private Types

typedef std::map< Uri,
ContactList * > 
database_map_t

Private Attributes

database_map_t mDatabase
Mutex mDatabaseMutex
std::set< UrimLockedRecords
Mutex mLockedRecordsMutex
Condition mRecordUnlocked
unsigned int mRemoveLingerSecs
InMemorySyncRegDbHandlermHandler

Detailed Description

Implementation of a persistence manager.

This class keeps all registrations in memory, and is used for remote replication.

Removed contact bindings are kept in memory with a RegExpires time of 0. This is required in order to properly syncronize removed contact bindings with a peer instance. Contacts are not deleted from memory until they have been removed for "removeLingerSecs". The removeLingerSecs parameter is passed into the contructor. If removeLingerSecs is set to 0, then contacts are removed from memory immediately and this class behaves very similar to the InMemoryRegistrationDatabase class.

The InMemorySyncRegDbHandler can be used by an external mechanism to transport registration bindings to a remote peer for replication. See the RegSyncClient and RegSyncServer implementations in the repro project.

Definition at line 41 of file InMemorySyncRegDb.hxx.


Member Typedef Documentation

typedef std::map<Uri,ContactList *> resip::InMemorySyncRegDb::database_map_t [private]

Definition at line 70 of file InMemorySyncRegDb.hxx.


Constructor & Destructor Documentation

InMemorySyncRegDb::InMemorySyncRegDb ( unsigned int  removeLingerSecs = 0)

Definition at line 56 of file InMemorySyncRegDb.cxx.

                                                                  : 
   mRemoveLingerSecs(removeLingerSecs),
   mHandler(0)
{
}
InMemorySyncRegDb::~InMemorySyncRegDb ( ) [virtual]

Definition at line 62 of file InMemorySyncRegDb.cxx.

References mDatabase.

{
   for( database_map_t::const_iterator it = mDatabase.begin();
        it != mDatabase.end(); it++)
   {
      delete it->second;
   }
   mDatabase.clear();
}

Member Function Documentation

void InMemorySyncRegDb::addAor ( const Uri aor,
const ContactList &  contacts 
) [virtual]

Implements resip::RegistrationPersistenceManager.

Definition at line 92 of file InMemorySyncRegDb.cxx.

References mDatabase, mDatabaseMutex, mHandler, and resip::InMemorySyncRegDbHandler::onAorModified().

{
   Lock g(mDatabaseMutex);
   database_map_t::iterator it = mDatabase.find(aor);
   if(it != mDatabase.end())
   {
       if(it->second)
       {
           *(it->second) = contacts;
       }
       else
       {
           it->second = new ContactList(contacts);
       }
   }
   else
   {
       mDatabase[aor] = new ContactList(contacts);
   }
   if(mHandler) mHandler->onAorModified(aor, contacts);
}

Here is the call graph for this function:

bool InMemorySyncRegDb::aorIsRegistered ( const Uri aor) [virtual]

Implements resip::RegistrationPersistenceManager.

Definition at line 164 of file InMemorySyncRegDb.cxx.

References resip::Timer::getTimeSecs(), mDatabase, mDatabaseMutex, and mRemoveLingerSecs.

{
   Lock g(mDatabaseMutex);
   database_map_t::iterator i = mDatabase.find(aor);
   if (i != mDatabase.end() && i->second == 0)
   {
      if(mRemoveLingerSecs > 0)
      {
         ContactList& contacts = *(i->second);
         UInt64 now = Timer::getTimeSecs();
         for(ContactList::iterator it = contacts.begin(); it != contacts.end(); it++)
         {
            if(it->mRegExpires > now)
            {
               return true;
            }
         }
      }
      else
      {
          return true;
      }
   }
   return false;
}

Here is the call graph for this function:

void InMemorySyncRegDb::getAors ( InMemorySyncRegDb::UriList container) [virtual]

return all the AOR in the DB

Implements resip::RegistrationPersistenceManager.

Definition at line 152 of file InMemorySyncRegDb.cxx.

References mDatabase, and mDatabaseMutex.

{
   container.clear();
   Lock g(mDatabaseMutex);
   for( database_map_t::const_iterator it = mDatabase.begin();
        it != mDatabase.end(); it++)
   {
      container.push_back(it->first);
   }
}
void InMemorySyncRegDb::getContacts ( const Uri aor,
ContactList &  container 
) [virtual]

Implements resip::RegistrationPersistenceManager.

Definition at line 328 of file InMemorySyncRegDb.cxx.

References contactsRemoveIfRequired(), resip::Timer::getTimeSecs(), mDatabase, mDatabaseMutex, and mRemoveLingerSecs.

{
   Lock g(mDatabaseMutex);
   database_map_t::iterator i = mDatabase.find(aor);
   if (i == mDatabase.end() || i->second == 0)
   {
      container.clear();
      return;
   }
   if(mRemoveLingerSecs > 0)
   {
      ContactList& contacts = *(i->second);
      UInt64 now = Timer::getTimeSecs();
      contactsRemoveIfRequired(contacts, now, mRemoveLingerSecs);
      container.clear();
      for(ContactList::iterator it = contacts.begin(); it != contacts.end(); it++)
      {
         if(it->mRegExpires > now)
         {
             container.push_back(*it);
         }
      }
   }
   else
   {
      container = *(i->second);
   }
}

Here is the call graph for this function:

void InMemorySyncRegDb::getContactsFull ( const Uri aor,
ContactList &  container 
) [virtual]

Definition at line 358 of file InMemorySyncRegDb.cxx.

References contactsRemoveIfRequired(), resip::Timer::getTimeSecs(), mDatabase, mDatabaseMutex, and mRemoveLingerSecs.

{
   Lock g(mDatabaseMutex);
   database_map_t::iterator i = mDatabase.find(aor);
   if (i == mDatabase.end() || i->second == 0)
   {
      container.clear();
      return;
   }
   ContactList& contacts = *(i->second);
   if(mRemoveLingerSecs > 0)
   {
      UInt64 now = Timer::getTimeSecs();
      contactsRemoveIfRequired(contacts, now, mRemoveLingerSecs);
   }
   container = contacts;
}

Here is the call graph for this function:

void InMemorySyncRegDb::initialSync ( unsigned int  connectionId) [virtual]

Definition at line 73 of file InMemorySyncRegDb.cxx.

References contactsRemoveIfRequired(), resip::Timer::getTimeSecs(), mDatabase, mDatabaseMutex, mHandler, mRemoveLingerSecs, and resip::InMemorySyncRegDbHandler::onInitialSyncAor().

{
   Lock g(mDatabaseMutex);
   UInt64 now = Timer::getTimeSecs();
   for(database_map_t::iterator it = mDatabase.begin(); it != mDatabase.end(); it++)
   {
      if(it->second)
      {
         ContactList& contacts = *(it->second);
         if(mRemoveLingerSecs > 0) 
         {
            contactsRemoveIfRequired(contacts, now, mRemoveLingerSecs);
         }
         if(mHandler) mHandler->onInitialSyncAor(connectionId, it->first, contacts);        
      }
   }
}

Here is the call graph for this function:

void InMemorySyncRegDb::lockRecord ( const Uri aor) [virtual]

Implements resip::RegistrationPersistenceManager.

Definition at line 191 of file InMemorySyncRegDb.cxx.

References DebugLog, mDatabase, mDatabaseMutex, mLockedRecords, mLockedRecordsMutex, mRecordUnlocked, resip::ThreadIf::selfId(), and resip::Condition::wait().

{
   Lock g2(mLockedRecordsMutex);

   DebugLog(<< "InMemorySyncRegDb::lockRecord:  aor=" << aor << " threadid=" << ThreadIf::selfId());

   {
      Lock g1(mDatabaseMutex);
      // This forces insertion if the record does not yet exist.
      mDatabase[aor];
   }

   while (mLockedRecords.count(aor))
   {
      mRecordUnlocked.wait(mLockedRecordsMutex);
   }

   mLockedRecords.insert(aor);
}

Here is the call graph for this function:

void InMemorySyncRegDb::removeAor ( const Uri aor) [virtual]

Implements resip::RegistrationPersistenceManager.

Definition at line 116 of file InMemorySyncRegDb.cxx.

References resip::Timer::getTimeSecs(), mDatabase, mDatabaseMutex, mHandler, mRemoveLingerSecs, and resip::InMemorySyncRegDbHandler::onAorModified().

Referenced by removeContact().

{
  database_map_t::iterator i;

  Lock g(mDatabaseMutex);
  i = mDatabase.find(aor);
  //DebugLog (<< "Removing registration bindings " << aor);
  if (i != mDatabase.end())
  {
     if (i->second)
     {
        if(mRemoveLingerSecs > 0)
        {
           ContactList& contacts = *(i->second);
           UInt64 now = Timer::getTimeSecs();
           for(ContactList::iterator it = contacts.begin(); it != contacts.end(); it++)
           {
              // Don't delete record - set expires to 0
              it->mRegExpires = 0;
              it->mLastUpdated = now;
           }
           if(mHandler) mHandler->onAorModified(aor, contacts);
        }
        else
        {
           delete i->second;
           // Setting this to 0 causes it to be removed when we unlock the AOR.
           i->second = 0;
           ContactList emptyList;
           if(mHandler) mHandler->onAorModified(aor, emptyList);
        }
     }
  }
}

Here is the call graph for this function:

void InMemorySyncRegDb::removeContact ( const Uri aor,
const ContactInstanceRecord rec 
) [virtual]

Implements resip::RegistrationPersistenceManager.

Definition at line 280 of file InMemorySyncRegDb.cxx.

References resip::Timer::getTimeSecs(), mDatabase, mDatabaseMutex, mHandler, mRemoveLingerSecs, resip::ContactInstanceRecord::mSyncContact, resip::InMemorySyncRegDbHandler::onAorModified(), and removeAor().

{
   ContactList *contactList = 0;

   {
      Lock g(mDatabaseMutex);

      database_map_t::iterator i;
      i = mDatabase.find(aor);
      if (i == mDatabase.end() || i->second == 0)
      {
         return;
      }
      contactList = i->second;
   }

   ContactList::iterator j;

   // See if the contact is present. We use URI matching rules here.
   for (j = contactList->begin(); j != contactList->end(); j++)
   {
      if (*j == rec)
      {
         if(mRemoveLingerSecs > 0)
         {
            j->mRegExpires = 0;
            j->mLastUpdated = Timer::getTimeSecs();
            if(mHandler && !rec.mSyncContact) mHandler->onAorModified(aor, *contactList);
         }
         else
         {
            contactList->erase(j);
            if (contactList->empty())
            {
               removeAor(aor);
            }
            else
            {
               if(mHandler && !rec.mSyncContact) mHandler->onAorModified(aor, *contactList);
            }
         }
         return;
      }
   }
}

Here is the call graph for this function:

virtual void resip::InMemorySyncRegDb::setHandler ( InMemorySyncRegDbHandler handler) [inline, virtual]

Definition at line 48 of file InMemorySyncRegDb.hxx.

References mHandler.

{ mHandler = handler; }
void InMemorySyncRegDb::unlockRecord ( const Uri aor) [virtual]

Implements resip::RegistrationPersistenceManager.

Definition at line 212 of file InMemorySyncRegDb.cxx.

References resip::Condition::broadcast(), DebugLog, mDatabase, mDatabaseMutex, mLockedRecords, mLockedRecordsMutex, mRecordUnlocked, and resip::ThreadIf::selfId().

{
   Lock g2(mLockedRecordsMutex);

   DebugLog(<< "InMemorySyncRegDb::unlockRecord:  aor=" << aor << " threadid=" << ThreadIf::selfId());

   {
      Lock g1(mDatabaseMutex);
      // If the pointer is null, we remove the record from the map.
      database_map_t::iterator i = mDatabase.find(aor);

      // The record must have been inserted when we locked it in the first place
      assert (i != mDatabase.end());

      if (i->second == 0)
      {
         mDatabase.erase(i);
      }
   }

   mLockedRecords.erase(aor);
   mRecordUnlocked.broadcast();
}

Here is the call graph for this function:

RegistrationPersistenceManager::update_status_t InMemorySyncRegDb::updateContact ( const resip::Uri aor,
const ContactInstanceRecord rec 
) [virtual]

Implements resip::RegistrationPersistenceManager.

Definition at line 237 of file InMemorySyncRegDb.cxx.

References resip::RegistrationPersistenceManager::CONTACT_CREATED, resip::RegistrationPersistenceManager::CONTACT_UPDATED, mDatabase, mDatabaseMutex, mHandler, resip::ContactInstanceRecord::mSyncContact, and resip::InMemorySyncRegDbHandler::onAorModified().

{
   ContactList *contactList = 0;

   {
      Lock g(mDatabaseMutex);

      database_map_t::iterator i;
      i = mDatabase.find(aor);
      if (i == mDatabase.end() || i->second == 0)
      {
         contactList = new ContactList();
         mDatabase[aor] = contactList;
      }
      else
      {
         contactList = i->second;
      }
   }
   
   assert(contactList);

   ContactList::iterator j;

   // See if the contact is already present. We use URI matching rules here.
   for (j = contactList->begin(); j != contactList->end(); j++)
   {
      if (*j == rec)
      {
         *j=rec;
         if(mHandler && !rec.mSyncContact) mHandler->onAorModified(aor, *contactList);
         return CONTACT_UPDATED;
      }
   }

   // This is a new contact, so we add it to the list.
   contactList->push_back(rec);
   if(mHandler && !rec.mSyncContact) mHandler->onAorModified(aor, *contactList);
   return CONTACT_CREATED;
}

Here is the call graph for this function:


Member Data Documentation

Definition at line 74 of file InMemorySyncRegDb.hxx.

Referenced by lockRecord(), and unlockRecord().

Definition at line 75 of file InMemorySyncRegDb.hxx.

Referenced by lockRecord(), and unlockRecord().

Definition at line 76 of file InMemorySyncRegDb.hxx.

Referenced by lockRecord(), and unlockRecord().


The documentation for this class was generated from the following files: