/* Miranda IM: the free IM client for Microsoft* Windows* Copyright 2000-2003 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 "commonheaders.h" #define CACHESECTIONSIZE 4096 #define CACHESECTIONCOUNT 32 static BOOL safetyMode = TRUE; static PBYTE pDbCache; static DWORD lastUseCounter; struct DBCacheSectionInfo { DWORD ofsBase; DWORD lastUsed; } static cacheSectionInfo[CACHESECTIONCOUNT]; static __inline int FindSectionForOffset(const DWORD ofs) { int i; for(i = 0;i= cacheSectionInfo[i].ofsBase && ofs= cacheSectionInfo[i].ofsBase && ofs= cacheSectionInfo[i].ofsBase+CACHESECTIONSIZE) //don't finish at end CopyMemory(pDbCache+i*CACHESECTIONSIZE,(PBYTE)pData+cacheSectionInfo[i].ofsBase-ofs,CACHESECTIONSIZE); else CopyMemory(pDbCache+i*CACHESECTIONSIZE,(PBYTE)pData+cacheSectionInfo[i].ofsBase-ofs,bytes-(cacheSectionInfo[i].ofsBase-ofs)); } else { //start at beginning if (ofs+bytes >= cacheSectionInfo[i].ofsBase+CACHESECTIONSIZE) //don't finish at end CopyMemory(pDbCache+i*CACHESECTIONSIZE+ofs-cacheSectionInfo[i].ofsBase,pData,cacheSectionInfo[i].ofsBase+CACHESECTIONSIZE-ofs); else CopyMemory(pDbCache+i*CACHESECTIONSIZE+ofs-cacheSectionInfo[i].ofsBase,pData,bytes); } } } } void DBMoveChunk(DWORD ofsDest,DWORD ofsSource,int bytes) { DWORD bytesRead; PBYTE buf; log3("move %d %08x->%08x",bytes,ofsSource,ofsDest); buf = (PBYTE)mir_alloc(bytes); SetFilePointer(hDbFile,ofsSource,NULL,FILE_BEGIN); ReadFile(hDbFile,buf,bytes,&bytesRead,NULL); DBWrite(ofsDest,buf,bytes); mir_free(buf); logg(); } static UINT_PTR flushBuffersTimerId; static VOID CALLBACK DoBufferFlushTimerProc(HWND hwnd,UINT message,UINT_PTR idEvent,DWORD dwTime) { KillTimer(NULL,flushBuffersTimerId); log0("tflush1"); FlushFileBuffers(hDbFile); log0("tflush2"); } void DBFlush(int setting) { if (!setting) { log0("nflush1"); if (safetyMode) FlushFileBuffers(hDbFile); log0("nflush2"); return; } KillTimer(NULL,flushBuffersTimerId); flushBuffersTimerId = SetTimer(NULL,flushBuffersTimerId,50,DoBufferFlushTimerProc); } static INT_PTR CacheSetSafetyMode(WPARAM wParam,LPARAM lParam) { EnterCriticalSection(&csDbAccess); safetyMode = wParam; LeaveCriticalSection(&csDbAccess); if (safetyMode) FlushFileBuffers(hDbFile); return 0; } int InitCache(void) { pDbCache = (PBYTE)mir_alloc(CACHESECTIONSIZE*CACHESECTIONCOUNT); lastUseCounter = CACHESECTIONCOUNT; for(int i = 0; i < CACHESECTIONCOUNT; i++) { cacheSectionInfo[i].ofsBase = 0; cacheSectionInfo[i].lastUsed = i; SetFilePointer(hDbFile,cacheSectionInfo[i].ofsBase,NULL,FILE_BEGIN); DWORD bytesRead; ReadFile(hDbFile,pDbCache+i*CACHESECTIONSIZE,CACHESECTIONSIZE,&bytesRead,NULL); } return 0; } void UninitCache(void) { mir_free(pDbCache); KillTimer(NULL,flushBuffersTimerId); }