/* 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" #include "database.h" #define CACHESECTIONSIZE 4096 #define CACHESECTIONCOUNT 32 extern HANDLE hDbFile; extern CRITICAL_SECTION csDbAccess; 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) { int i; DWORD bytesRead; CreateServiceFunction(MS_DB_SETSAFETYMODE,CacheSetSafetyMode); pDbCache=(PBYTE)mir_alloc(CACHESECTIONSIZE*CACHESECTIONCOUNT); lastUseCounter=CACHESECTIONCOUNT; for(i=0;i