summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/m_db_int.h57
-rw-r--r--plugins/Db3x_mmap/src/dbcontacts.cpp81
-rw-r--r--plugins/Db3x_mmap/src/dbintf.cpp34
-rw-r--r--plugins/Db3x_mmap/src/dbintf.h47
-rw-r--r--plugins/Db3x_mmap/src/dbsettings.cpp189
-rw-r--r--plugins/Dbx_tree/DataBase.cpp9
-rw-r--r--src/miranda32_10.vcxproj4
-rw-r--r--src/miranda32_10.vcxproj.filters6
-rw-r--r--src/modules/database/database.h49
-rw-r--r--src/modules/database/dbintf.cpp22
-rw-r--r--src/modules/database/mdatabasecache.cpp233
11 files changed, 425 insertions, 306 deletions
diff --git a/include/m_db_int.h b/include/m_db_int.h
index df6671a486..cd498c5330 100644
--- a/include/m_db_int.h
+++ b/include/m_db_int.h
@@ -31,8 +31,43 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
///////////////////////////////////////////////////////////////////////////////
// basic database interface
+struct DBCachedGlobalValue
+{
+ char* name;
+ DBVARIANT value;
+};
+
+struct DBCachedContactValue
+{
+ char* name;
+ DBVARIANT value;
+ DBCachedContactValue* next;
+};
+
+struct DBCachedContact
+{
+ HANDLE hContact;
+ HANDLE hNext;
+ DBCachedContactValue* first;
+ DBCachedContactValue* last;
+};
+
+interface MIDatabaseCache
+{
+ STDMETHOD_(DBCachedContact*,AddContactToCache)(HANDLE hContact) PURE;
+ STDMETHOD_(DBCachedContact*,GetCachedContact)(HANDLE hContact) PURE;
+ STDMETHOD_(void,FreeCachedContact)(HANDLE hContact) PURE;
+
+ STDMETHOD_(char*,InsertCachedSetting)(const char *szName, int) PURE;
+ STDMETHOD_(char*,GetCachedSetting)(const char *szModuleName, const char *szSettingName, int, int) PURE;
+ STDMETHOD_(void,SetCachedVariant)(DBVARIANT *s, DBVARIANT *d) PURE;
+ STDMETHOD_(DBVARIANT*,GetCachedValuePtr)(HANDLE hContact, char *szSetting, int bAllocate) PURE;
+};
+
interface MIDatabase
{
+ MIDatabaseCache* m_cache;
+
STDMETHOD_(void,SetCacheSafetyMode)(BOOL) PURE;
STDMETHOD_(LONG,GetContactCount)(void) PURE;
@@ -194,4 +229,26 @@ __forceinline MIDatabase* GetCurrentDatabase(void)
{ return (MIDatabase*)CallService(MS_DB_GET_CURRENT, 0, 0);
}
+// MS_DB_INIT_INSTANCE : initializes a database instance
+// wParam : 0 (unused)
+// lParam : MIDatabase* = pointer to a database instance
+// returns 0
+
+#define MS_DB_INIT_INSTANCE "DB/InitDbInstance"
+
+__forceinline void InitDbInstance(MIDatabase* pDatabase)
+{ CallService(MS_DB_INIT_INSTANCE, 0, (LPARAM)pDatabase);
+}
+
+// MS_DB_DESTROY_INSTANCE : destroys a database instance
+// wParam : 0 (unused)
+// lParam : MIDatabase* = pointer to a database instance
+// returns 0
+
+#define MS_DB_DESTROY_INSTANCE "DB/DestroyDbInstance"
+
+__forceinline void DestroyDbInstance(MIDatabase* pDatabase)
+{ CallService(MS_DB_DESTROY_INSTANCE, 0, (LPARAM)pDatabase);
+}
+
#endif // M_DB_INT_H__
diff --git a/plugins/Db3x_mmap/src/dbcontacts.cpp b/plugins/Db3x_mmap/src/dbcontacts.cpp
index 7dcbdc6206..c8be49a189 100644
--- a/plugins/Db3x_mmap/src/dbcontacts.cpp
+++ b/plugins/Db3x_mmap/src/dbcontacts.cpp
@@ -23,34 +23,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "commonheaders.h"
-DBCachedContactValueList* CDb3Base::AddToCachedContactList(HANDLE hContact, int index)
-{
- DBCachedContactValueList* VL = (DBCachedContactValueList*)HeapAlloc(m_hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedContactValueList));
- VL->hContact = hContact;
- if (index == -1)
- m_lContacts.insert(VL);
- else
- m_lContacts.insert(VL,index);
- return VL;
-}
-
-#define proto_module "Protocol"
-#define proto_setting "p"
-
int CDb3Base::CheckProto(HANDLE hContact, const char *proto)
{
char protobuf[MAX_PATH] = {0};
DBVARIANT dbv;
- DBCONTACTGETSETTING sVal = {proto_module,proto_setting,&dbv};
+ DBCONTACTGETSETTING sVal = { "Protocol", "p", &dbv };
dbv.type = DBVT_ASCIIZ;
dbv.pszVal = protobuf;
dbv.cchVal = sizeof(protobuf);
- if (GetContactSettingStatic(hContact, &sVal) != 0 || (dbv.type != DBVT_ASCIIZ))
+ if ( GetContactSettingStatic(hContact, &sVal) != 0 || (dbv.type != DBVT_ASCIIZ))
return 0;
- return !strcmp(protobuf,proto);
+ return !strcmp(protobuf, proto);
}
STDMETHODIMP_(LONG) CDb3Base::GetContactCount(void)
@@ -70,34 +56,30 @@ STDMETHODIMP_(HANDLE) CDb3Base::FindFirstContact(const char *szProto)
STDMETHODIMP_(HANDLE) CDb3Base::FindNextContact(HANDLE hContact, const char *szProto)
{
- DBCachedContactValueList VLtemp, *VL = NULL;
- VLtemp.hContact = hContact;
-
mir_cslock lck(m_csDbAccess);
- while (VLtemp.hContact) {
- int index;
- if (( index = m_lContacts.getIndex(&VLtemp)) != -1) {
- VL = m_lContacts[index];
+ while (hContact) {
+ DBCachedContact *VL = m_cache->GetCachedContact(hContact);
+ if (VL != NULL) {
if (VL->hNext != NULL) {
if (!szProto || CheckProto(VL->hNext, szProto))
return VL->hNext;
- VLtemp.hContact = VL->hNext;
+ hContact = VL->hNext;
continue;
} }
- DBContact *dbc = (DBContact*)DBRead(VLtemp.hContact,sizeof(DBContact),NULL);
+ DBContact *dbc = (DBContact*)DBRead(hContact, sizeof(DBContact), NULL);
if (dbc->signature != DBCONTACT_SIGNATURE)
break;
- if ( VL == NULL )
- VL = AddToCachedContactList(VLtemp.hContact,index);
+ if (VL == NULL)
+ VL = m_cache->AddContactToCache(hContact);
VL->hNext = (HANDLE)dbc->ofsNext;
if (VL->hNext != NULL && (!szProto || CheckProto(VL->hNext, szProto)))
return VL->hNext;
- VLtemp.hContact = VL->hNext;
+ hContact = VL->hNext;
}
return NULL;
@@ -127,24 +109,9 @@ STDMETHODIMP_(LONG) CDb3Base::DeleteContact(HANDLE hContact)
// get back in
lck.lock();
- DBCachedContactValueList VLtemp;
- VLtemp.hContact = hContact;
- int index;
- if ((index = m_lContacts.getIndex(&VLtemp)) != -1) {
- DBCachedContactValueList *VL = m_lContacts[index];
- DBCachedContactValue* V = VL->first;
- while ( V != NULL ) {
- DBCachedContactValue* V1 = V->next;
- FreeCachedVariant(&V->value);
- HeapFree( m_hCacheHeap, 0, V );
- V = V1;
- }
- HeapFree( m_hCacheHeap, 0, VL );
-
- if (VLtemp.hContact == m_hLastCachedContact)
- m_hLastCachedContact = NULL;
- m_lContacts.remove(index);
- }
+ m_cache->FreeCachedContact(hContact);
+ if (hContact == m_hLastCachedContact)
+ m_hLastCachedContact = NULL;
dbc = (DBContact*)DBRead(hContact, sizeof(DBContact), NULL);
//delete settings chain
@@ -182,12 +149,9 @@ STDMETHODIMP_(LONG) CDb3Base::DeleteContact(HANDLE hContact)
dbcPrev->ofsNext = ofsNext;
DBWrite(ofsThis,dbcPrev,sizeof(DBContact));
- DBCachedContactValueList VLtemp;
- VLtemp.hContact = (HANDLE)ofsThis;
- if ((index = m_lContacts.getIndex(&VLtemp)) != -1) {
- DBCachedContactValueList *VL = m_lContacts[index];
+ DBCachedContact *VL = m_cache->GetCachedContact((HANDLE)ofsThis);
+ if (VL)
VL->hNext = (HANDLE)ofsNext;
- }
}
//delete contact
@@ -215,9 +179,8 @@ STDMETHODIMP_(HANDLE) CDb3Base::AddContact()
DBWrite(ofsNew,&dbc,sizeof(DBContact));
DBWrite(0,&m_dbHeader,sizeof(m_dbHeader));
DBFlush(0);
-
- AddToCachedContactList((HANDLE)ofsNew, -1);
}
+ m_cache->AddContactToCache((HANDLE)ofsNew);
NotifyEventHooks(hContactAddedEvent,(WPARAM)ofsNew,0);
return (HANDLE)ofsNew;
@@ -225,17 +188,13 @@ STDMETHODIMP_(HANDLE) CDb3Base::AddContact()
STDMETHODIMP_(BOOL) CDb3Base::IsDbContact(HANDLE hContact)
{
- mir_cslock lck(m_csDbAccess);
-
- DBCachedContactValueList VLtemp;
- VLtemp.hContact = hContact;
- int index = m_lContacts.getIndex(&VLtemp);
- if (index != -1)
+ if (m_cache->GetCachedContact(hContact))
return TRUE;
+ mir_cslock lck(m_csDbAccess);
DBContact *dbc = (DBContact*)DBRead(hContact,sizeof(DBContact),NULL);
if (dbc->signature == DBCONTACT_SIGNATURE) {
- AddToCachedContactList(hContact, index);
+ m_cache->AddContactToCache(hContact);
return TRUE;
}
diff --git a/plugins/Db3x_mmap/src/dbintf.cpp b/plugins/Db3x_mmap/src/dbintf.cpp
index 34a34ab6ab..be56756d35 100644
--- a/plugins/Db3x_mmap/src/dbintf.cpp
+++ b/plugins/Db3x_mmap/src/dbintf.cpp
@@ -25,21 +25,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
DBSignature dbSignature = {"Miranda ICQ DB",0x1A};
-static int stringCompare(const char* p1, const char* p2)
-{
- return strcmp(p1+1, p2+1);
-}
-
-static int stringCompare2(const char* p1, const char* p2)
-{
- return strcmp(p1, p2);
-}
-
-static int compareGlobals(const DBCachedGlobalValue* p1, const DBCachedGlobalValue* p2)
-{
- return strcmp(p1->name, p2->name);
-}
-
static int ModCompare(const ModuleName *mn1, const ModuleName *mn2 )
{
return strcmp( mn1->name, mn2->name );
@@ -50,18 +35,20 @@ static int OfsCompare(const ModuleName *mn1, const ModuleName *mn2 )
return ( mn1->ofs - mn2->ofs );
}
+static int stringCompare2(const char* p1, const char* p2)
+{ return strcmp(p1, p2);
+}
+
CDb3Base::CDb3Base(const TCHAR* tszFileName) :
m_hDbFile(INVALID_HANDLE_VALUE),
m_safetyMode(true),
m_bReadOnly(true),
- m_lSettings(100, stringCompare),
- m_lContacts(50, LIST<DBCachedContactValueList>::FTSortFunc(HandleKeySort)),
- m_lGlobalSettings(50, compareGlobals),
- m_lResidentSettings(50, stringCompare2),
m_lMods(50, ModCompare),
- m_lOfs(50, OfsCompare)
+ m_lOfs(50, OfsCompare),
+ m_lResidentSettings(50, stringCompare2)
{
m_tszProfileName = mir_tstrdup(tszFileName);
+ InitDbInstance(this);
InitializeCriticalSection(&m_csDbAccess);
@@ -70,17 +57,11 @@ CDb3Base::CDb3Base(const TCHAR* tszFileName) :
m_ChunkSize = sinf.dwAllocationGranularity;
m_codePage = CallService(MS_LANGPACK_GETCODEPAGE, 0, 0);
- m_hCacheHeap = HeapCreate(0, 0, 0);
m_hModHeap = HeapCreate(0,0,0);
}
CDb3Base::~CDb3Base()
{
- // destroy settings
- HeapDestroy(m_hCacheHeap);
- m_lContacts.destroy();
- m_lSettings.destroy();
- m_lGlobalSettings.destroy();
m_lResidentSettings.destroy();
// destroy modules
@@ -108,6 +89,7 @@ CDb3Base::~CDb3Base()
DeleteCriticalSection(&m_csDbAccess);
+ DestroyDbInstance(this);
mir_free(m_tszProfileName);
}
diff --git a/plugins/Db3x_mmap/src/dbintf.h b/plugins/Db3x_mmap/src/dbintf.h
index d5bef059ef..a810b36876 100644
--- a/plugins/Db3x_mmap/src/dbintf.h
+++ b/plugins/Db3x_mmap/src/dbintf.h
@@ -136,27 +136,6 @@ struct DBEvent
#include <poppack.h>
-struct DBCachedGlobalValue
-{
- char* name;
- DBVARIANT value;
-};
-
-struct DBCachedContactValue
-{
- char* name;
- DBVARIANT value;
- DBCachedContactValue* next;
-};
-
-struct DBCachedContactValueList
-{
- HANDLE hContact;
- HANDLE hNext;
- DBCachedContactValue* first;
- DBCachedContactValue* last;
-};
-
#define MAXCACHEDREADSIZE 65536
struct CDb3Base : public MIDatabase, public MIDatabaseChecker, public MZeroedObject
@@ -255,6 +234,7 @@ public:
protected:
DWORD m_dwFileSize;
+ HANDLE hSettingChangeEvent, hContactDeletedEvent, hContactAddedEvent;
CRITICAL_SECTION m_csDbAccess;
@@ -272,34 +252,14 @@ protected:
int m_codePage;
- HANDLE m_hCacheHeap;
- HANDLE m_hLastCachedContact;
- char* m_lastSetting;
- DBCachedContactValueList *m_lastVL;
-
- LIST<DBCachedContactValueList> m_lContacts;
- LIST<DBCachedGlobalValue> m_lGlobalSettings;
- LIST<char> m_lSettings, m_lResidentSettings;
- HANDLE hSettingChangeEvent, hContactDeletedEvent, hContactAddedEvent;
-
- char* InsertCachedSetting(const char* szName, size_t cbNameLen);
- char* GetCachedSetting(const char *szModuleName,const char *szSettingName, int moduleNameLen, int settingNameLen);
- void SetCachedVariant(DBVARIANT* s, DBVARIANT* d);
- void FreeCachedVariant(DBVARIANT* V);
- DBVARIANT* GetCachedValuePtr(HANDLE hContact, char* szSetting, int bAllocate);
- int GetContactSettingWorker(HANDLE hContact,DBCONTACTGETSETTING *dbcgs,int isStatic);
-
- ////////////////////////////////////////////////////////////////////////////
- // contacts
-
- DBCachedContactValueList* AddToCachedContactList(HANDLE hContact, int index);
-
////////////////////////////////////////////////////////////////////////////
// modules
HANDLE m_hModHeap;
LIST<ModuleName> m_lMods, m_lOfs;
+ LIST<char> m_lResidentSettings;
HANDLE hEventAddedEvent, hEventDeletedEvent, hEventFilterAddedEvent;
+ HANDLE m_hLastCachedContact;
ModuleName *m_lastmn;
void AddToList(char *name, DWORD len, DWORD ofs);
@@ -320,6 +280,7 @@ protected:
DWORD ConvertModuleNameOfs(DWORD ofsOld);
void ConvertOldEvent(DBEvent*& dbei);
+ int GetContactSettingWorker(HANDLE hContact,DBCONTACTGETSETTING *dbcgs,int isStatic);
int WorkSettingsChain(DWORD ofsContact, DBContact *dbc, int firstTime);
int WorkEventChain(DWORD ofsContact, DBContact *dbc, int firstTime);
diff --git a/plugins/Db3x_mmap/src/dbsettings.cpp b/plugins/Db3x_mmap/src/dbsettings.cpp
index fedc5f60d2..872d482e27 100644
--- a/plugins/Db3x_mmap/src/dbsettings.cpp
+++ b/plugins/Db3x_mmap/src/dbsettings.cpp
@@ -24,7 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "commonheaders.h"
DWORD GetModuleNameOfs(const char *szName);
-DBCachedContactValueList* AddToCachedContactList(HANDLE hContact, int index);
+DBCachedContact* AddToCachedContactList(HANDLE hContact, int index);
int DBPreset_QuerySetting(const char *szModule, const char *szSetting, DBVARIANT *dbv, BOOL isStatic);
@@ -35,154 +35,6 @@ DWORD __forceinline GetSettingValueLength(PBYTE pSetting)
return pSetting[0];
}
-char* CDb3Base::InsertCachedSetting(const char* szName, size_t cbNameLen)
-{
- char* newValue = (char*)HeapAlloc(m_hCacheHeap, 0, cbNameLen);
- *newValue = 0;
- strcpy(newValue+1, szName+1);
- m_lSettings.insert(newValue);
- return newValue;
-}
-
-char* CDb3Base::GetCachedSetting(const char *szModuleName,const char *szSettingName, int moduleNameLen, int settingNameLen)
-{
- char szFullName[512];
- strcpy(szFullName+1,szModuleName);
- szFullName[moduleNameLen+1] = '/';
- strcpy(szFullName+moduleNameLen+2,szSettingName);
-
- if (m_lastSetting && strcmp(szFullName+1, m_lastSetting) == 0)
- return m_lastSetting;
-
- int index = m_lSettings.getIndex(szFullName);
- if (index != -1)
- m_lastSetting = m_lSettings[index]+1;
- else
- m_lastSetting = InsertCachedSetting( szFullName, settingNameLen+moduleNameLen+3)+1;
-
- return m_lastSetting;
-}
-
-void CDb3Base::SetCachedVariant( DBVARIANT* s /* new */, DBVARIANT* d /* cached */ )
-{
- char* szSave = ( d->type == DBVT_UTF8 || d->type == DBVT_ASCIIZ ) ? d->pszVal : NULL;
-
- memcpy( d, s, sizeof( DBVARIANT ));
- if (( s->type == DBVT_UTF8 || s->type == DBVT_ASCIIZ ) && s->pszVal != NULL ) {
- if ( szSave != NULL )
- d->pszVal = (char*)HeapReAlloc(m_hCacheHeap,0,szSave,strlen(s->pszVal)+1);
- else
- d->pszVal = (char*)HeapAlloc(m_hCacheHeap,0,strlen(s->pszVal)+1);
- strcpy(d->pszVal,s->pszVal);
- }
- else if ( szSave != NULL )
- HeapFree(m_hCacheHeap,0,szSave);
-
-#ifdef DBLOGGING
- switch( d->type ) {
- case DBVT_BYTE: log1( "set cached byte: %d", d->bVal ); break;
- case DBVT_WORD: log1( "set cached word: %d", d->wVal ); break;
- case DBVT_DWORD: log1( "set cached dword: %d", d->dVal ); break;
- case DBVT_UTF8:
- case DBVT_ASCIIZ: log1( "set cached string: '%s'", d->pszVal ); break;
- default: log1( "set cached crap: %d", d->type ); break;
- }
-#endif
-}
-
-void CDb3Base::FreeCachedVariant( DBVARIANT* V )
-{
- if (( V->type == DBVT_ASCIIZ || V->type == DBVT_UTF8 ) && V->pszVal != NULL )
- HeapFree(m_hCacheHeap,0,V->pszVal);
-}
-
-DBVARIANT* CDb3Base::GetCachedValuePtr( HANDLE hContact, char* szSetting, int bAllocate )
-{
- if ( hContact == 0 ) {
- DBCachedGlobalValue Vtemp, *V;
- Vtemp.name = szSetting;
- int index = m_lGlobalSettings.getIndex(&Vtemp);
- if (index != -1) {
- V = m_lGlobalSettings[index];
- if ( bAllocate == -1 ) {
- FreeCachedVariant( &V->value );
- m_lGlobalSettings.remove(index);
- HeapFree(m_hCacheHeap,0,V);
- return NULL;
- }
- }
- else {
- if ( bAllocate != 1 )
- return NULL;
-
- V = (DBCachedGlobalValue*)HeapAlloc(m_hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedGlobalValue));
- V->name = szSetting;
- m_lGlobalSettings.insert(V);
- }
-
- return &V->value;
- }
- else {
- DBCachedContactValue *V, *V1;
- DBCachedContactValueList VLtemp,*VL;
-
- if (m_hLastCachedContact == hContact && m_lastVL)
- VL = m_lastVL;
- else {
- VLtemp.hContact = hContact;
-
- int index = m_lContacts.getIndex(&VLtemp);
- if (index == -1) {
- if ( bAllocate != 1 )
- return NULL;
-
- VL = AddToCachedContactList(hContact, index);
- }
- else VL = m_lContacts[index];
-
- m_lastVL = VL;
- m_hLastCachedContact = hContact;
- }
-
- for ( V = VL->first; V != NULL; V = V->next)
- if (V->name == szSetting)
- break;
-
- if ( V == NULL ) {
- if ( bAllocate != 1 )
- return NULL;
-
- V = (DBCachedContactValue *)HeapAlloc(m_hCacheHeap, HEAP_ZERO_MEMORY, sizeof(DBCachedContactValue));
- if (VL->last)
- VL->last->next = V;
- else
- VL->first = V;
- VL->last = V;
- V->name = szSetting;
- }
- else if ( bAllocate == -1 ) {
- m_lastVL = NULL;
- FreeCachedVariant(&V->value);
- if ( VL->first == V ) {
- VL->first = V->next;
- if (VL->last == V)
- VL->last = V->next; // NULL
- }
- else
- for ( V1 = VL->first; V1 != NULL; V1 = V1->next )
- if ( V1->next == V ) {
- V1->next = V->next;
- if (VL->last == V)
- VL->last = V1;
- break;
- }
- HeapFree(m_hCacheHeap,0,V);
- return NULL;
- }
-
- return &V->value;
-} }
-
#define NeedBytes(n) if (bytesRemaining<(n)) pBlob = (PBYTE)DBRead(ofsBlobPtr,(n),&bytesRemaining)
#define MoveAlong(n) {int x = n; pBlob += (x); ofsBlobPtr += (x); bytesRemaining -= (x);}
#define VLT(n) ((n == DBVT_UTF8)?DBVT_ASCIIZ:n)
@@ -219,9 +71,9 @@ int CDb3Base::GetContactSettingWorker(HANDLE hContact,DBCONTACTGETSETTING *dbcgs
log3("get [%08p] %s/%s",hContact,dbcgs->szModule,dbcgs->szSetting);
- szCachedSettingName = GetCachedSetting(dbcgs->szModule,dbcgs->szSetting,moduleNameLen,settingNameLen);
+ szCachedSettingName = m_cache->GetCachedSetting(dbcgs->szModule,dbcgs->szSetting,moduleNameLen,settingNameLen);
{
- DBVARIANT* pCachedValue = GetCachedValuePtr( hContact, szCachedSettingName, 0 );
+ DBVARIANT* pCachedValue = m_cache->GetCachedValuePtr(hContact, szCachedSettingName, 0);
if ( pCachedValue != NULL ) {
if ( pCachedValue->type == DBVT_ASCIIZ || pCachedValue->type == DBVT_UTF8 ) {
int cbOrigLen = dbcgs->pValue->cchVal;
@@ -320,9 +172,9 @@ int CDb3Base::GetContactSettingWorker(HANDLE hContact,DBCONTACTGETSETTING *dbcgs
/**** add to cache **********************/
if ( dbcgs->pValue->type != DBVT_BLOB ) {
- DBVARIANT* pCachedValue = GetCachedValuePtr( hContact, szCachedSettingName, 1 );
+ DBVARIANT* pCachedValue = m_cache->GetCachedValuePtr( hContact, szCachedSettingName, 1 );
if ( pCachedValue != NULL )
- SetCachedVariant(dbcgs->pValue,pCachedValue);
+ m_cache->SetCachedVariant(dbcgs->pValue, pCachedValue);
}
logg();
@@ -351,7 +203,7 @@ int CDb3Base::GetContactSettingWorker(HANDLE hContact,DBCONTACTGETSETTING *dbcgs
/**** add missing setting to cache **********************/
if ( dbcgs->pValue->type != DBVT_BLOB )
{
- DBVARIANT* pCachedValue = GetCachedValuePtr( hContact, szCachedSettingName, 1 );
+ DBVARIANT* pCachedValue = m_cache->GetCachedValuePtr( hContact, szCachedSettingName, 1 );
if ( pCachedValue != NULL )
pCachedValue->type = DBVT_DELETED;
}
@@ -479,22 +331,13 @@ STDMETHODIMP_(BOOL) CDb3Base::FreeVariant(DBVARIANT *dbv)
STDMETHODIMP_(BOOL) CDb3Base::SetSettingResident(BOOL bIsResident, const char *pszSettingName)
{
- size_t cbSettingNameLen = strlen(pszSettingName) + 2;
+ int cbSettingNameLen = (int)strlen(pszSettingName) + 2;
if (cbSettingNameLen < 512) {
- char* szSetting;
- char szTemp[512];
- strcpy( szTemp+1, pszSettingName);
-
- mir_cslock lck(m_csDbAccess);
- int idx = m_lSettings.getIndex(szTemp);
- if (idx == -1)
- szSetting = InsertCachedSetting( szTemp, cbSettingNameLen);
- else
- szSetting = m_lSettings[idx];
-
+ char *szSetting = m_cache->InsertCachedSetting(pszSettingName, cbSettingNameLen);
*szSetting = (char)bIsResident;
- idx = m_lResidentSettings.getIndex(szSetting+1);
+ mir_cslock lck(m_csDbAccess);
+ int idx = m_lResidentSettings.getIndex(szSetting+1);
if (idx == -1) {
if (bIsResident)
m_lResidentSettings.insert(szSetting+1);
@@ -574,9 +417,9 @@ STDMETHODIMP_(BOOL) CDb3Base::WriteContactSetting(HANDLE hContact, DBCONTACTWRIT
mir_cslockfull lck(m_csDbAccess);
- char* szCachedSettingName = GetCachedSetting(tmp.szModule, tmp.szSetting, moduleNameLen, settingNameLen);
+ char* szCachedSettingName = m_cache->GetCachedSetting(tmp.szModule, tmp.szSetting, moduleNameLen, settingNameLen);
if ( tmp.value.type != DBVT_BLOB ) {
- DBVARIANT* pCachedValue = GetCachedValuePtr(hContact, szCachedSettingName, 1);
+ DBVARIANT* pCachedValue = m_cache->GetCachedValuePtr(hContact, szCachedSettingName, 1);
if ( pCachedValue != NULL ) {
BOOL bIsIdentical = FALSE;
if ( pCachedValue->type == tmp.value.type ) {
@@ -590,7 +433,7 @@ STDMETHODIMP_(BOOL) CDb3Base::WriteContactSetting(HANDLE hContact, DBCONTACTWRIT
if ( bIsIdentical )
return 0;
}
- SetCachedVariant(&tmp.value, pCachedValue);
+ m_cache->SetCachedVariant(&tmp.value, pCachedValue);
}
if ( szCachedSettingName[-1] != 0 ) {
lck.unlock();
@@ -598,7 +441,7 @@ STDMETHODIMP_(BOOL) CDb3Base::WriteContactSetting(HANDLE hContact, DBCONTACTWRIT
return 0;
}
}
- else GetCachedValuePtr(hContact, szCachedSettingName, -1);
+ else m_cache->GetCachedValuePtr(hContact, szCachedSettingName, -1);
ofsModuleName = GetModuleNameOfs(tmp.szModule);
if (hContact == 0) ofsContact = m_dbHeader.ofsUser;
@@ -851,8 +694,8 @@ STDMETHODIMP_(BOOL) CDb3Base::DeleteContactSetting(HANDLE hContact, DBCONTACTGET
}
DBMoveChunk(ofsSettingToCut,ofsSettingToCut+nameLen+valLen,ofsBlobPtr+1-ofsSettingToCut);
- szCachedSettingName = GetCachedSetting(dbcgs->szModule,dbcgs->szSetting,moduleNameLen,settingNameLen);
- GetCachedValuePtr((HANDLE)saveWparam, szCachedSettingName, -1 );
+ szCachedSettingName = m_cache->GetCachedSetting(dbcgs->szModule,dbcgs->szSetting,moduleNameLen,settingNameLen);
+ m_cache->GetCachedValuePtr((HANDLE)saveWparam, szCachedSettingName, -1 );
//quit
DBFlush(1);
diff --git a/plugins/Dbx_tree/DataBase.cpp b/plugins/Dbx_tree/DataBase.cpp
index 033e472c9d..50fe494b3c 100644
--- a/plugins/Dbx_tree/DataBase.cpp
+++ b/plugins/Dbx_tree/DataBase.cpp
@@ -31,12 +31,13 @@ CDataBase *gDataBase = NULL;
CDataBase::CDataBase(const TCHAR *FileName)
{
- int len = _tcslen(FileName);
+ InitDbInstance(this);
+
+ size_t len = _tcslen(FileName);
m_FileName[0] = new TCHAR[len + 1];
_tcsncpy_s(m_FileName[0], len + 1, FileName, len);
m_FileName[0][len] = 0;
-
TCHAR * tmp = _tcsrchr(m_FileName[0], '.');
if (tmp)
{
@@ -62,6 +63,7 @@ CDataBase::CDataBase(const TCHAR *FileName)
m_Entities = NULL;
m_Settings = NULL;
m_Events = NULL;
+
}
CDataBase::~CDataBase()
{
@@ -85,8 +87,9 @@ CDataBase::~CDataBase()
delete [] (m_FileName[i]);
}
-
+ DestroyDbInstance(this);
}
+
int CDataBase::CreateDB()
{
/// TODO: create and show wizard
diff --git a/src/miranda32_10.vcxproj b/src/miranda32_10.vcxproj
index ca0f8ffa35..5707d30e91 100644
--- a/src/miranda32_10.vcxproj
+++ b/src/miranda32_10.vcxproj
@@ -244,6 +244,7 @@
<ClInclude Include="core\commonheaders.h" />
<ClInclude Include="core\miranda.h" />
<ClInclude Include="core\stdplug.h" />
+ <ClInclude Include="modules\database\database.h" />
<ClInclude Include="modules\database\profilemanager.h" />
<ClInclude Include="modules\findadd\findadd.h" />
<ClInclude Include="modules\json\internalJSONNode.h" />
@@ -299,6 +300,9 @@
<ClCompile Include="modules\database\dbutils.cpp">
<PrecompiledHeaderFile>..\..\core\commonheaders.h</PrecompiledHeaderFile>
</ClCompile>
+ <ClCompile Include="modules\database\mdatabasecache.cpp">
+ <PrecompiledHeaderFile>..\..\core\commonheaders.h</PrecompiledHeaderFile>
+ </ClCompile>
<ClCompile Include="modules\database\profilemanager.cpp">
<PrecompiledHeaderFile>..\..\core\commonheaders.h</PrecompiledHeaderFile>
</ClCompile>
diff --git a/src/miranda32_10.vcxproj.filters b/src/miranda32_10.vcxproj.filters
index dd95088c4f..fb7f03cd6e 100644
--- a/src/miranda32_10.vcxproj.filters
+++ b/src/miranda32_10.vcxproj.filters
@@ -270,6 +270,9 @@
<ClInclude Include="..\include\m_db_int.h">
<Filter>Modules\database</Filter>
</ClInclude>
+ <ClInclude Include="modules\database\database.h">
+ <Filter>Modules\database</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="core\commonheaders.cpp">
@@ -572,6 +575,9 @@
<ClCompile Include="modules\clist\contacts.cpp">
<Filter>Modules\clist</Filter>
</ClCompile>
+ <ClCompile Include="modules\database\mdatabasecache.cpp">
+ <Filter>Modules\database</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="resource.rc">
diff --git a/src/modules/database/database.h b/src/modules/database/database.h
new file mode 100644
index 0000000000..b0b5717e0b
--- /dev/null
+++ b/src/modules/database/database.h
@@ -0,0 +1,49 @@
+/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright 2012 Miranda NG project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+class MDatabaseCache : public MIDatabaseCache, public MZeroedObject
+{
+ HANDLE m_hCacheHeap;
+ char* m_lastSetting;
+ DBCachedContact *m_lastVL;
+
+ LIST<DBCachedContact> m_lContacts;
+ LIST<DBCachedGlobalValue> m_lGlobalSettings;
+ LIST<char> m_lSettings;
+
+ void FreeCachedVariant(DBVARIANT* V);
+
+public:
+ MDatabaseCache();
+ ~MDatabaseCache();
+
+protected:
+ STDMETHODIMP_(DBCachedContact*) AddContactToCache(HANDLE hContact);
+ STDMETHODIMP_(DBCachedContact*) GetCachedContact(HANDLE hContact);
+ STDMETHODIMP_(void) FreeCachedContact(HANDLE hContact);
+
+ STDMETHODIMP_(char*) InsertCachedSetting(const char *szName, int);
+ STDMETHODIMP_(char*) GetCachedSetting(const char *szModuleName, const char *szSettingName, int, int);
+ STDMETHODIMP_(void) SetCachedVariant(DBVARIANT *s, DBVARIANT *d);
+ STDMETHODIMP_(DBVARIANT*) GetCachedValuePtr(HANDLE hContact, char *szSetting, int bAllocate);
+};
diff --git a/src/modules/database/dbintf.cpp b/src/modules/database/dbintf.cpp
index 6c6371e6ec..da83e284d2 100644
--- a/src/modules/database/dbintf.cpp
+++ b/src/modules/database/dbintf.cpp
@@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "..\..\core\commonheaders.h"
+#include "database.h"
MIDatabase *currDb = NULL;
DATABASELINK *currDblink = NULL;
@@ -191,6 +192,24 @@ static INT_PTR srvGetCurrentDb(WPARAM wParam,LPARAM lParam)
return (INT_PTR)currDb;
}
+static INT_PTR srvInitInstance(WPARAM wParam,LPARAM lParam)
+{
+ MIDatabase* pDb = (MIDatabase*)lParam;
+ if (pDb != NULL)
+ pDb->m_cache = new MDatabaseCache();
+ return 0;
+}
+
+static INT_PTR srvDestroyInstance(WPARAM wParam,LPARAM lParam)
+{
+ MIDatabase* pDb = (MIDatabase*)lParam;
+ if (pDb != NULL) {
+ delete pDb->m_cache;
+ pDb->m_cache = NULL;
+ }
+ return 0;
+}
+
///////////////////////////////////////////////////////////////////////////////
int LoadDbintfModule()
@@ -232,5 +251,8 @@ int LoadDbintfModule()
CreateServiceFunction(MS_DB_REGISTER_PLUGIN, srvRegisterPlugin);
CreateServiceFunction(MS_DB_FIND_PLUGIN, srvFindPlugin);
CreateServiceFunction(MS_DB_GET_CURRENT, srvGetCurrentDb);
+
+ CreateServiceFunction(MS_DB_INIT_INSTANCE, srvInitInstance);
+ CreateServiceFunction(MS_DB_DESTROY_INSTANCE, srvDestroyInstance);
return 0;
}
diff --git a/src/modules/database/mdatabasecache.cpp b/src/modules/database/mdatabasecache.cpp
new file mode 100644
index 0000000000..abb24dd0fe
--- /dev/null
+++ b/src/modules/database/mdatabasecache.cpp
@@ -0,0 +1,233 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2010 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "..\..\core\commonheaders.h"
+#include "database.h"
+
+static int stringCompare(const char* p1, const char* p2)
+{ return strcmp(p1+1, p2+1);
+}
+
+static int compareGlobals(const DBCachedGlobalValue* p1, const DBCachedGlobalValue* p2)
+{ return strcmp(p1->name, p2->name);
+}
+
+MDatabaseCache::MDatabaseCache() :
+ m_lSettings(100, stringCompare),
+ m_lContacts(50, LIST<DBCachedContact>::FTSortFunc(HandleKeySort)),
+ m_lGlobalSettings(50, compareGlobals)
+{
+ m_hCacheHeap = HeapCreate(0, 0, 0);
+}
+
+MDatabaseCache::~MDatabaseCache()
+{
+ HeapDestroy(m_hCacheHeap);
+ m_lContacts.destroy();
+ m_lSettings.destroy();
+ m_lGlobalSettings.destroy();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+DBCachedContact* MDatabaseCache::AddContactToCache(HANDLE hContact)
+{
+ DBCachedContact* VL = (DBCachedContact*)HeapAlloc(m_hCacheHeap, HEAP_ZERO_MEMORY, sizeof(DBCachedContact));
+ VL->hContact = hContact;
+ m_lContacts.insert(VL);
+ return VL;
+}
+
+DBCachedContact* MDatabaseCache::GetCachedContact(HANDLE hContact)
+{
+ DBCachedContact VLtemp = { hContact };
+ int index = m_lContacts.getIndex(&VLtemp);
+ return (index == -1) ? NULL : m_lContacts[index];
+}
+
+void MDatabaseCache::FreeCachedContact(HANDLE hContact)
+{
+ DBCachedContact VLtemp = { hContact };
+ int index = m_lContacts.getIndex(&VLtemp);
+ if (index == -1)
+ return;
+
+ DBCachedContact* VL = m_lContacts[index];
+ DBCachedContactValue* V = VL->first;
+ while (V != NULL) {
+ DBCachedContactValue* V1 = V->next;
+ FreeCachedVariant(&V->value);
+ HeapFree( m_hCacheHeap, 0, V );
+ V = V1;
+ }
+ HeapFree( m_hCacheHeap, 0, VL );
+
+ m_lContacts.remove(index);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+char* MDatabaseCache::InsertCachedSetting(const char* szName, int cbLen)
+{
+ char* newValue = (char*)HeapAlloc(m_hCacheHeap, 0, cbLen);
+ *newValue = 0;
+ strcpy(newValue+1, szName+1);
+ m_lSettings.insert(newValue);
+ return newValue;
+}
+
+char* MDatabaseCache::GetCachedSetting(const char *szModuleName,const char *szSettingName, int moduleNameLen, int settingNameLen)
+{
+ char szFullName[512];
+ strcpy(szFullName+1,szModuleName);
+ szFullName[moduleNameLen+1] = '/';
+ strcpy(szFullName+moduleNameLen+2,szSettingName);
+
+ if (m_lastSetting && strcmp(szFullName+1, m_lastSetting) == 0)
+ return m_lastSetting;
+
+ int index = m_lSettings.getIndex(szFullName);
+ if (index != -1)
+ m_lastSetting = m_lSettings[index]+1;
+ else
+ m_lastSetting = InsertCachedSetting( szFullName, settingNameLen+moduleNameLen+3)+1;
+
+ return m_lastSetting;
+}
+
+void MDatabaseCache::SetCachedVariant(DBVARIANT* s /* new */, DBVARIANT* d /* cached */ )
+{
+ char* szSave = ( d->type == DBVT_UTF8 || d->type == DBVT_ASCIIZ ) ? d->pszVal : NULL;
+
+ memcpy( d, s, sizeof( DBVARIANT ));
+ if (( s->type == DBVT_UTF8 || s->type == DBVT_ASCIIZ ) && s->pszVal != NULL ) {
+ if ( szSave != NULL )
+ d->pszVal = (char*)HeapReAlloc(m_hCacheHeap,0,szSave,strlen(s->pszVal)+1);
+ else
+ d->pszVal = (char*)HeapAlloc(m_hCacheHeap,0,strlen(s->pszVal)+1);
+ strcpy(d->pszVal,s->pszVal);
+ }
+ else if ( szSave != NULL )
+ HeapFree(m_hCacheHeap,0,szSave);
+
+#ifdef DBLOGGING
+ switch( d->type ) {
+ case DBVT_BYTE: log1( "set cached byte: %d", d->bVal ); break;
+ case DBVT_WORD: log1( "set cached word: %d", d->wVal ); break;
+ case DBVT_DWORD: log1( "set cached dword: %d", d->dVal ); break;
+ case DBVT_UTF8:
+ case DBVT_ASCIIZ: log1( "set cached string: '%s'", d->pszVal ); break;
+ default: log1( "set cached crap: %d", d->type ); break;
+ }
+#endif
+}
+
+void MDatabaseCache::FreeCachedVariant(DBVARIANT* V)
+{
+ if (( V->type == DBVT_ASCIIZ || V->type == DBVT_UTF8 ) && V->pszVal != NULL )
+ HeapFree(m_hCacheHeap,0,V->pszVal);
+}
+
+STDMETHODIMP_(DBVARIANT*) MDatabaseCache::GetCachedValuePtr(HANDLE hContact, char *szSetting, int bAllocate)
+{
+ // a global setting
+ if ( hContact == 0 ) {
+ DBCachedGlobalValue Vtemp, *V;
+ Vtemp.name = szSetting;
+ int index = m_lGlobalSettings.getIndex(&Vtemp);
+ if (index != -1) {
+ V = m_lGlobalSettings[index];
+ if ( bAllocate == -1 ) {
+ FreeCachedVariant( &V->value );
+ m_lGlobalSettings.remove(index);
+ HeapFree(m_hCacheHeap,0,V);
+ return NULL;
+ }
+ }
+ else {
+ if ( bAllocate != 1 )
+ return NULL;
+
+ V = (DBCachedGlobalValue*)HeapAlloc(m_hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedGlobalValue));
+ V->name = szSetting;
+ m_lGlobalSettings.insert(V);
+ }
+
+ return &V->value;
+ }
+
+ // a contact setting
+ DBCachedContactValue *V, *V1;
+ DBCachedContact VLtemp,*VL;
+
+ VLtemp.hContact = hContact;
+
+ int index = m_lContacts.getIndex(&VLtemp);
+ if (index == -1) {
+ if ( bAllocate != 1 )
+ return NULL;
+
+ VL = AddContactToCache(hContact);
+ }
+ else VL = m_lContacts[index];
+
+ m_lastVL = VL;
+
+ for ( V = VL->first; V != NULL; V = V->next)
+ if (V->name == szSetting)
+ break;
+
+ if ( V == NULL ) {
+ if ( bAllocate != 1 )
+ return NULL;
+
+ V = (DBCachedContactValue *)HeapAlloc(m_hCacheHeap, HEAP_ZERO_MEMORY, sizeof(DBCachedContactValue));
+ if (VL->last)
+ VL->last->next = V;
+ else
+ VL->first = V;
+ VL->last = V;
+ V->name = szSetting;
+ }
+ else if ( bAllocate == -1 ) {
+ m_lastVL = NULL;
+ FreeCachedVariant(&V->value);
+ if ( VL->first == V ) {
+ VL->first = V->next;
+ if (VL->last == V)
+ VL->last = V->next; // NULL
+ }
+ else
+ for ( V1 = VL->first; V1 != NULL; V1 = V1->next )
+ if ( V1->next == V ) {
+ V1->next = V->next;
+ if (VL->last == V)
+ VL->last = V1;
+ break;
+ }
+ HeapFree(m_hCacheHeap,0,V);
+ return NULL;
+ }
+
+ return &V->value;
+}