summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/Dbx_mdb/dbx_lmdb.vcxproj4
-rw-r--r--plugins/Dbx_mdb/src/dbcontacts.cpp29
-rw-r--r--plugins/Dbx_mdb/src/dbevents.cpp4
-rw-r--r--plugins/Dbx_mdb/src/dbintf.cpp22
-rw-r--r--plugins/Dbx_mdb/src/dbintf.h26
-rw-r--r--plugins/Dbx_mdb/src/dbmodulechain.cpp89
-rw-r--r--plugins/Dbx_mdb/src/dbsettings.cpp15
-rw-r--r--plugins/Dbx_mdb/src/stdafx.h33
8 files changed, 80 insertions, 142 deletions
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 @@
<ClCompile Include="src\lmdb\*.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
- <ClCompile Include="src\lmdb\*.cpp">
+ <ClCompile Include="src\lmdb\*.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemDefinitionGroup>
<ClCompile>
<ExceptionHandling>Sync</ExceptionHandling>
+ <PreprocessorDefinitions Condition="'$(Configuration)'=='Debug'">MDB_DEBUG=5;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>MDB_VL32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
</Project> \ 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<DBCachedContact> 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 <pshpack1.h>
-#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<DWORD, std::string> m_Modules;
- HANDLE m_hModHeap;
- LIST<ModuleName> m_lMods, m_lOfs;
LIST<char> 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<char*>(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 <process.h>
#include <memory>
#include <vector>
-#include <functional>
+#include <algorithm>
+#include <map>
#include <newpluginapi.h>
#include <win2k.h>
@@ -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; }
};