From ed204fe350540966e492859c9f9c734b6b9f1cde Mon Sep 17 00:00:00 2001 From: MikalaiR Date: Sun, 3 Jul 2016 17:19:54 +0000 Subject: dbx_lmdb: code optimization git-svn-id: http://svn.miranda-ng.org/main/trunk@17057 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Dbx_mdb/dbx_lmdb.vcxproj | 4 +- plugins/Dbx_mdb/src/dbcontacts.cpp | 29 ++++-------- plugins/Dbx_mdb/src/dbevents.cpp | 4 +- plugins/Dbx_mdb/src/dbintf.cpp | 22 +-------- plugins/Dbx_mdb/src/dbintf.h | 26 ++++------ plugins/Dbx_mdb/src/dbmodulechain.cpp | 89 +++++++++-------------------------- plugins/Dbx_mdb/src/dbsettings.cpp | 15 +++--- plugins/Dbx_mdb/src/stdafx.h | 33 +++++++++++-- 8 files changed, 80 insertions(+), 142 deletions(-) (limited to 'plugins') diff --git a/plugins/Dbx_mdb/dbx_lmdb.vcxproj b/plugins/Dbx_mdb/dbx_lmdb.vcxproj index fa4812577b..11f517d307 100644 --- a/plugins/Dbx_mdb/dbx_lmdb.vcxproj +++ b/plugins/Dbx_mdb/dbx_lmdb.vcxproj @@ -29,13 +29,15 @@ NotUsing - + NotUsing Sync + MDB_DEBUG=5;%(PreprocessorDefinitions) + MDB_VL32;%(PreprocessorDefinitions) \ No newline at end of file diff --git a/plugins/Dbx_mdb/src/dbcontacts.cpp b/plugins/Dbx_mdb/src/dbcontacts.cpp index 2645a12db2..629790ea61 100644 --- a/plugins/Dbx_mdb/src/dbcontacts.cpp +++ b/plugins/Dbx_mdb/src/dbcontacts.cpp @@ -286,12 +286,12 @@ void DBCachedContact::Advance(DWORD id, DBEvent &dbe) void DBCachedContact::Snapshot() { - memcpy(&tmp_dbc, &dbc, sizeof(dbc)); + tmp_dbc = dbc; } void DBCachedContact::Revert() { - memcpy(&dbc, &tmp_dbc, sizeof(dbc)); + dbc = tmp_dbc; } ///////////////////////////////////////////////////////////////////////////////////////// @@ -301,26 +301,15 @@ void CDbxMdb::FillContacts() { LIST arContacts(m_contactCount); - { - txn_ptr_ro trnlck(m_txn); - cursor_ptr_ro cursor(m_curContacts); - - MDB_val key, data; - while (mdb_cursor_get(cursor, &key, &data, MDB_NEXT) == MDB_SUCCESS) - { - const DBContact *dbc = (const DBContact*)data.mv_data; - - DBCachedContact *cc = m_cache->AddContactToCache(*(MCONTACT*)key.mv_data); - cc->dbc.dwEventCount = dbc->dwEventCount; - cc->dbc.dwFirstUnread = dbc->dwFirstUnread; - cc->dbc.tsFirstUnread = dbc->tsFirstUnread; - arContacts.insert(cc); - } - } + txn_ptr_ro trnlck(m_txn); + cursor_ptr_ro cursor(m_curContacts); - for (int i = 0; i < arContacts.getCount(); i++) + MDB_val key, data; + while (mdb_cursor_get(cursor, &key, &data, MDB_NEXT) == MDB_SUCCESS) { - DBCachedContact *cc = arContacts[i]; + DBCachedContact *cc = m_cache->AddContactToCache(*(MCONTACT*)key.mv_data); + cc->dbc = *(DBContact*)data.mv_data; + CheckProto(cc, ""); DBVARIANT dbv; dbv.type = DBVT_DWORD; diff --git a/plugins/Dbx_mdb/src/dbevents.cpp b/plugins/Dbx_mdb/src/dbevents.cpp index 5436cbca38..48c8993cdd 100644 --- a/plugins/Dbx_mdb/src/dbevents.cpp +++ b/plugins/Dbx_mdb/src/dbevents.cpp @@ -36,7 +36,7 @@ STDMETHODIMP_(MEVENT) CDbxMdb::AddEvent(MCONTACT contactID, DBEVENTINFO *dbei) DBEvent dbe; dbe.contactID = contactID; // store native or subcontact's id - dbe.ofsModuleName = GetModuleNameOfs(dbei->szModule); + dbe.ofsModuleName = GetModuleID(dbei->szModule); MCONTACT contactNotifyID = contactID; DBCachedContact *cc, *ccSub = NULL; @@ -221,7 +221,7 @@ STDMETHODIMP_(BOOL) CDbxMdb::GetEvent(MEVENT hDbEvent, DBEVENTINFO *dbei) const DBEvent *dbe = (const DBEvent*)data.mv_data; - dbei->szModule = GetModuleNameByOfs(dbe->ofsModuleName); + dbei->szModule = GetModuleName(dbe->ofsModuleName); dbei->timestamp = dbe->timestamp; dbei->flags = dbe->flags; dbei->eventType = dbe->wEventType; diff --git a/plugins/Dbx_mdb/src/dbintf.cpp b/plugins/Dbx_mdb/src/dbintf.cpp index 1f0befba61..f27e819a4d 100644 --- a/plugins/Dbx_mdb/src/dbintf.cpp +++ b/plugins/Dbx_mdb/src/dbintf.cpp @@ -23,23 +23,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "stdafx.h" -static int ModCompare(const ModuleName *mn1, const ModuleName *mn2) -{ - return strcmp(mn1->szName, mn2->szName); -} - -static int OfsCompare(const ModuleName *mn1, const ModuleName *mn2) -{ - return (mn1->dwId - mn2->dwId); -} - CDbxMdb::CDbxMdb(const TCHAR *tszFileName, int iMode) : m_safetyMode(true), m_bReadOnly((iMode & DBMODE_READONLY) != 0), m_bShared((iMode & DBMODE_SHARED) != 0), m_maxContactId(1), - m_lMods(50, ModCompare), - m_lOfs(50, OfsCompare), m_lResidentSettings(50, strcmp) { m_tszProfileName = mir_tstrdup(tszFileName); @@ -50,14 +38,10 @@ CDbxMdb::CDbxMdb(const TCHAR *tszFileName, int iMode) : mdb_env_set_userctx(m_pMdbEnv, this); m_codePage = Langpack_GetDefaultCodePage(); - m_hModHeap = HeapCreate(0, 0, 0); } CDbxMdb::~CDbxMdb() { - // destroy modules - HeapDestroy(m_hModHeap); - mdb_env_close(m_pMdbEnv); DestroyServiceFunction(hService); @@ -135,8 +119,6 @@ int CDbxMdb::Load(bool bSkipInit) mdb_cursor_open(m_txn, m_dbEventsSort, &m_curEventsSort); mdb_cursor_open(m_txn, m_dbSettings, &m_curSettings); mdb_cursor_open(m_txn, m_dbModules, &m_curModules); - if (mdb_cursor_get(m_curModules, &key, &val, MDB_LAST) == MDB_SUCCESS) - m_maxModuleID = *(DWORD*)key.mv_data; mdb_cursor_open(m_txn, m_dbContacts, &m_curContacts); if (mdb_cursor_get(m_curContacts, &key, &val, MDB_LAST) == MDB_SUCCESS) @@ -150,7 +132,7 @@ int CDbxMdb::Load(bool bSkipInit) } - if (InitModuleNames()) return EGROKPRF_DAMAGED; + if (InitModules()) return EGROKPRF_DAMAGED; if (InitCrypt()) return EGROKPRF_DAMAGED; // everything is ok, go on @@ -201,7 +183,7 @@ int CDbxMdb::Check(void) int CDbxMdb::PrepareCheck(int*) { - InitModuleNames(); + InitModules(); return InitCrypt(); } diff --git a/plugins/Dbx_mdb/src/dbintf.h b/plugins/Dbx_mdb/src/dbintf.h index 5aeadf3488..51ee91ed64 100644 --- a/plugins/Dbx_mdb/src/dbintf.h +++ b/plugins/Dbx_mdb/src/dbintf.h @@ -35,15 +35,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define MARKED_READ (DBEF_READ | DBEF_SENT) -struct ModuleName -{ - DWORD dwId; - char szName[]; -}; - #include -#define DBHEADER_VERSION MAKELONG(1, 2) +#define DBHEADER_VERSION MAKELONG(1, 3) #define DBHEADER_SIGNATURE 0x40DECADEu struct DBHeader @@ -124,8 +118,6 @@ struct EventItem DWORD eventId; }; -class LMDBEventCursor; - struct CDbxMdb : public MIDatabase, public MIDatabaseChecker, public MZeroedObject { friend class LMDBEventCursor; @@ -216,7 +208,7 @@ public: protected: MDB_env *m_pMdbEnv; - MDB_txn *m_txn; + TXN_RO m_txn; DWORD m_dwFileSize; MDB_dbi m_dbGlobal; DBHeader m_header; @@ -261,19 +253,17 @@ protected: MDB_dbi m_dbModules; MDB_cursor *m_curModules; + + std::map m_Modules; - HANDLE m_hModHeap; - LIST m_lMods, m_lOfs; LIST m_lResidentSettings; HANDLE hEventAddedEvent, hEventDeletedEvent, hEventFilterAddedEvent; MCONTACT m_hLastCachedContact; - DWORD m_maxModuleID; - void AddToList(const char *name, DWORD ofs); - DWORD FindExistingModuleNameOfs(const char *szName); - int InitModuleNames(void); - DWORD GetModuleNameOfs(const char *szName); - char* GetModuleNameByOfs(DWORD ofs); + int InitModules(); + + DWORD GetModuleID(const char *szName); + char* GetModuleName(DWORD dwId); int GetContactSettingWorker(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv, int isStatic); diff --git a/plugins/Dbx_mdb/src/dbmodulechain.cpp b/plugins/Dbx_mdb/src/dbmodulechain.cpp index fc86bad6bc..142126c6dc 100644 --- a/plugins/Dbx_mdb/src/dbmodulechain.cpp +++ b/plugins/Dbx_mdb/src/dbmodulechain.cpp @@ -23,23 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "stdafx.h" -void CDbxMdb::AddToList(const char *szName, DWORD dwId) -{ - size_t iNameLength = strlen(szName) + 1; - ModuleName *mn = (ModuleName*)HeapAlloc(m_hModHeap, 0, sizeof(ModuleName) + iNameLength); - mn->dwId = dwId; - memcpy(&mn->szName, szName, iNameLength); - - if (m_lMods.getIndex(mn) != -1) - DatabaseCorruption(_T("%s (Module Name not unique)")); - m_lMods.insert(mn); - - if (m_lOfs.getIndex(mn) != -1) - DatabaseCorruption(_T("%s (Module Offset not unique)")); - m_lOfs.insert(mn); -} - -int CDbxMdb::InitModuleNames(void) +int CDbxMdb::InitModules() { txn_ptr_ro trnlck(m_txn); cursor_ptr_ro cursor(m_curModules); @@ -49,71 +33,42 @@ int CDbxMdb::InitModuleNames(void) { DWORD iMod = *(DWORD*)key.mv_data; const char *szMod = (const char*)data.mv_data; - AddToList(szMod, iMod); - } - return 0; -} - -thread_local ModuleName *t_lastmn = nullptr; - -DWORD CDbxMdb::FindExistingModuleNameOfs(const char *szName) -{ - if (t_lastmn && !strcmp(szName, t_lastmn->szName)) - return t_lastmn->dwId; - - ModuleName *pmn = m_lMods.find((ModuleName*)(szName - sizeof(DWORD))); // crazy hack - if (pmn != nullptr) - { - t_lastmn = pmn; - return pmn->dwId; + m_Modules[iMod] = szMod; } return 0; } // will create the offset if it needs to -DWORD CDbxMdb::GetModuleNameOfs(const char *szName) +DWORD CDbxMdb::GetModuleID(const char *szName) { - DWORD ofsExisting = FindExistingModuleNameOfs(szName); - if (ofsExisting) - return ofsExisting; - - if (m_bReadOnly) - return 0; - - size_t nameLen = strlen(szName); - -// mir_cslock lck(m_csDbAccess); - - // need to create the module name - DWORD newIdx = InterlockedIncrement(&m_maxModuleID); - - MDB_val key = { sizeof(DWORD), &newIdx }, data = { nameLen + 1, (void*)szName }; - - for (;; Remap()) { - txn_ptr trnlck(m_pMdbEnv); - MDB_CHECK(mdb_put(trnlck, m_dbModules, &key, &data, 0), -1); - if (trnlck.commit() == MDB_SUCCESS) - break; + DWORD iHash = mir_hashstr(szName); + if (auto it = m_Modules.find(iHash) == m_Modules.end()) + { + MDB_val key = { sizeof(iHash), &iHash }, data = { strlen(szName) + 1, (void*)szName }; + + for (;; Remap()) { + txn_ptr txn(m_pMdbEnv); + MDB_CHECK(mdb_put(txn, m_dbModules, &key, &data, 0), -1); + if (txn.commit() == MDB_SUCCESS) + break; + } + m_Modules[iHash] = szName; } - AddToList(szName, newIdx); - - // quit - return newIdx; + return iHash; } -char* CDbxMdb::GetModuleNameByOfs(DWORD ofs) +char* CDbxMdb::GetModuleName(DWORD dwId) { - ModuleName *mn = m_lOfs.find((ModuleName*)&ofs); - return mn ? mn->szName : nullptr; + auto it = m_Modules.find(dwId); + return it != m_Modules.end() ? const_cast(it->second.c_str()) : nullptr; } STDMETHODIMP_(BOOL) CDbxMdb::EnumModuleNames(DBMODULEENUMPROC pFunc, void *pParam) { - for (int i = 0; i < m_lMods.getCount(); i++) { - ModuleName *pmn = m_lMods[i]; - if (int ret = pFunc(pmn->szName, pmn->dwId, (LPARAM)pParam)) + for (auto it = m_Modules.begin(); it != m_Modules.end(); ++it) + if (int ret = pFunc(it->second.c_str(), it->first, (LPARAM)pParam)) return ret; - } + return 0; } diff --git a/plugins/Dbx_mdb/src/dbsettings.cpp b/plugins/Dbx_mdb/src/dbsettings.cpp index ec9a2549be..95faa27a68 100644 --- a/plugins/Dbx_mdb/src/dbsettings.cpp +++ b/plugins/Dbx_mdb/src/dbsettings.cpp @@ -107,7 +107,7 @@ LBL_Seek: DBSettingKey *keyVal = (DBSettingKey *)_alloca(sizeof(DBSettingKey) + settingNameLen + 1); keyVal->hContact = contactID; - keyVal->dwModuleId = GetModuleNameOfs(szModule); + keyVal->dwModuleId = GetModuleID(szModule); memcpy(&keyVal->szSettingName, szSetting, settingNameLen + 1); @@ -459,7 +459,7 @@ STDMETHODIMP_(BOOL) CDbxMdb::WriteContactSetting(MCONTACT contactID, DBCONTACTWR DBSettingKey *keyVal = (DBSettingKey *)_alloca(sizeof(DBSettingKey) + settingNameLen + 1); keyVal->hContact = contactID; - keyVal->dwModuleId = GetModuleNameOfs(dbcws->szModule); + keyVal->dwModuleId = GetModuleID(dbcws->szModule); memcpy(&keyVal->szSettingName, dbcws->szSetting, settingNameLen + 1); @@ -527,7 +527,7 @@ STDMETHODIMP_(BOOL) CDbxMdb::DeleteContactSetting(MCONTACT contactID, LPCSTR szM { DBSettingKey *keyVal = (DBSettingKey*)_alloca(sizeof(DBSettingKey) + settingNameLen + 1); keyVal->hContact = contactID; - keyVal->dwModuleId = GetModuleNameOfs(szModule); + keyVal->dwModuleId = GetModuleID(szModule); memcpy(&keyVal->szSettingName, szSetting, settingNameLen + 1); MDB_val key = { sizeof(DBSettingKey) + settingNameLen + 1, keyVal }; @@ -556,19 +556,16 @@ STDMETHODIMP_(BOOL) CDbxMdb::EnumContactSettings(MCONTACT contactID, DBCONTACTEN { int result = -1; - DBSettingKey keySearch = { 0 }; - keySearch.hContact = contactID; - keySearch.dwModuleId = GetModuleNameOfs(dbces->szModule); - + DBSettingKey keyVal = { contactID, GetModuleID(dbces->szModule) }; txn_ptr_ro txn(m_txn); cursor_ptr_ro cursor(m_curSettings); - MDB_val key = { sizeof(keySearch), &keySearch }, data; + MDB_val key = { sizeof(keyVal), &keyVal }, data; for (int res = mdb_cursor_get(cursor, &key, &data, MDB_SET_RANGE); res == MDB_SUCCESS; res = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) { const DBSettingKey *pKey = (const DBSettingKey*)key.mv_data; - if (pKey->hContact != contactID || pKey->dwModuleId != keySearch.dwModuleId) + if (pKey->hContact != contactID || pKey->dwModuleId != keyVal.dwModuleId) break; result = (dbces->pfnEnumProc)(pKey->szSettingName, dbces->lParam); } diff --git a/plugins/Dbx_mdb/src/stdafx.h b/plugins/Dbx_mdb/src/stdafx.h index 32fbfff7f1..5360475a0c 100644 --- a/plugins/Dbx_mdb/src/stdafx.h +++ b/plugins/Dbx_mdb/src/stdafx.h @@ -26,7 +26,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include -#include +#include +#include #include #include @@ -81,17 +82,39 @@ public: } }; -class txn_ptr_ro +struct TXN_RO { MDB_txn *m_txn; + bool bIsActive; + mir_cs cs; + + __forceinline TXN_RO() : m_txn(nullptr), bIsActive(false) {} + + __forceinline operator MDB_txn* () { return m_txn; } + __forceinline MDB_txn** operator &() { return &m_txn; } +}; + +class txn_ptr_ro +{ + TXN_RO &m_txn; + bool bNeedReset; + mir_cslock lock; public: - __forceinline txn_ptr_ro(MDB_txn *txn) : m_txn(txn) + __forceinline txn_ptr_ro(TXN_RO &txn) : m_txn(txn), bNeedReset(!txn.bIsActive), lock(m_txn.cs) { - mdb_txn_renew(m_txn); + if (bNeedReset) + { + mdb_txn_renew(m_txn); + m_txn.bIsActive = true; + } } __forceinline ~txn_ptr_ro() { - mdb_txn_reset(m_txn); + if (bNeedReset) + { + mdb_txn_reset(m_txn); + m_txn.bIsActive = false; + } } __forceinline operator MDB_txn*() const { return m_txn; } }; -- cgit v1.2.3