summaryrefslogtreecommitdiff
path: root/plugins/Dbx_mdbx/src/dbintf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Dbx_mdbx/src/dbintf.cpp')
-rw-r--r--plugins/Dbx_mdbx/src/dbintf.cpp267
1 files changed, 149 insertions, 118 deletions
diff --git a/plugins/Dbx_mdbx/src/dbintf.cpp b/plugins/Dbx_mdbx/src/dbintf.cpp
index 7faf1328eb..d03d0ab498 100644
--- a/plugins/Dbx_mdbx/src/dbintf.cpp
+++ b/plugins/Dbx_mdbx/src/dbintf.cpp
@@ -36,6 +36,9 @@ CDbxMDBX::CDbxMDBX(const wchar_t *tszFileName, int iMode) :
CDbxMDBX::~CDbxMDBX()
{
+ if (m_curEventsSort)
+ mdbx_cursor_close(m_curEventsSort);
+
mdbx_env_close(m_env);
if (!m_bReadOnly)
@@ -51,6 +54,93 @@ CDbxMDBX::~CDbxMDBX()
/////////////////////////////////////////////////////////////////////////////////////////
+BOOL CDbxMDBX::Backup(const wchar_t *pwszPath)
+{
+ HANDLE pFile = ::CreateFile(pwszPath, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
+ if (pFile == nullptr) {
+ Netlib_Logf(0, "Backup file <%S> cannot be created", pwszPath);
+ return 1;
+ }
+
+ int res = mdbx_env_copy2fd(m_env, pFile, MDBX_CP_COMPACT);
+ if (res != MDBX_SUCCESS) {
+ Netlib_Logf(0, "CDbxMDBX::Backup: mdbx_env_copy2fd failed with error code %d", res);
+LBL_Fail:
+ CloseHandle(pFile);
+ DeleteFileW(pwszPath);
+ return res;
+ }
+
+ res = FlushFileBuffers(pFile);
+ if (res == 0) {
+ Netlib_Logf(0, "CDbxMDBX::Backup: FlushFileBuffers failed with error code %d", GetLastError());
+ goto LBL_Fail;
+ }
+
+ CloseHandle(pFile);
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+size_t iDefHeaderOffset = 0;
+BYTE bDefHeader[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+int CDbxMDBX::Check(void)
+{
+ FILE *pFile = _wfopen(m_pwszProfileName, L"rb");
+ if (pFile == nullptr)
+ return EGROKPRF_CANTREAD;
+
+ fseek(pFile, (LONG)iDefHeaderOffset, SEEK_SET);
+ BYTE buf[_countof(bDefHeader)];
+ size_t cbRead = fread(buf, 1, _countof(buf), pFile);
+ fclose(pFile);
+ if (cbRead != _countof(buf))
+ return EGROKPRF_DAMAGED;
+
+ return (memcmp(buf, bDefHeader, _countof(bDefHeader))) ? EGROKPRF_UNKHEADER : 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+BOOL CDbxMDBX::Compact()
+{
+ CMStringW wszTmpFile(FORMAT, L"%s.tmp", m_pwszProfileName.get());
+
+ mir_cslock lck(m_csDbAccess);
+ int res = Backup(wszTmpFile);
+ if (res)
+ return res;
+
+ mdbx_env_close(m_env);
+
+ DeleteFileW(m_pwszProfileName);
+ MoveFileW(wszTmpFile, m_pwszProfileName);
+
+ Map();
+ Load();
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CDbxMDBX::DBFlush(bool bForce)
+{
+ if (bForce) {
+ mir_cslock lck(m_csDbAccess);
+
+ if (m_pWriteTran) {
+ mdbx_txn_commit(m_pWriteTran);
+ m_pWriteTran = nullptr;
+ }
+ }
+ else if (m_safetyMode)
+ m_impl.m_timer.Start(50);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
int CDbxMDBX::Load()
{
MDBX_db_flags_t defFlags = MDBX_CREATE;
@@ -64,7 +154,7 @@ int CDbxMDBX::Load()
}
return EGROKPRF_DAMAGED;
}
-
+
mdbx_dbi_open(trnlck, "global", defFlags | MDBX_INTEGERKEY, &m_dbGlobal);
mdbx_dbi_open(trnlck, "crypto", defFlags, &m_dbCrypto);
mdbx_dbi_open(trnlck, "contacts", defFlags | MDBX_INTEGERKEY, &m_dbContacts);
@@ -102,18 +192,20 @@ int CDbxMDBX::Load()
}
mdbx_txn_begin(m_env, nullptr, MDBX_TXN_RDONLY, &m_txn_ro);
- mdbx_cursor_open(m_txn_ro, m_dbEvents, &m_curEvents);
- mdbx_cursor_open(m_txn_ro, m_dbEventIds, &m_curEventIds);
- mdbx_cursor_open(m_txn_ro, m_dbEventsSort, &m_curEventsSort);
- mdbx_cursor_open(m_txn_ro, m_dbSettings, &m_curSettings);
- mdbx_cursor_open(m_txn_ro, m_dbModules, &m_curModules);
- mdbx_cursor_open(m_txn_ro, m_dbContacts, &m_curContacts);
+
+ m_curEventsSort = mdbx_cursor_create(nullptr);
MDBX_val key, val;
- if (mdbx_cursor_get(m_curEvents, &key, &val, MDBX_LAST) == MDBX_SUCCESS)
- m_dwMaxEventId = *(MEVENT*)key.iov_base;
- if (mdbx_cursor_get(m_curContacts, &key, &val, MDBX_LAST) == MDBX_SUCCESS)
- m_maxContactId = *(MCONTACT*)key.iov_base;
+ {
+ cursor_ptr pCursor(m_txn_ro, m_dbEvents);
+ if (mdbx_cursor_get(pCursor, &key, &val, MDBX_LAST) == MDBX_SUCCESS)
+ m_dwMaxEventId = *(MEVENT *)key.iov_base;
+ }
+ {
+ cursor_ptr pCursor(m_txn_ro, m_dbContacts);
+ if (mdbx_cursor_get(pCursor, &key, &val, MDBX_LAST) == MDBX_SUCCESS)
+ m_maxContactId = *(MCONTACT *)key.iov_base;
+ }
mdbx_txn_reset(m_txn_ro);
@@ -127,71 +219,51 @@ int CDbxMDBX::Load()
/////////////////////////////////////////////////////////////////////////////////////////
-size_t iDefHeaderOffset = 0;
-BYTE bDefHeader[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
-int CDbxMDBX::Check(void)
+static void assert_func(const MDBX_env*, const char *msg, const char *function, unsigned line) MDBX_CXX17_NOEXCEPT
{
- FILE *pFile = _wfopen(m_pwszProfileName, L"rb");
- if (pFile == nullptr)
- return EGROKPRF_CANTREAD;
-
- fseek(pFile, (LONG)iDefHeaderOffset, SEEK_SET);
- BYTE buf[_countof(bDefHeader)];
- size_t cbRead = fread(buf, 1, _countof(buf), pFile);
- fclose(pFile);
- if (cbRead != _countof(buf))
- return EGROKPRF_DAMAGED;
+ Netlib_Logf(nullptr, "MDBX: assertion failed (%s, %d): %s", function, line, msg);
- return (memcmp(buf, bDefHeader, _countof(bDefHeader))) ? EGROKPRF_UNKHEADER : 0;
+ #if defined(_DEBUG)
+ _wassert(_A2T(msg).get(), _A2T(function).get(), line);
+ #endif
}
-/////////////////////////////////////////////////////////////////////////////////////////
-
-BOOL CDbxMDBX::Compact()
+int CDbxMDBX::Map()
{
- CMStringW wszTmpFile(FORMAT, L"%s.tmp", m_pwszProfileName.get());
-
- mir_cslock lck(m_csDbAccess);
- int res = Backup(wszTmpFile);
- if (res)
- return res;
+ if (!LockName(m_pwszProfileName))
+ return EGROKPRF_CANTREAD;
- mdbx_env_close(m_env);
+ mdbx_env_create(&m_env);
+ mdbx_env_set_maxdbs(m_env, 10);
+ mdbx_env_set_userctx(m_env, this);
+ mdbx_env_set_assert(m_env, assert_func);
- DeleteFileW(m_pwszProfileName);
- MoveFileW(wszTmpFile, m_pwszProfileName);
+#ifdef _WIN64
+ mdbx_env_set_maxreaders(m_env, 1024);
+ __int64 upperLimit = 0x400000000ul;
+#else
+ mdbx_env_set_maxreaders(m_env, 244);
+ intptr_t upperLimit = 512ul << 20;
+#endif
- Map();
- Load();
- return 0;
-}
-
-BOOL CDbxMDBX::Backup(const wchar_t *pwszPath)
-{
- HANDLE pFile = ::CreateFile(pwszPath, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
- if (pFile == nullptr) {
- Netlib_Logf(0, "Backup file <%S> cannot be created", pwszPath);
- return 1;
- }
+ int rc = mdbx_env_set_geometry(m_env,
+ -1, // minimal lower limit
+ 1ul << 20, // at least 1M for now
+ upperLimit, // 512M upper size
+ 1ul << 20, // 1M growth step
+ 512ul << 10, // 512K shrink threshold
+ -1); // default page size
+ if (rc != MDBX_SUCCESS)
+ return EGROKPRF_CANTREAD;
- int res = mdbx_env_copy2fd(m_env, pFile, MDBX_CP_COMPACT);
- if (res != MDBX_SUCCESS) {
- Netlib_Logf(0, "CDbxMDBX::Backup: mdbx_env_copy2fd failed with error code %d", res);
-LBL_Fail:
- CloseHandle(pFile);
- DeleteFileW(pwszPath);
- return res;
- }
+ MDBX_env_flags_t mode = MDBX_NOSUBDIR | MDBX_MAPASYNC | MDBX_WRITEMAP | MDBX_SAFE_NOSYNC | MDBX_COALESCE | MDBX_EXCLUSIVE;
+ if (m_bReadOnly)
+ mode |= MDBX_RDONLY;
- res = FlushFileBuffers(pFile);
- if (res == 0) {
- Netlib_Logf(0, "CDbxMDBX::Backup: FlushFileBuffers failed with error code %d", GetLastError());
- goto LBL_Fail;
- }
+ if (mdbx_env_open(m_env, _T2A(m_pwszProfileName), mode, 0664) != MDBX_SUCCESS)
+ return EGROKPRF_CANTREAD;
- CloseHandle(pFile);
- return 0;
+ return EGROKPRF_NOERROR;
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -212,51 +284,21 @@ void CDbxMDBX::SetCacheSafetyMode(BOOL bIsSet)
/////////////////////////////////////////////////////////////////////////////////////////
-static void assert_func(const MDBX_env*, const char *msg, const char *function, unsigned line) MDBX_CXX17_NOEXCEPT
+MDBX_txn* CDbxMDBX::StartTran()
{
- Netlib_Logf(nullptr, "MDBX: assertion failed (%s, %d): %s", function, line, msg);
-
- #if defined(_DEBUG)
- _wassert(_A2T(msg), _A2T(function), line);
- #endif
-}
-
-int CDbxMDBX::Map()
-{
- if (!LockName(m_pwszProfileName))
- return EGROKPRF_CANTREAD;
-
- mdbx_env_create(&m_env);
- mdbx_env_set_maxdbs(m_env, 10);
- mdbx_env_set_userctx(m_env, this);
- mdbx_env_set_assert(m_env, assert_func);
-
- #ifdef _WIN64
- mdbx_env_set_maxreaders(m_env, 1024);
- __int64 upperLimit = 0x400000000ul;
- #else
- mdbx_env_set_maxreaders(m_env, 244);
- intptr_t upperLimit = 512ul << 20;
- #endif
-
- int rc = mdbx_env_set_geometry(m_env,
- -1, // minimal lower limit
- 1ul << 20, // at least 1M for now
- upperLimit, // 512M upper size
- 1ul << 20, // 1M growth step
- 512ul << 10, // 512K shrink threshold
- -1); // default page size
- if (rc != MDBX_SUCCESS)
- return EGROKPRF_CANTREAD;
+ /*
+ mir_cslock lck(m_csDbAccess);
- MDBX_env_flags_t mode = MDBX_NOSUBDIR | MDBX_MAPASYNC | MDBX_WRITEMAP | MDBX_SAFE_NOSYNC | MDBX_COALESCE | MDBX_EXCLUSIVE;
- if (m_bReadOnly)
- mode |= MDBX_RDONLY;
+ if (m_pWriteTran == nullptr) {
+ m_dbError = mdbx_txn_begin(m_env, nullptr, (m_bReadOnly) ? MDBX_TXN_RDONLY : MDBX_TXN_READWRITE, &m_pWriteTran);
+ // FIXME: throw an exception
+ _ASSERT(m_dbError == MDBX_SUCCESS);
+ }*/
- if (mdbx_env_open(m_env, _T2A(m_pwszProfileName), mode, 0664) != MDBX_SUCCESS)
- return EGROKPRF_CANTREAD;
-
- return EGROKPRF_NOERROR;
+ MDBX_txn *res = nullptr;
+ m_dbError = mdbx_txn_begin(m_env, m_pWriteTran, (m_bReadOnly) ? MDBX_TXN_RDONLY : MDBX_TXN_READWRITE, &res);
+ _ASSERT(m_dbError == MDBX_SUCCESS);
+ return res;
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -276,17 +318,6 @@ void CDbxMDBX::TouchFile()
}
}
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CDbxMDBX::DBFlush(bool bForce)
-{
- if (bForce)
- mdbx_env_sync(m_env);
-
- else if (m_safetyMode)
- m_impl.m_timer.Start(50);
-}
-
///////////////////////////////////////////////////////////////////////////////
// MIDatabaseChecker