summaryrefslogtreecommitdiff
path: root/plugins/Dbx_mdb
diff options
context:
space:
mode:
authorMikalaiR <nikolay.romanovich@narod.ru>2016-02-18 12:32:59 +0000
committerMikalaiR <nikolay.romanovich@narod.ru>2016-02-18 12:32:59 +0000
commit2868202cb6260735157346833a4cf6326772011d (patch)
tree8bd251c1f657b3057975afee34055eba2c66f458 /plugins/Dbx_mdb
parent73a0b84498501c1e2907f1cdc5f222f1f400edfd (diff)
dbx_lmdb: speed optimization
git-svn-id: http://svn.miranda-ng.org/main/trunk@16301 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Dbx_mdb')
-rw-r--r--plugins/Dbx_mdb/src/dbcontacts.cpp18
-rw-r--r--plugins/Dbx_mdb/src/dbevents.cpp65
-rw-r--r--plugins/Dbx_mdb/src/dbintf.cpp28
-rw-r--r--plugins/Dbx_mdb/src/dbintf.h3
-rw-r--r--plugins/Dbx_mdb/src/dbmodulechain.cpp4
-rw-r--r--plugins/Dbx_mdb/src/dbsettings.cpp4
-rw-r--r--plugins/Dbx_mdb/src/stdafx.h31
7 files changed, 103 insertions, 50 deletions
diff --git a/plugins/Dbx_mdb/src/dbcontacts.cpp b/plugins/Dbx_mdb/src/dbcontacts.cpp
index 4bfec0261c..554df02d9a 100644
--- a/plugins/Dbx_mdb/src/dbcontacts.cpp
+++ b/plugins/Dbx_mdb/src/dbcontacts.cpp
@@ -104,6 +104,22 @@ STDMETHODIMP_(LONG) CDbxMdb::DeleteContact(MCONTACT contactID)
if (trnlck.commit())
break;
}
+
+ DBEventSortingKey keyVal = { 0, 0, contactID };
+ key = { sizeof(keyVal), &keyVal }; MDB_val data;
+
+ txn_ptr trnlck(m_pMdbEnv, true);
+ cursor_ptr cursor(trnlck, m_dbEventsSort);
+ mdb_cursor_get(cursor, &key, &data, MDB_SET);
+ while (mdb_cursor_get(cursor, &key, &data, MDB_NEXT) == MDB_SUCCESS)
+ {
+ DBEventSortingKey *pKey = (DBEventSortingKey*)key.mv_data;
+ if (pKey->dwContactId != contactID)
+ return 0;
+
+ mdb_cursor_del(cursor, 0);
+ }
+
return 0;
}
@@ -159,7 +175,7 @@ void CDbxMdb::GatherContactHistory(MCONTACT hContact, LIST<EventItem> &list)
DBEventSortingKey keyVal = { 0, 0, hContact };
MDB_val key = { sizeof(keyVal), &keyVal }, data;
- txn_ptr trnlck(m_pMdbEnv, true);
+ txn_ptr_ro trnlck(m_pMdbEnv);
cursor_ptr cursor(trnlck, m_dbEventsSort);
mdb_cursor_get(cursor, &key, &data, MDB_SET);
while (mdb_cursor_get(cursor, &key, &data, MDB_NEXT) == MDB_SUCCESS) {
diff --git a/plugins/Dbx_mdb/src/dbevents.cpp b/plugins/Dbx_mdb/src/dbevents.cpp
index dd9a75e12f..d8c5a37d6d 100644
--- a/plugins/Dbx_mdb/src/dbevents.cpp
+++ b/plugins/Dbx_mdb/src/dbevents.cpp
@@ -23,6 +23,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "stdafx.h"
+MDB_txn* txn_ptr_ro::m_txn;
+
STDMETHODIMP_(LONG) CDbxMdb::GetEventCount(MCONTACT contactID)
{
DBCachedContact *cc = m_cache->GetCachedContact(contactID);
@@ -82,7 +84,7 @@ STDMETHODIMP_(MEVENT) CDbxMdb::AddEvent(MCONTACT contactID, DBEVENTINFO *dbei)
mir_cslockfull lck(m_csDbAccess);
DWORD dwEventId = ++m_dwMaxEventId;
- for (;; Remap()) {
+ for (bool bContactIncremented = false; ;[=](){ if (bContactIncremented) cc->dbc.dwEventCount--; }(), Remap()) {
txn_ptr txn(m_pMdbEnv);
MDB_val key = { sizeof(int), &dwEventId }, data = { sizeof(DBEvent) + dbe.cbBlob, NULL };
@@ -99,6 +101,7 @@ STDMETHODIMP_(MEVENT) CDbxMdb::AddEvent(MCONTACT contactID, DBEVENTINFO *dbei)
MDB_CHECK(mdb_put(txn, m_dbEventsSort, &key, &data, 0), 0);
cc->Advance(dwEventId, dbe);
+ bContactIncremented = true;
MDB_val keyc = { sizeof(int), &contactID }, datac = { sizeof(DBContact), &cc->dbc };
MDB_CHECK(mdb_put(txn, m_dbContacts, &keyc, &datac, 0), 0);
@@ -133,51 +136,56 @@ STDMETHODIMP_(BOOL) CDbxMdb::DeleteEvent(MCONTACT contactID, MEVENT hDbEvent)
return 1;
mir_cslockfull lck(m_csDbAccess);
- txn_ptr txn(m_pMdbEnv);
-
- for (;; Remap()) {
+
+ for (bool bContactDecremented = false; ;[=](){ if (bContactDecremented) cc->dbc.dwEventCount++; }(), Remap())
+ {
+ txn_ptr txn(m_pMdbEnv);
MDB_val key = { sizeof(MEVENT), &hDbEvent }, data;
- if (mdb_get(txn, m_dbEvents, &key, &data) != MDB_SUCCESS)
- return 1;
+ MDB_CHECK(mdb_get(txn, m_dbEvents, &key, &data), 1);
DBEvent *dbe = (DBEvent*)data.mv_data;
DWORD dwSavedContact = dbe->contactID;
DBEventSortingKey key2 = { hDbEvent, dbe->timestamp, contactID };
- mdb_del(txn, m_dbEvents, &key, &data);
// remove a sorting key
key.mv_size = sizeof(key2); key.mv_data = &key2;
- mdb_del(txn, m_dbEventsSort, &key, &data);
+ MDB_CHECK(mdb_del(txn, m_dbEventsSort, &key, &data), 1)
// remove a sub's history entry too
if (contactID != dwSavedContact) {
key2.dwContactId = dwSavedContact;
- mdb_del(txn, m_dbEventsSort, &key, &data);
+ MDB_CHECK(mdb_del(txn, m_dbEventsSort, &key, &data), 1);
}
+ // remove a event
+ key = { sizeof(MEVENT), &hDbEvent };
+ MDB_CHECK(mdb_del(txn, m_dbEvents, &key, &data), 1);
+
// update a contact
key.mv_size = sizeof(int); key.mv_data = &contactID;
cc->dbc.dwEventCount--;
+ bContactDecremented = true;
if (cc->dbc.dwFirstUnread == hDbEvent)
FindNextUnread(txn, cc, key2);
+
+ data = { sizeof(DBContact), &cc->dbc };
+
+ MDB_CHECK(mdb_put(txn, m_dbContacts, &key, &data, 0), 0);
if (txn.commit())
break;
}
lck.unlock();
- // call notifier while outside mutex
NotifyEventHooks(hEventDeletedEvent, contactID, hDbEvent);
- // get back in
- lck.lock();
return 0;
}
STDMETHODIMP_(LONG) CDbxMdb::GetBlobSize(MEVENT hDbEvent)
{
mir_cslock lck(m_csDbAccess);
- txn_ptr txn(m_pMdbEnv, true);
+ txn_ptr_ro txn(m_pMdbEnv);
MDB_val key = { sizeof(MEVENT), &hDbEvent }, data;
if (mdb_get(txn, m_dbEvents, &key, &data) != MDB_SUCCESS)
@@ -196,7 +204,7 @@ STDMETHODIMP_(BOOL) CDbxMdb::GetEvent(MEVENT hDbEvent, DBEVENTINFO *dbei)
}
mir_cslock lck(m_csDbAccess);
- txn_ptr txn(m_pMdbEnv, true);
+ txn_ptr_ro txn(m_pMdbEnv);
MDB_val key = { sizeof(MEVENT), &hDbEvent }, data;
if (mdb_get(txn, m_dbEvents, &key, &data) != MDB_SUCCESS)
@@ -210,11 +218,13 @@ STDMETHODIMP_(BOOL) CDbxMdb::GetEvent(MEVENT hDbEvent, DBEVENTINFO *dbei)
dbei->timestamp = dbe->timestamp;
dbei->flags = dbe->flags;
dbei->eventType = dbe->wEventType;
- int bytesToCopy = (dbei->cbBlob < dbe->cbBlob) ? dbei->cbBlob : dbe->cbBlob;
+ size_t bytesToCopy = min(dbei->cbBlob, dbe->cbBlob);
dbei->cbBlob = dbe->cbBlob;
- if (bytesToCopy && dbei->pBlob) {
+ if (bytesToCopy && dbei->pBlob)
+ {
BYTE *pSrc = (BYTE*)data.mv_data + sizeof(DBEvent);
- if (dbe->flags & DBEF_ENCRYPTED) {
+ if (dbe->flags & DBEF_ENCRYPTED)
+ {
dbei->flags &= ~DBEF_ENCRYPTED;
size_t len;
BYTE* pBlob = (BYTE*)m_crypto->decodeBuffer(pSrc, dbe->cbBlob, &len);
@@ -222,7 +232,7 @@ STDMETHODIMP_(BOOL) CDbxMdb::GetEvent(MEVENT hDbEvent, DBEVENTINFO *dbei)
return 1;
memcpy(dbei->pBlob, pBlob, bytesToCopy);
- if (bytesToCopy > (int)len)
+ if (bytesToCopy > len)
memset(dbei->pBlob + len, 0, bytesToCopy - len);
mir_free(pBlob);
}
@@ -294,7 +304,7 @@ STDMETHODIMP_(MCONTACT) CDbxMdb::GetEventContact(MEVENT hDbEvent)
if (hDbEvent == 0) return INVALID_CONTACT_ID;
mir_cslock lck(m_csDbAccess);
- txn_ptr txn(m_pMdbEnv, true);
+ txn_ptr_ro txn(m_pMdbEnv);
MDB_val key = { sizeof(MEVENT), &hDbEvent }, data;
if (mdb_get(txn, m_dbEvents, &key, &data) != MDB_SUCCESS)
@@ -310,7 +320,7 @@ STDMETHODIMP_(MEVENT) CDbxMdb::FindFirstEvent(MCONTACT contactID)
MDB_val key = { sizeof(keyVal), &keyVal }, data;
mir_cslock lck(m_csDbAccess);
- txn_ptr txn(m_pMdbEnv, true);
+ txn_ptr_ro txn(m_pMdbEnv);
cursor_ptr cursor(txn, m_dbEventsSort);
mdb_cursor_get(cursor, &key, &data, MDB_SET);
@@ -334,7 +344,7 @@ STDMETHODIMP_(MEVENT) CDbxMdb::FindLastEvent(MCONTACT contactID)
MDB_val key = { sizeof(keyVal), &keyVal }, data;
mir_cslock lck(m_csDbAccess);
- txn_ptr txn(m_pMdbEnv, true);
+ txn_ptr_ro txn(m_pMdbEnv);
cursor_ptr cursor(txn, m_dbEventsSort);
mdb_cursor_get(cursor, &key, &data, MDB_SET);
@@ -354,7 +364,7 @@ STDMETHODIMP_(MEVENT) CDbxMdb::FindNextEvent(MCONTACT contactID, MEVENT hDbEvent
DWORD ts;
mir_cslock lck(m_csDbAccess);
- txn_ptr txn(m_pMdbEnv, true);
+ txn_ptr_ro txn(m_pMdbEnv);
if (m_evLast != hDbEvent) {
MDB_val key = { sizeof(MEVENT), &hDbEvent };
@@ -387,7 +397,7 @@ STDMETHODIMP_(MEVENT) CDbxMdb::FindPrevEvent(MCONTACT contactID, MEVENT hDbEvent
DWORD ts;
mir_cslock lck(m_csDbAccess);
- txn_ptr txn(m_pMdbEnv, true);
+ txn_ptr_ro txn(m_pMdbEnv);
if (m_evLast != hDbEvent) {
MDB_val key = { sizeof(MEVENT), &hDbEvent };
@@ -411,12 +421,3 @@ STDMETHODIMP_(MEVENT) CDbxMdb::FindPrevEvent(MCONTACT contactID, MEVENT hDbEvent
m_tsLast = pKey->ts;
return m_evLast = (pKey->dwContactId == contactID) ? pKey->dwEventId : 0;
}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// low-level history cleaner
-
-int CDbxMdb::WipeContactHistory(DBContact*)
-{
- // drop subContact's history if any
- return 0;
-}
diff --git a/plugins/Dbx_mdb/src/dbintf.cpp b/plugins/Dbx_mdb/src/dbintf.cpp
index 503746369e..b7c0c81572 100644
--- a/plugins/Dbx_mdb/src/dbintf.cpp
+++ b/plugins/Dbx_mdb/src/dbintf.cpp
@@ -23,6 +23,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "stdafx.h"
+#define CMP_UINT32(A,B) if (A != B) return (A < B) ? -1 : 1;
+
+static int MDB_CompareEvents(const MDB_val *v1, const MDB_val *v2)
+{
+ DBEventSortingKey *k1 = static_cast<DBEventSortingKey*>(v1->mv_data);
+ DBEventSortingKey *k2 = static_cast<DBEventSortingKey*>(v2->mv_data);
+ CMP_UINT32(k1->dwContactId, k2->dwContactId);
+ CMP_UINT32(k1->ts, k2->ts);
+ CMP_UINT32(k1->dwEventId, k2->dwEventId);
+ return 0;
+}
+
static int ModCompare(const ModuleName *mn1, const ModuleName *mn2)
{
return strcmp(mn1->name, mn2->name);
@@ -85,11 +97,12 @@ CDbxMdb::~CDbxMdb()
int CDbxMdb::Load(bool bSkipInit)
{
- if (!Remap())
+ if (!Map())
return EGROKPRF_CANTREAD;
if (!bSkipInit) {
txn_ptr trnlck(m_pMdbEnv);
+
mdb_open(trnlck, "global", MDB_CREATE | MDB_INTEGERKEY, &m_dbGlobal);
mdb_open(trnlck, "contacts", MDB_CREATE | MDB_INTEGERKEY, &m_dbContacts);
mdb_open(trnlck, "modules", MDB_CREATE | MDB_INTEGERKEY, &m_dbModules);
@@ -97,6 +110,8 @@ int CDbxMdb::Load(bool bSkipInit)
mdb_open(trnlck, "eventsrt", MDB_CREATE | MDB_INTEGERKEY, &m_dbEventsSort);
mdb_open(trnlck, "settings", MDB_CREATE, &m_dbSettings);
+ //mdb_set_compare(trnlck, m_dbEventsSort, MDB_CompareEvents);
+
DWORD keyVal = 1;
MDB_val key = { sizeof(DWORD), &keyVal }, data;
if (mdb_get(trnlck, m_dbGlobal, &key, &data) == MDB_SUCCESS) {
@@ -146,7 +161,7 @@ int CDbxMdb::Load(bool bSkipInit)
int CDbxMdb::Create(void)
{
m_dwFileSize = 0;
- return (Remap()) ? 0 : EGROKPRF_CANTREAD;
+ return (Map()) ? 0 : EGROKPRF_CANTREAD;
}
int CDbxMdb::Check(void)
@@ -182,7 +197,7 @@ STDMETHODIMP_(void) CDbxMdb::SetCacheSafetyMode(BOOL bIsSet)
m_safetyMode = bIsSet != 0;
}
-bool CDbxMdb::Remap()
+bool CDbxMdb::Map()
{
m_dwFileSize += 0x100000;
mdb_env_set_mapsize(m_pMdbEnv, m_dwFileSize);
@@ -195,6 +210,13 @@ bool CDbxMdb::Remap()
return mdb_env_open(m_pMdbEnv, _T2A(m_tszProfileName), mode, 0664) == MDB_SUCCESS;
}
+bool CDbxMdb::Remap()
+{
+ mir_cslock lck(m_csDbAccess);
+ m_dwFileSize += 0x100000;
+ return mdb_env_set_mapsize(m_pMdbEnv, m_dwFileSize) == MDB_SUCCESS;
+}
+
/////////////////////////////////////////////////////////////////////////////////////////
static DWORD DatabaseCorrupted = 0;
diff --git a/plugins/Dbx_mdb/src/dbintf.h b/plugins/Dbx_mdb/src/dbintf.h
index 30dd786bb9..866b637786 100644
--- a/plugins/Dbx_mdb/src/dbintf.h
+++ b/plugins/Dbx_mdb/src/dbintf.h
@@ -205,7 +205,7 @@ protected:
void FillContacts(void);
bool Remap();
-
+ bool Map();
public: // Check functions
int WorkInitialChecks(int);
int WorkModuleChain(int);
@@ -248,7 +248,6 @@ protected:
MDB_dbi m_dbContacts;
int m_contactCount, m_dwMaxContactId;
- int WipeContactHistory(DBContact *dbc);
void GatherContactHistory(MCONTACT hContact, LIST<EventItem> &items);
////////////////////////////////////////////////////////////////////////////
diff --git a/plugins/Dbx_mdb/src/dbmodulechain.cpp b/plugins/Dbx_mdb/src/dbmodulechain.cpp
index 1ab0971b20..a91ccc576c 100644
--- a/plugins/Dbx_mdb/src/dbmodulechain.cpp
+++ b/plugins/Dbx_mdb/src/dbmodulechain.cpp
@@ -42,8 +42,8 @@ int CDbxMdb::InitModuleNames(void)
{
m_maxModuleID = 0;
- txn_ptr trnlck(m_pMdbEnv);
- mdb_open(trnlck, "modules", MDB_INTEGERKEY, &m_dbModules);
+ txn_ptr_ro trnlck(m_pMdbEnv);
+ //mdb_open(trnlck, "modules", MDB_INTEGERKEY, &m_dbModules);
cursor_ptr cursor(trnlck, m_dbModules);
if (!cursor)
diff --git a/plugins/Dbx_mdb/src/dbsettings.cpp b/plugins/Dbx_mdb/src/dbsettings.cpp
index 89750b8fc7..ebfe1970b4 100644
--- a/plugins/Dbx_mdb/src/dbsettings.cpp
+++ b/plugins/Dbx_mdb/src/dbsettings.cpp
@@ -121,7 +121,7 @@ LBL_Seek:
DBCachedContact *cc = (contactID) ? m_cache->GetCachedContact(contactID) : NULL;
- txn_ptr trnlck(m_pMdbEnv);
+ txn_ptr_ro trnlck(m_pMdbEnv);
//mdb_open(trnlck, "settings", 0, &m_dbSettings);
DBSettingKey keySearch;
@@ -597,7 +597,7 @@ STDMETHODIMP_(BOOL) CDbxMdb::EnumContactSettings(MCONTACT contactID, DBCONTACTEN
LIST<char> arSettings(50);
{
- txn_ptr trnlck(m_pMdbEnv, true);
+ txn_ptr_ro trnlck(m_pMdbEnv);
cursor_ptr cursor(trnlck, m_dbSettings);
MDB_val key = { sizeof(keySearch), &keySearch }, data;
diff --git a/plugins/Dbx_mdb/src/stdafx.h b/plugins/Dbx_mdb/src/stdafx.h
index dd06f5806a..ee324a69ee 100644
--- a/plugins/Dbx_mdb/src/stdafx.h
+++ b/plugins/Dbx_mdb/src/stdafx.h
@@ -21,13 +21,6 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#define _CRT_SECURE_NO_WARNINGS
-#define _WIN32_WINNT 0x0501
-
-#pragma warning(disable:4509)
-
-//#define SIZEOF(x) _countof(x)
-
#include <windows.h>
#include <time.h>
#include <process.h>
@@ -83,12 +76,34 @@ public:
}
};
+class txn_ptr_ro
+{
+ static MDB_txn *m_txn;
+
+public:
+ __forceinline txn_ptr_ro(MDB_env *pEnv)
+ {
+ if (!m_txn)
+ mdb_txn_begin(pEnv, NULL, MDB_RDONLY, &m_txn);
+ else
+ mdb_txn_renew(m_txn);
+ }
+
+ __forceinline ~txn_ptr_ro()
+ {
+ if (m_txn)
+ mdb_txn_reset(m_txn);
+ }
+
+ __forceinline operator MDB_txn*() const { return m_txn; }
+};
+
class cursor_ptr
{
MDB_cursor *m_cursor;
public:
- __forceinline cursor_ptr(const txn_ptr &_txn, MDB_dbi _dbi)
+ __forceinline cursor_ptr(MDB_txn *_txn, MDB_dbi _dbi)
{
if (mdb_cursor_open(_txn, _dbi, &m_cursor) != MDB_SUCCESS)
m_cursor = NULL;