From 7578f068b6dd10641ced7d08d5eebb4654c4911c Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Fri, 14 Feb 2014 15:34:14 +0000 Subject: Dbx_tree moved to deprecated git-svn-id: http://svn.miranda-ng.org/main/trunk@8122 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Dbx_tree/src/BlockManager.cpp | 963 ---------------------------------- 1 file changed, 963 deletions(-) delete mode 100644 plugins/Dbx_tree/src/BlockManager.cpp (limited to 'plugins/Dbx_tree/src/BlockManager.cpp') diff --git a/plugins/Dbx_tree/src/BlockManager.cpp b/plugins/Dbx_tree/src/BlockManager.cpp deleted file mode 100644 index b6a7d22feb..0000000000 --- a/plugins/Dbx_tree/src/BlockManager.cpp +++ /dev/null @@ -1,963 +0,0 @@ -/* - -dbx_tree: tree database driver for Miranda IM - -Copyright 2007-2010 Michael "Protogenes" Kunz, - -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 "Interface.h" -#include "BlockManager.h" -#include "Logger.h" - -CBlockManager::CBlockManager( - CFileAccess & FileAccess, - CEncryptionManager & EncryptionManager - ) -: m_BlockSync(), - m_FileAccess(FileAccess), - m_EncryptionManager(EncryptionManager), - m_BlockTable(1024), - m_FreeBlocks() -{ - m_Optimize.Thread = NULL; - m_Optimize.Source = 0; - m_Optimize.Dest = 0; - - m_CacheInfo.Growth = 0; - m_CacheInfo.Size = 0; - m_CacheInfo.LastPurge = time(NULL); - - m_PendingHead = NULL; - m_PendingTail = NULL; - m_PendingLast = NULL; - m_LastFlush = time(NULL); - m_BytesPending = 20; - m_FirstFreeIndex = 0; - - m_SaveMode = true; - m_ReadOnly = m_FileAccess.ReadOnly(); - - memset(m_Cache, 0, sizeof(m_Cache)); -} - -CBlockManager::~CBlockManager() -{ - m_BlockSync.BeginWrite(); - if (m_Optimize.Thread) - { - m_Optimize.Thread->FreeOnTerminate(false); - m_Optimize.Thread->Terminate(); - - m_BlockSync.EndWrite(); - m_Optimize.Thread->WaitFor(); - - delete m_Optimize.Thread; - } else { - m_BlockSync.EndWrite(); - } - - _PendingFlush(true); - - for (uint32_t buddy = 0; buddy < cCacheBuddyCount; buddy++) - { - TCacheEntry * i = m_Cache[buddy]; - while (i) - { - free(i->Cache); - - TCacheEntry * tmp = i; - i = i->Next; - free(tmp); - } - } -} - -// Optimize File Size -void CBlockManager::ExecuteOptimize() -{ /* - TBlockHeadFree h = {0,0}; - uint8_t * buf = (uint8_t*)malloc(1 << 18); // 256kb - uint32_t bufuse = 0; - uint32_t bufsize = 1 << 18; - uint32_t lastflush = 0; - - { - int i = 0; - while (!m_Optimize.Thread->Terminated() && (i < 600)) - { - ++i; - Sleep(100); // wait for Miranda to start - } - } - - TransactionBeginWrite(); - - while (!m_Optimize.Thread->Terminated() && (m_Optimize.Source < m_FileAccess.Size()) && !m_ReadOnly) - { - m_FileAccess.Read(&h, m_Optimize.Source, sizeof(h)); - if (h.ID == cFreeBlockID) - { - _RemoveFreeBlock(m_Optimize.Source, h.Size); - - m_Optimize.Source += h.Size; - } else { - - if (bufsize < bufuse + h.Size) - { - buf = (uint8_t*)realloc(buf, bufuse + h.Size); - bufsize = bufuse + h.Size; - } - m_FileAccess.Read(buf + bufuse, m_Optimize.Source, h.Size); - - m_BlockTable[h.ID >> 2].Addr = (m_Optimize.Dest + bufuse) >> 2; - - m_Optimize.Source += h.Size; - bufuse += h.Size; - } - - if ((m_BlockSync.Waiting() > 0) - || (bufuse + 1024 >= bufsize) - || (m_Optimize.Source >= m_FileAccess.Size())) // buffer is nearly full or EOF - { - if (m_Optimize.Dest != m_Optimize.Source) // move blocks - { - TBlockHeadFree h = {cFreeBlockID, m_Optimize.Source - m_Optimize.Dest}; - TBlockTailFree t = {m_Optimize.Source - m_Optimize.Dest, cFreeBlockID}; - - m_FileAccess.Write(buf, m_Optimize.Dest, bufuse); - - m_FileAccess.Write(&h, m_Optimize.Dest + bufuse, sizeof(h)); - m_FileAccess.Invalidate(m_Optimize.Dest + bufuse + sizeof(h), m_Optimize.Source - m_Optimize.Dest - bufuse - sizeof(h) - sizeof(t)); - m_FileAccess.Write(&t, m_Optimize.Dest + bufuse - sizeof(t), sizeof(t)); - - if (m_SaveMode) - { - m_FileAccess.CloseTransaction(); - m_FileAccess.Flush(); - m_FileAccess.UseJournal(false); - - m_FileAccess.Write(buf, m_Optimize.Dest, bufuse); - - m_FileAccess.Write(&h, m_Optimize.Dest + bufuse, sizeof(h)); - m_FileAccess.Invalidate(m_Optimize.Dest + bufuse + sizeof(h), m_Optimize.Source - m_Optimize.Dest - bufuse - sizeof(h) - sizeof(t)); - m_FileAccess.Write(&t, m_Optimize.Dest + bufuse - sizeof(t), sizeof(t)); - - m_FileAccess.Flush(); - m_FileAccess.CleanJournal(); - m_FileAccess.UseJournal(true); - } - - m_Optimize.Dest += bufuse; - bufuse = 0; - } - - if (m_BlockSync.Waiting() > 0) - { - unsigned int w = m_BlockSync.Waiting(); - m_BlockSync.EndWrite(); - Sleep(w * 64 + 1); - m_BlockSync.BeginWrite(); - m_FileAccess.UseJournal(m_SaveMode); - } - } - } - - if (m_Optimize.Source >= m_FileAccess.Size()) - m_FileAccess.Size(m_Optimize.Dest); - - m_Optimize.Thread = NULL; - m_Optimize.Source = 0; - m_Optimize.Dest = 0; - if (m_SaveMode) - TransactionEndWrite(); - else - m_BlockSync.EndWrite(); - - free(buf); */ - - m_Optimize.Thread = NULL; -} - -inline void CBlockManager::_PendingAdd(uint32_t BlockID, uint32_t Addr, uint32_t Size, TCacheEntry * Cache) -{ - TPendingOperation * p = NULL; - if (BlockID == cFreeBlockID) - { - p = (TPendingOperation*)malloc(sizeof(TPendingOperation)); - - p->BlockID = cFreeBlockID; - p->Addr = Addr; - p->Size = Size; - p->CacheEntry = NULL; - p->EncryptionBuffer = NULL; - - m_BytesPending += 24 + sizeof(TBlockHeadFree) + sizeof(TBlockTailFree); - if (Addr & cPendingInvalidate) - m_BytesPending += 12; - - } else { - if (Cache->Pending) - { - p = Cache->Pending; - _PendingRemove(Cache->Pending, false); - } else { - p = (TPendingOperation*)malloc(sizeof(TPendingOperation)); - } - - p->BlockID = BlockID; - p->Addr = Addr; - p->Size = Size; - p->CacheEntry = Cache; - p->EncryptionBuffer = NULL; - - m_BytesPending += 12 + Size; - - Cache->Pending = p; - } - - p->Next = NULL; - p->Prev = m_PendingTail; - if (m_PendingTail) - m_PendingTail->Next = p; - - m_PendingTail = p; - if (!m_PendingHead) - m_PendingHead = p; -} - -inline void CBlockManager::_PendingRemove(TPendingOperation * Pending, bool Free) -{ - if (Pending->Prev) - Pending->Prev->Next = Pending->Next; - else - m_PendingHead = Pending->Next; - - if (Pending->Next) - Pending->Next->Prev = Pending->Prev; - else - m_PendingTail = Pending->Prev; - - free(Pending->EncryptionBuffer); - - if (m_PendingLast == Pending) - m_PendingLast = Pending->Prev; - - Pending->CacheEntry->Pending = NULL; - if (Free) - free(Pending); -} - -inline void CBlockManager::_PendingFlush(bool FullFlush) -{ - TPendingOperation * i = NULL; - - if (m_ReadOnly) - return; - - if (FullFlush) - { - if (m_SaveMode) - { - _PendingFlush(false); // write to journal - m_FileAccess.Flush(); - m_FileAccess.UseJournal(false); - m_FileAccess.Size(m_FileAccess.Size()); // resize real file - } else { - m_FileAccess.UseJournal(false); - } - - i = m_PendingHead; - } else if (m_PendingLast) - { - i = m_PendingLast->Next; - m_FileAccess.UseJournal(m_SaveMode); - } else { - i = m_PendingHead; - m_FileAccess.UseJournal(m_SaveMode); - } - - while (i) - { - if (i->BlockID == cFreeBlockID) - { - uint32_t addr = i->Addr & ~cPendingInvalidate; - if (addr + i->Size <= m_FileAccess.Size()) - { - TBlockHeadFree h = {cFreeBlockID, i->Size}; - TBlockTailFree t = {i->Size, cFreeBlockID}; - - m_FileAccess.Write(&h, addr, sizeof(h)); - if (i->Addr & cPendingInvalidate) - m_FileAccess.Invalidate(addr + sizeof(h), i->Size - sizeof(h) - sizeof(t)); - m_FileAccess.Write(&t, addr + i->Size - sizeof(t), sizeof(t)); - } - - } else { - - if (i->BlockID && !i->EncryptionBuffer && m_EncryptionManager.IsEncrypted(i->BlockID)) - { - i->EncryptionBuffer = (TBlockHeadOcc*) malloc(i->Size); - memcpy(i->EncryptionBuffer, i->CacheEntry->Cache, i->Size); - m_EncryptionManager.Encrypt(i->EncryptionBuffer + 1, i->Size - sizeof(TBlockHeadOcc) - sizeof(TBlockTailOcc), i->BlockID, 0); - } - - if (i->EncryptionBuffer) - { - m_FileAccess.Write(i->EncryptionBuffer, i->Addr, i->Size); - } else { - m_FileAccess.Write(i->CacheEntry->Cache, i->Addr, i->Size); - } - } - - i = i->Next; - } // while - - if (FullFlush) - { - m_FileAccess.Flush(); - if (m_SaveMode) - m_FileAccess.CleanJournal(); - - m_BytesPending = 20; - m_LastFlush = time(NULL); - - i = m_PendingHead; - while (i) - { - free(i->EncryptionBuffer); - - if (i->CacheEntry) - i->CacheEntry->Pending = NULL; - - TPendingOperation * tmp = i; - i = i->Next; - free(tmp); - } - m_PendingHead = NULL; - m_PendingTail = NULL; - m_PendingLast = NULL; - } else { - m_PendingLast = m_PendingTail; - m_FileAccess.CloseTransaction(); - } -} - -inline CBlockManager::TCacheEntry * CBlockManager::_CacheInsert(uint32_t Idx, TBlockHeadOcc * Cache, bool Virtual) -{ - TCacheEntry * res; - uint32_t myidx = ROR_32(Idx, cCacheBuddyBits); - - res = (TCacheEntry *)malloc(sizeof(TCacheEntry)); - res->Cache = Cache; - res->Pending = NULL; - res->Idx = myidx; - res->Forced = Virtual; - - TCacheEntry * volatile * last = &m_Cache[Idx % cCacheBuddyCount]; - TCacheEntry * i; - do { - i = *last; - - while (i && (i->Idx < myidx)) - { - last = &i->Next; - i = i->Next; - } - - if (i && (i->Idx == myidx)) - { - free(res); - free(Cache); - - i->LastUse = time(NULL) >> 2; - return i; - } - - res->Next = i; - - } while (i != CMPXCHG_Ptr(*last, res, i)); - - res->LastUse = time(NULL) >> 2; - - m_BlockTable[Idx].InCache = true; - if (!Virtual) - XADD_32(m_CacheInfo.Growth, res->Cache->Size); - - return res; -} - -inline CBlockManager::TCacheEntry * CBlockManager::_CacheFind(uint32_t Idx) -{ - TCacheEntry * i = m_Cache[Idx % cCacheBuddyCount]; - uint32_t myidx = ROR_32(Idx, cCacheBuddyBits); - while (i && (i->Idx < myidx)) - i = i->Next; - - if (i && (i->Idx == myidx)) - return i; - else - return NULL; -} - -inline void CBlockManager::_CacheErase(uint32_t Idx) -{ - TCacheEntry * i = m_Cache[Idx % cCacheBuddyCount]; - TCacheEntry * volatile * l = &m_Cache[Idx % cCacheBuddyCount]; - - uint32_t myidx = ROR_32(Idx, cCacheBuddyBits); - - while (i->Idx < myidx) - { - l = &i->Next; - i = i->Next; - } - *l = i->Next; - - free(i->Cache); - free(i); -} - -inline void CBlockManager::_CachePurge() -{ - _PendingFlush(true); - - uint32_t ts = time(NULL); - if (m_CacheInfo.Size + m_CacheInfo.Growth > cCachePurgeSize) { - ts = ts - (ts - m_CacheInfo.LastPurge) * cCachePurgeSize / (m_CacheInfo.Size + 2 * m_CacheInfo.Growth); - } else if (m_CacheInfo.Growth > m_CacheInfo.Size) - { - ts = ts - (ts - m_CacheInfo.LastPurge) * m_CacheInfo.Size / m_CacheInfo.Growth; - } else if (m_CacheInfo.Size > m_CacheInfo.Growth) - { - ts = ts - (ts - m_CacheInfo.LastPurge) * m_CacheInfo.Growth / m_CacheInfo.Size; - } else { - ts = m_CacheInfo.LastPurge; - } - - m_CacheInfo.Size += m_CacheInfo.Growth; - m_CacheInfo.Growth = 0; - m_CacheInfo.LastPurge = time(NULL); - - for (uint32_t buddy = 0; buddy < cCacheBuddyCount; buddy++) - { - TCacheEntry * i = m_Cache[buddy]; - TCacheEntry * volatile * l = &m_Cache[buddy]; - - while (i) - { - if (!i->Forced && !i->KeepInCache && i->Idx && ((i->LastUse << 2) < ts)) - { - uint32_t idx = ROL_32(i->Idx, cCacheBuddyBits); - m_CacheInfo.Size -= i->Cache->Size; - m_BlockTable[idx].InCache = false; - free(i->Cache); - - *l = i->Next; - TCacheEntry * tmp = i; - i = i->Next; - free(tmp); - - } else { - l = &i->Next; - i = i->Next; - } - } - } -} - -inline uint32_t CBlockManager::_GetAvailableIndex() -{ - uint32_t id; - if (m_FirstFreeIndex) - { - id = m_FirstFreeIndex; - m_FirstFreeIndex = m_BlockTable[id].Addr; - TBlockTableEntry b = {false, false, 0}; - m_BlockTable[id] = b; - } else { - id = static_cast(m_BlockTable.size()); - if (id > (1 << 12)) - m_BlockTable.resize(id + (1 << 12)); - else - m_BlockTable.resize(id * 2); - - for (uint32_t i = static_cast(m_BlockTable.size() - 1); i > id; --i) - { - TBlockTableEntry b = {true, true, m_FirstFreeIndex}; - m_BlockTable[i] = b; - m_FirstFreeIndex = i; - } - } - return id; -} - -inline void CBlockManager::_InsertFreeBlock(uint32_t Addr, uint32_t Size, bool InvalidateData, bool Reuse) -{ - if (Addr + Size == m_FileAccess.Size()) - { - if (Reuse) // in FindFreePosition we would want to use that block - m_FileAccess.Size(Addr); - } else { - - if (Reuse) - m_FreeBlocks.insert(std::make_pair(Size, Addr)); - - if (!m_ReadOnly) - _PendingAdd(cFreeBlockID, InvalidateData ? Addr | cPendingInvalidate : Addr, Size, NULL); - - } -} - -inline void CBlockManager::_RemoveFreeBlock(uint32_t Addr, uint32_t Size) -{ - TFreeBlockMap::iterator i = m_FreeBlocks.find(Size); - while ((i != m_FreeBlocks.end()) && (i->first == Size)) - { - if (i->second == Addr) - { - m_FreeBlocks.erase(i); - i = m_FreeBlocks.end(); - } else { - ++i; - } - } -} - -inline uint32_t CBlockManager::_FindFreePosition(uint32_t Size) -{ - // try to find free block - TFreeBlockMap::iterator f; - TFreeBlockMap::iterator e = m_FreeBlocks.end(); - - if (m_FreeBlocks.size()) - { - f = m_FreeBlocks.find(Size); - if (f == e) - { - if (m_FreeBlocks.rbegin()->first > Size * 2) - { - f = m_FreeBlocks.end(); - --f; - } - } - } else { - f = e; - } - - uint32_t addr = 0; - - if (f == e) // no block found - expand file - { - addr = m_FileAccess.Size(); - m_FileAccess.Size(addr + Size); - - } else { - addr = f->second; - - if (f->first != Size) - { - _InsertFreeBlock(addr + Size, f->first - Size, false, true); - } - _InsertFreeBlock(addr, Size, false, false); - - m_FreeBlocks.erase(f); - } - - return addr; -} - -inline bool CBlockManager::_InitOperation(uint32_t BlockID, uint32_t & Addr, TCacheEntry * & Cache) -{ - if (!BlockID || (BlockID & 3) || ((BlockID >> 2) >= m_BlockTable.size())) - return false; - - uint32_t idx = BlockID >> 2; - TBlockTableEntry dat = m_BlockTable[idx]; - - if (dat.Deleted) // deleted or FreeIDList item - return false; - - Addr = dat.Addr << 2; - if (dat.InCache) - { - Cache = _CacheFind(idx); - } else if (Addr) - { - TBlockHeadOcc h; - - m_FileAccess.Read(&h, Addr, sizeof(h)); - - TBlockHeadOcc * block = (TBlockHeadOcc *) malloc(h.Size); - m_FileAccess.Read(block, Addr, h.Size); - - m_EncryptionManager.Decrypt(block + 1, h.Size - sizeof(TBlockHeadOcc) - sizeof(TBlockTailOcc), BlockID, 0); - - Cache = _CacheInsert(idx, block, false); - } else { - return false; - } - - return Cache != NULL; -} - -inline void CBlockManager::_UpdateBlock(uint32_t BlockID, TCacheEntry * CacheEntry, uint32_t Addr) -{ - CacheEntry->KeepInCache = m_ReadOnly; - - if (!CacheEntry->Forced) - { - if (!m_ReadOnly) - _PendingAdd(BlockID, Addr, CacheEntry->Cache->Size, CacheEntry); - } -} - - -uint32_t CBlockManager::ScanFile(uint32_t FirstBlockStart, uint32_t HeaderSignature, uint32_t FileSize) -{ - TBlockHeadOcc h, lasth = {0, 0, 0}; - uint32_t p; - uint32_t res = 0; - bool invalidateblock = false; - - p = FirstBlockStart; - m_FirstBlockStart = FirstBlockStart; - m_Optimize.Source = 0; - m_Optimize.Dest = 0; - - { // insert header cache element - void * header = malloc(FirstBlockStart); - m_FileAccess.Read(header, 0, FirstBlockStart); - _CacheInsert(0, (TBlockHeadOcc*)header, false); - } - - TransactionBeginWrite(); - - while (p < FileSize) - { - m_FileAccess.Read(&h, p, sizeof(h)); - if (CLogger::Instance().Level() >= CLogger::logERROR || !h.Size) - { - LOG(logCRITICAL, _T("Block-structure of file is corrupt!")); - return 0; - } - - if (h.ID == cFreeBlockID) - { - if (m_Optimize.Dest == 0) - m_Optimize.Dest = p; - - if (lasth.ID == cFreeBlockID) - { - lasth.Size += h.Size; - invalidateblock = true; - } else { - lasth = h; - } - - } else { - - if (lasth.ID == cFreeBlockID) - { - if (m_Optimize.Source == 0) - m_Optimize.Source = p; - - _InsertFreeBlock(p - lasth.Size, lasth.Size, invalidateblock, true); - } - lasth = h; - invalidateblock = false; - - while ((h.ID >> 2) >= m_BlockTable.size()) - m_BlockTable.resize(m_BlockTable.size() << 1); - - m_BlockTable[h.ID >> 2].Addr = p >> 2; - - if (h.Signature == HeaderSignature) - res = h.ID; - } - - p = p + h.Size; - } - - m_FirstFreeIndex = 0; - for (uint32_t i = static_cast(m_BlockTable.size() - 1); i > 0; --i) - { - if (m_BlockTable[i].Addr == 0) - { - TBlockTableEntry b = {true, true, m_FirstFreeIndex}; - m_BlockTable[i] = b; - m_FirstFreeIndex = i; - } - } - - TransactionEndWrite(); - - if (m_Optimize.Source && !m_FileAccess.ReadOnly()) - { - m_Optimize.Thread = new COptimizeThread(*this); - m_Optimize.Thread->Priority(CThread::tpLowest); - m_Optimize.Thread->FreeOnTerminate(true); - m_Optimize.Thread->Resume(); - } - - return res; -} - -void * CBlockManager::_CreateBlock(uint32_t & BlockID, const uint32_t Signature, uint32_t Size) -{ - uint32_t idx = _GetAvailableIndex(); - BlockID = idx << 2; - - Size = m_EncryptionManager.AlignSize(BlockID, (Size + 3) & 0xfffffffc); // align on cipher after we aligned on 4 bytes - - TBlockHeadOcc h = {BlockID, Size + sizeof(TBlockHeadOcc) + sizeof(TBlockTailOcc), Signature}; - TBlockTailOcc t = {BlockID}; - - TBlockHeadOcc * block = (TBlockHeadOcc*) malloc(Size + sizeof(h) + sizeof(t)); - *block = h; - memset(block + 1, 0, Size); - *(TBlockTailOcc*)(((uint8_t*)(block + 1)) + Size) = t; - - TCacheEntry * ce = _CacheInsert(idx, block, false); - - if (m_ReadOnly) - { - TBlockTableEntry b = {false, true, 0}; - m_BlockTable[idx] = b; - } else { - uint32_t addr = _FindFreePosition(Size + sizeof(h) + sizeof(t)); - TBlockTableEntry b = {false, true, addr >> 2 }; - m_BlockTable[idx] = b; - - _UpdateBlock(BlockID, ce, addr); - } - - return ce->Cache + 1; -} - -void * CBlockManager::_CreateBlockVirtual(uint32_t & BlockID, const uint32_t Signature, uint32_t Size) -{ - uint32_t idx = _GetAvailableIndex(); - BlockID = idx << 2; - - Size = m_EncryptionManager.AlignSize(BlockID, (Size + 3) & 0xfffffffc); // align on cipher after we aligned on 4 bytes - - TBlockHeadOcc h = {BlockID, Size + sizeof(TBlockHeadOcc) + sizeof(TBlockTailOcc), Signature}; - TBlockTailOcc t = {BlockID}; - - TBlockHeadOcc * block = (TBlockHeadOcc*) malloc(Size + sizeof(h) + sizeof(t)); - *block = h; - memset(block + 1, 0, Size); - *(TBlockTailOcc*)(((uint8_t*)(block + 1)) + Size) = t; - - return _CacheInsert(idx, block, true)->Cache + 1; -} - -bool CBlockManager::DeleteBlock(uint32_t BlockID) -{ - uint32_t idx = BlockID >> 2; - uint32_t addr; - uint32_t size; - TCacheEntry * ce; - if (!_InitOperation(BlockID, addr, ce)) - return false; - - if (!ce->Forced) - XADD_32(m_CacheInfo.Size, 0 - ce->Cache->Size); - - if (ce->Pending) - _PendingRemove(ce->Pending, true); - - size = ce->Cache->Size; - _CacheErase(idx); - - if (addr == 0) // Block in memory only - { - TBlockTableEntry b = {false, false, 0}; - m_BlockTable[idx] = b; - - } else if (m_ReadOnly) - { - m_BlockTable[idx].Deleted = true; - m_BlockTable[idx].InCache = false; - } else { - _InsertFreeBlock(addr, size, true, true); - - TBlockTableEntry b = {false, false, 0}; - m_BlockTable[idx] = b; - } - - return true; -} - -uint32_t CBlockManager::_ResizeBlock(uint32_t BlockID, void * & Buffer, uint32_t Size) -{ - uint32_t idx = BlockID >> 2; - uint32_t addr; - TCacheEntry * ce; - - if (Size == 0) - return 0; - - if (!_InitOperation(BlockID, addr, ce)) - return 0; - - Size = m_EncryptionManager.AlignSize(BlockID, (Size + 3) & 0xfffffffc); // align on cipher after we aligned on 4 bytes - - uint32_t os = ce->Cache->Size; - uint32_t ns = Size + sizeof(TBlockHeadOcc) + sizeof(TBlockTailOcc); - if (ns == ce->Cache->Size) - { - Buffer = ce->Cache + 1; - return Size; - } - - ce->Cache = (TBlockHeadOcc*) realloc(ce->Cache, ns); - ce->Cache->Size = ns; - TBlockTailOcc t = {BlockID}; - *(TBlockTailOcc*)(((uint8_t*)(ce->Cache + 1)) + Size) = t; - XADD_32(m_CacheInfo.Size, ns - os); - - Buffer = ce->Cache + 1; - ce->KeepInCache = m_ReadOnly; - - if (!m_ReadOnly && addr) - { - _InsertFreeBlock(addr, os, true, true); - addr = _FindFreePosition(ns); - m_BlockTable[idx].Addr = addr >> 2; - - _UpdateBlock(BlockID, ce, addr); // write down - } - - return Size; -} - -bool CBlockManager::IsForcedVirtual(uint32_t BlockID) -{ - TCacheEntry * ce = _CacheFind(BlockID >> 2); - return ce && ce->Forced; -} - -bool CBlockManager::WriteBlockToDisk(uint32_t BlockID) -{ - uint32_t addr; - TCacheEntry * ce; - - if (!_InitOperation(BlockID, addr, ce)) - return false; - - if (!ce->Forced) - return true; - - ce->Forced = false; - XADD_32(m_CacheInfo.Size, ce->Cache->Size); - - if (!m_ReadOnly) - { - addr = _FindFreePosition(ce->Cache->Size); - m_BlockTable[BlockID >> 2].Addr = addr >> 2; - _UpdateBlock(BlockID, ce, addr); - } - return true; -} - -bool CBlockManager::MakeBlockVirtual(uint32_t BlockID) -{ - uint32_t addr; - TCacheEntry * ce; - - if (!_InitOperation(BlockID, addr, ce)) - return false; - - if (ce->Forced) - return true; - - if (ce->Pending) // don't write down, we kill it anyway - _PendingRemove(ce->Pending, true); - - ce->Forced = true; - XADD_32(m_CacheInfo.Size, 0 - ce->Cache->Size); - - if (!m_ReadOnly) - { - _InsertFreeBlock(addr, ce->Cache->Size, true, true); - m_BlockTable[BlockID >> 2].Addr = 0; - } - return true; -} - -void * CBlockManager::_ReadBlock(uint32_t BlockID, uint32_t & Size, uint32_t & Signature) -{ - uint32_t addr; - TCacheEntry * ce; - - if ((BlockID == 0) && (Signature == -1)) - { - Size = m_FirstBlockStart; - return m_Cache[0]->Cache; - } - - if (!_InitOperation(BlockID, addr, ce)) - return NULL; - - if ((Signature != 0) && (Signature != ce->Cache->Signature)) - { - Signature = ce->Cache->Signature; - return NULL; - } - Signature = ce->Cache->Signature; - - if ((Size != 0) && (Size != ce->Cache->Size - sizeof(TBlockHeadOcc) - sizeof(TBlockTailOcc))) - { - Size = ce->Cache->Size - sizeof(TBlockHeadOcc) - sizeof(TBlockTailOcc); - return NULL; - } - Size = ce->Cache->Size - sizeof(TBlockHeadOcc) - sizeof(TBlockTailOcc); - - return ce->Cache + 1; -} - -bool CBlockManager::UpdateBlock(uint32_t BlockID, uint32_t Signature) -{ - uint32_t addr; - TCacheEntry * ce; - - if ((BlockID == 0) && (Signature == -1)) - { - if (!m_ReadOnly) - _PendingAdd(0, 0, m_FirstBlockStart, m_Cache[0]); - - return true; - } - - if (!_InitOperation(BlockID, addr, ce)) - return false; - - if (Signature) - ce->Cache->Signature = Signature; - - _UpdateBlock(BlockID, ce, addr); - - return true; -} - -// make file writeable: -// write all cached blocks to file and check for the old addresses -// remove virtual only from file -// update m_FreeBlocks along the way - -- cgit v1.2.3