From 926a719ab7c2ae9e8205a396540eb429bf2637ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20P=C3=B6sel?= Date: Mon, 17 Nov 2014 15:21:12 +0000 Subject: Facebook: Speed optimalization Use caching for ContactIDToHContact, ChatIDToHContact and ThreadIDToContactID methods. Should result in some performance increase. git-svn-id: http://svn.miranda-ng.org/main/trunk@11003 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/FacebookRM/src/client.h | 5 +++ protocols/FacebookRM/src/connection.cpp | 7 ++++ protocols/FacebookRM/src/contacts.cpp | 69 +++++++++++++++++++++++++++++---- 3 files changed, 74 insertions(+), 7 deletions(-) (limited to 'protocols') diff --git a/protocols/FacebookRM/src/client.h b/protocols/FacebookRM/src/client.h index 14b2731232..902477e573 100644 --- a/protocols/FacebookRM/src/client.h +++ b/protocols/FacebookRM/src/client.h @@ -102,6 +102,11 @@ public: std::map chat_rooms; std::map notifications; + // Contact/thread id caches + std::map thread_id_to_user_id; + std::map chat_id_to_hcontact; + std::map user_id_to_hcontact; + std::string get_newsfeed_type(); std::string get_server_type(); std::string get_privacy_type(); diff --git a/protocols/FacebookRM/src/connection.cpp b/protocols/FacebookRM/src/connection.cpp index 3372d671d2..1582056033 100644 --- a/protocols/FacebookRM/src/connection.cpp +++ b/protocols/FacebookRM/src/connection.cpp @@ -63,6 +63,13 @@ void FacebookProto::ChangeStatus(void*) facy.pages.clear(); facy.typers.clear(); + // Clear thread/user id caches? + /* Right now it's commented out because it's not really needed to erase - maybe only when user changes login/pass in same account, but even then it shouldn't cause problems + facy.thread_id_to_user_id.clear(); + facy.chat_id_to_hcontact.clear(); + facy.user_id_to_hcontact.clear(); + */ + // Close connection handle if (facy.hFcbCon) Netlib_CloseHandle(facy.hFcbCon); diff --git a/protocols/FacebookRM/src/contacts.cpp b/protocols/FacebookRM/src/contacts.cpp index 02c059fc88..2e99856a7f 100644 --- a/protocols/FacebookRM/src/contacts.cpp +++ b/protocols/FacebookRM/src/contacts.cpp @@ -77,15 +77,26 @@ bool FacebookProto::IsMyContact(MCONTACT hContact, bool include_chat) MCONTACT FacebookProto::ChatIDToHContact(std::tstring chat_id) { - // TODO: use some cache to optimize this + // First check cache + std::map::iterator it = facy.chat_id_to_hcontact.find(chat_id); + if (it != facy.chat_id_to_hcontact.end()) { + // Check if contact is still valid + if (CallService(MS_DB_CONTACT_IS, (WPARAM)it->second, 0) == 1) + return it->second; + else + facy.chat_id_to_hcontact.erase(it); + } + // Go through all local contacts for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { if (!IsMyContact(hContact, true)) continue; ptrT id(getTStringA(hContact, "ChatRoomID")); - if (id && !_tcscmp(id, chat_id.c_str())) + if (id && !_tcscmp(id, chat_id.c_str())) { + facy.chat_id_to_hcontact.insert(std::make_pair(chat_id, hContact)); return hContact; + } } return 0; @@ -93,15 +104,26 @@ MCONTACT FacebookProto::ChatIDToHContact(std::tstring chat_id) MCONTACT FacebookProto::ContactIDToHContact(std::string user_id) { - // TODO: use some cache to optimize this + // First check cache + std::map::iterator it = facy.user_id_to_hcontact.find(user_id); + if (it != facy.user_id_to_hcontact.end()) { + // Check if contact is still valid + if (CallService(MS_DB_CONTACT_IS, (WPARAM)it->second, 0) == 1) + return it->second; + else + facy.user_id_to_hcontact.erase(it); + } + // Go through all local contacts for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { if (isChatRoom(hContact)) continue; ptrA id(getStringA(hContact, FACEBOOK_KEY_ID)); - if (id && !strcmp(id, user_id.c_str())) + if (id && !strcmp(id, user_id.c_str())) { + facy.user_id_to_hcontact.insert(std::make_pair(user_id, hContact)); return hContact; + } } return 0; @@ -109,6 +131,13 @@ MCONTACT FacebookProto::ContactIDToHContact(std::string user_id) std::string FacebookProto::ThreadIDToContactID(std::string thread_id) { + // First check cache + std::map::iterator it = facy.thread_id_to_user_id.find(thread_id); + if (it != facy.thread_id_to_user_id.end()) { + return it->second; + } + + // Go through all local contacts for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { if (!IsMyContact(hContact)) continue; @@ -116,7 +145,12 @@ std::string FacebookProto::ThreadIDToContactID(std::string thread_id) ptrA tid(getStringA(hContact, FACEBOOK_KEY_TID)); if (tid && !strcmp(tid, thread_id.c_str())) { ptrA id(getStringA(hContact, FACEBOOK_KEY_ID)); - return (id ? id : ""); + std::string user_id = (id ? id : ""); + if (!user_id.empty()) { + facy.thread_id_to_user_id.insert(std::make_pair(thread_id, user_id)); + return user_id; + } + break; // this shouldn't happen unless user manually deletes ID from FB contact in DB } } @@ -130,7 +164,7 @@ std::string FacebookProto::ThreadIDToContactID(std::string thread_id) data += "&__a=1&__dyn=&__req=&ttstamp=0"; data += "&threads[thread_ids][0]=" + utils::url::encode(thread_id); - std::string user_id; + std::string user_id = ""; http::response resp = facy.flap(REQUEST_THREAD_INFO, &data); if (resp.code == HTTP_CODE_OK) { @@ -140,6 +174,9 @@ std::string FacebookProto::ThreadIDToContactID(std::string thread_id) p->parse_thread_info(&resp.data, &user_id); delete p; + if (!user_id.empty()) + facy.thread_id_to_user_id.insert(std::make_pair(thread_id, user_id)); + debugLogA("***** Thread info processed"); CODE_BLOCK_CATCH @@ -607,7 +644,25 @@ HANDLE FacebookProto::GetAwayMsg(MCONTACT hContact) int FacebookProto::OnContactDeleted(WPARAM wParam,LPARAM) { - CancelFriendship(wParam, 1); + MCONTACT hContact = (MCONTACT)wParam; + + // Remove this contact from caches + ptrA id(getStringA(hContact, FACEBOOK_KEY_ID)); + if (id) + facy.user_id_to_hcontact.erase(std::string(id)); + + ptrA tid(getStringA(hContact, FACEBOOK_KEY_TID)); + if (tid) + facy.thread_id_to_user_id.erase(std::string(tid)); + + if (isChatRoom(hContact)) { + ptrT chat_id(getTStringA(hContact, "ChatRoomID")); + if (chat_id) + facy.chat_id_to_hcontact.erase(std::tstring(chat_id)); + } + + // Cancel friendship (with confirmation) + CancelFriendship(hContact, 1); return 0; } -- cgit v1.2.3