Impl: Cache for contact manager. 09/62309/2
authorDenis Dolzhenko <d.dolzhenko@samsung.com>
Tue, 15 Mar 2016 09:51:55 +0000 (11:51 +0200)
committerDenis Dolzhenko <d.dolzhenko@samsung.com>
Tue, 15 Mar 2016 09:59:10 +0000 (11:59 +0200)
Change-Id: Id44b6736e67dcd85a2376681212b500a0e36c019
Signed-off-by: Denis Dolzhenko <d.dolzhenko@samsung.com>
src/Common/ContactManager/inc/ContactManager.h
src/Common/ContactManager/src/ContactManager.cpp
test/TC/TestContactManager.cpp

index e56f7e9..9e2299b 100644 (file)
@@ -22,6 +22,7 @@
 #include <vector>
 #include <contacts.h>
 #include <memory>
+#include <unordered_map>
 
 #include "ContactList.h"
 #include "ContactPersonPhoneLog.h"
@@ -62,44 +63,31 @@ namespace Msg
             std::shared_ptr<ContactList<T>> search(const std::string &keyword);
 
             /**
-             *@brief        Search by phone number ContactPersonNumber record
-             *@param[in]    number - phone number
-             *@return       Reference to ContactPersonNumber
-             */
-            ContactPersonNumberRef getContactPersonNumber(const std::string &number) const;
-
-            /**
-             *@brief        Search by email address ContactPersonEmail record
-             *@param[in]    email - email address
-             *@return       Reference to ContactPersonEmail
-             */
-            ContactPersonEmailRef getContactPersonEmail(const std::string &email) const;
-
-            /**
              *@brief        Search by email and phone and return ContactPersonAddress record
              *@param[in]    address - email or number
              *@return       Reference to ContactPersonAddress
              */
-            ContactPersonAddressRef getContactPersonAddress(const std::string &address) const;
+            ContactPersonAddressRef getContactPersonAddress(const std::string &address);
 
             /**
              *@brief        Search for contacts-id, name, phone-number and thumbnail path based on phone-number id
              *@param[in]    phoneId - identifier of phone-number in contacts-database
              *@return       Reference to ContactPersonNumber
              */
-            ContactPersonNumberRef getContactPersonNumber(int phoneId) const;
+            ContactPersonNumberRef getContactPersonNumber(int phoneId);
 
             /**
              *@brief        Return owner's ContactPersonAddress record
              *@return       Reference to ContactPersonAddress
              */
-            ContactOwnerProfileRef getOwnerProfile() const;
+            ContactOwnerProfileRef getOwnerProfile();
 
             /**
              *@brief        Add listener on contacts database
              *@param[in]    listener
              */
             void addListener(IContactManagerListener &listener);
+
             /**
              *@brief        Remove listener
              *@param[in]    listener - listener to be remove
@@ -107,6 +95,9 @@ namespace Msg
             void removeListener(IContactManagerListener &listener);
 
         private:
+            typedef std::unordered_map<std::string, ContactPersonAddressRef> AddressMap;
+
+        private:
             /**
              *@brief        A callback passed to contacts_db_add_changed_cb() to get notifications
                             about contacts modifications from contact service
@@ -120,11 +111,30 @@ namespace Msg
              * @brief Generic search for basic contact attributes based on custom filter passed from above
              * @param[in] filter to be used for db-request. DO NOT destroy filter manually, it will be destroyed insithe this method.
              */
-            ContactPersonNumberRef getContactPersonNumber(contacts_filter_h filter) const;
-            ContactPersonEmailRef getContactPersonEmail(contacts_filter_h filter) const;
+            ContactPersonNumberRef getContactPersonNumber(contacts_filter_h filter);
+            ContactPersonEmailRef getContactPersonEmail(contacts_filter_h filter);
+
+            /**
+             *@brief        Search by phone number ContactPersonNumber record
+             *@param[in]    number - phone number
+             *@return       Reference to ContactPersonNumber
+             */
+            ContactPersonNumberRef getContactPersonNumber(const std::string &number);
+
+            /**
+             *@brief        Search by email address ContactPersonEmail record
+             *@param[in]    email - email address
+             *@return       Reference to ContactPersonEmail
+             */
+            ContactPersonEmailRef getContactPersonEmail(const std::string &email);
+
+            void invalidateCache();
+            ContactPersonAddressRef getAddress(const std::string &address);
 
         private:
             std::list<IContactManagerListener *> m_Listeners;
+            AddressMap m_AddressMap;
+            ContactOwnerProfileRef m_OwnerProfile;
     };
 
     class IContactManagerListener
index e56d302..6c94439 100644 (file)
 
  namespace Msg
  {
+    const int mapReservSize = 512;
+
     ContactManager::ContactManager()
     {
         MSG_LOG("");
+        m_AddressMap.reserve(mapReservSize);
         int error = contacts_connect();
         if(error != 0)
         {
         return list ? std::make_shared<ContactList<ContactPersonEmail>>(list) : nullptr;
     }
 
-    ContactPersonNumberRef ContactManager::getContactPersonNumber(int phoneNumId) const
+    ContactPersonNumberRef ContactManager::getContactPersonNumber(int phoneNumId)
     {
+        // TODO: impl cache policy if needed
         contacts_filter_h filter = nullptr;
         contacts_filter_create(_contacts_contact_number._uri, &filter);
         contacts_filter_add_int(filter, _contacts_person_number.number_id, CONTACTS_MATCH_EQUAL, phoneNumId);
         return filter ? getContactPersonNumber(filter) : nullptr;
     }
 
-    ContactPersonNumberRef ContactManager::getContactPersonNumber(const std::string &number) const
+    ContactPersonNumberRef ContactManager::getContactPersonNumber(const std::string &number)
     {
         contacts_filter_h filter = nullptr;
         contacts_filter_create(_contacts_contact_number._uri, &filter);
         return filter ? getContactPersonNumber(filter) : nullptr;
     }
 
-    ContactPersonEmailRef ContactManager::getContactPersonEmail(const std::string &email) const
+    ContactPersonEmailRef ContactManager::getContactPersonEmail(const std::string &email)
     {
         contacts_filter_h filter = nullptr;
         contacts_filter_create(_contacts_contact_email._uri, &filter);
         return filter ? getContactPersonEmail(filter) : nullptr;
     }
 
-    ContactPersonAddressRef ContactManager::getContactPersonAddress(const std::string &address) const
+    ContactPersonAddressRef ContactManager::getContactPersonAddress(const std::string &address)
     {
-        if(MsgUtils::isValidNumber(address))
-            return getContactPersonNumber(address);
-
-        return getContactPersonEmail(address);
+        return getAddress(address);
     }
 
-    ContactOwnerProfileRef ContactManager::getOwnerProfile() const
+    ContactOwnerProfileRef ContactManager::getOwnerProfile()
     {
-        contacts_list_h list = nullptr;
-        contacts_record_h myProfile = nullptr;
-        contacts_db_get_all_records(_contacts_my_profile._uri, 0, 1, &list);
-        if(list)
+        if(!m_OwnerProfile)
         {
-            contacts_list_get_current_record_p(list, &myProfile);
-            contacts_list_destroy(list, false);
+            contacts_list_h list = nullptr;
+            contacts_record_h myProfile = nullptr;
+            contacts_db_get_all_records(_contacts_my_profile._uri, 0, 1, &list);
+            if(list)
+            {
+                contacts_list_get_current_record_p(list, &myProfile);
+                contacts_list_destroy(list, false);
+            }
+            if(myProfile)
+                m_OwnerProfile.reset(new ContactOwnerProfile(true, myProfile));
         }
-        return myProfile ? std::make_shared<ContactOwnerProfile>(true, myProfile) : nullptr;
+        return m_OwnerProfile;
     }
 
     void ContactManager::contactChangedCb(const char *view_uri, void *user_data)
     {
         ContactManager *self = static_cast<ContactManager *>(user_data);
+        self->invalidateCache();
         for(auto listener : self->m_Listeners)
         {
             listener->onContactChanged();
     void ContactManager::contactDisplayOrderChangedCb(contacts_name_display_order_e name_display_order, void *user_data)
     {
         ContactManager *self = static_cast<ContactManager *>(user_data);
+        self->invalidateCache();
         for(auto listener : self->m_Listeners)
         {
             listener->onContactChanged();
         }
     }
 
-    ContactPersonNumberRef ContactManager::getContactPersonNumber(contacts_filter_h filter) const
+    ContactPersonNumberRef ContactManager::getContactPersonNumber(contacts_filter_h filter)
     {
         contacts_query_h query = nullptr;
         contacts_list_h list = nullptr;
         return cResValue ? std::make_shared<ContactPersonNumber>(true, cResValue) : nullptr;
     }
 
-    ContactPersonEmailRef ContactManager::getContactPersonEmail(contacts_filter_h filter) const
+    ContactPersonEmailRef ContactManager::getContactPersonEmail(contacts_filter_h filter)
     {
         contacts_query_h query = nullptr;
         contacts_list_h list = nullptr;
         contacts_list_destroy(list, false);
         return cResValue ? std::make_shared<ContactPersonEmail>(true, cResValue) : nullptr;
     }
+
+    ContactPersonAddressRef ContactManager::getAddress(const std::string &address)
+    {
+        auto it = m_AddressMap.find(address);
+        if(m_AddressMap.end() == it)
+        {
+            ContactPersonAddressRef personAddress = MsgUtils::isValidNumber(address) ?
+                    std::static_pointer_cast<ContactPersonAddress>(getContactPersonNumber(address)):
+                    std::static_pointer_cast<ContactPersonAddress>(getContactPersonEmail(address));
+            m_AddressMap[address] = personAddress;
+
+            return personAddress;
+        }
+        return it->second;
+    }
+
+    void ContactManager::invalidateCache()
+    {
+        m_AddressMap.clear();
+        m_OwnerProfile.reset();
+    }
 }
 
index dd320c7..1d88437 100644 (file)
@@ -51,7 +51,7 @@ TEST_F( TestContactManager, FindNameSasha )
     const std::string strName = "Sasha";
 
     m_ContactId = Msg::Test::ContactUtils::getInst().createContact(strName, strNumber);
-    ContactPersonNumberRef item = m_ContactManager.getContactPersonNumber(strNumber);
+    auto item = m_ContactManager.getContactPersonAddress(strNumber);
     std::string result = item->getDispName();
 
     testing::Test::RecordProperty("Number", strNumber.c_str());
@@ -69,7 +69,7 @@ TEST_F( TestContactManager, FindNameVova )
 
     m_ContactId = Msg::Test::ContactUtils::getInst().createContact(strName, strNumber);
 
-    ContactPersonNumberRef item = m_ContactManager.getContactPersonNumber(strNumber);
+    auto item = m_ContactManager.getContactPersonAddress(strNumber);
     std::string result = item->getDispName();
 
     testing::Test::RecordProperty("Number", strNumber.c_str());
@@ -87,7 +87,7 @@ TEST_F( TestContactManager, TestGetNameById )
 
     m_ContactId = Msg::Test::ContactUtils::getInst().createContact(strName, strNumber);
 
-    ContactPersonNumberRef item = m_ContactManager.getContactPersonNumber(strNumber);
+    auto item = m_ContactManager.getContactPersonAddress(strNumber);
     std::string result1 = item->getDispName();
 
     std::string result2 = Msg::Test::ContactUtils::getInst().getNameById(m_ContactId);