#include "stdafx.h" #include "CircleBuff.h" #include "LogFileSaveThread.h" #include #define TIMEOUT_FILE_OP (500) CircleBuff g_Circle; CircleBuff::CircleBuff() { m_UsedSize = 0; m_BasePos = 0; m_HeadPos = 0; m_TotalSize = 1024 * 1024 * 8; m_pBuff = new char[m_TotalSize];//8M } CircleBuff::~CircleBuff() { if (m_pBuff) { delete[]m_pBuff; } m_pBuff = NULL; } bool CircleBuff::SetCacheSize(DWORD Size) { if (m_pBuff && m_TotalSize > Size) { return true; } if (m_pBuff) { delete[]m_pBuff; } m_pBuff = new char[Size]; if (m_pBuff != NULL) { m_TotalSize = Size; return true; } m_TotalSize = 0; return false; } bool CircleBuff::CopyContext(char *pContext, DWORD ContextSize, DWORD Offset, DWORD OffsetSize) { if (ContextSize < OffsetSize || ContextSize == 0) { return false; } DWORD copied = min((m_TotalSize - Offset), OffsetSize); memcpy(pContext, &(m_pBuff[Offset]), copied); if (copied == OffsetSize) { return true; } memcpy(&(pContext[copied]), &(m_pBuff[0]), OffsetSize - copied); return true; } DWORD CircleBuff::AddContext(const char *pContext, DWORD Size) { DWORD copied = 0; if (m_TotalSize > (Size + m_UsedSize)) { if (m_HeadPos >= m_BasePos) { copied = min((m_TotalSize - m_HeadPos), Size); memcpy(&m_pBuff[m_HeadPos], pContext, copied); if (copied == Size) { //done here m_HeadPos += copied; if (m_HeadPos == m_TotalSize) { m_HeadPos = 0; } } else { //it must be overloaded memcpy(&m_pBuff[0], &pContext[copied], Size - copied); m_HeadPos = Size - copied; } } else { memcpy(&m_pBuff[m_HeadPos], pContext, Size); m_HeadPos += Size; } m_UsedSize += Size; copied = Size; } return copied; } //---------------------------------- BlockMap::BlockMap() { m_FileIdx = 0; } BlockMap::~BlockMap() { } bool BlockMap::ChangeFilePath(DWORD FileId,const char *pFilePath) { bool ret = false; Thread_Lock(); map::iterator iter = m_Block.find(FileId); if (iter != m_Block.end()) { iter->second.m_FileName = pFilePath; ret = true; } Thread_UnLock(); return ret; } DWORD BlockMap::CreateLogFile(const char *pFilePath) { DWORD ret = 0; string filenameLow = pFilePath; transform(filenameLow.begin(), filenameLow.end(), filenameLow.begin(), tolower); Thread_Lock(); //find match filename map::iterator iter = m_Block.begin(); while (iter != m_Block.end()) { if (iter->second.m_FileName == filenameLow) { //we found one ret = iter->first; break; } ++iter; } if (ret == 0) { BlockInfo info; info.m_FileName = filenameLow; m_Block[++m_FileIdx] = info; ret = m_FileIdx; } Thread_UnLock(); return ret; } void BlockMap::ClearMapInfo() { map::iterator iter = m_Block.begin(); while (iter != m_Block.end()) { iter->second.m_Block.clear(); iter->second.m_TotalSize = 0; ++iter; } } bool BlockMap::WriteLogFile(DWORD Id, LOGFILESTATUS &Pattern, const char *pContext, DWORD size) { bool ret = false; BlockInfo info; if (Thread_Lock(TIMEOUT_FILE_OP) != WAIT_OBJECT_0) { return ret; } map::iterator iter = m_Block.find(Id); if (iter != m_Block.end()) { //found one if (iter->second.m_FileStatus.InitStatus == false) { iter->second.m_FileStatus = Pattern; } //lock circle if (g_Circle.Thread_Lock(TIMEOUT_FILE_OP) != WAIT_OBJECT_0) { Thread_UnLock(); return ret; } //g_Circle.Thread_Lock(); //update circle BLOCKID Id; Id.Offset = g_Circle.m_HeadPos; DWORD Saved = g_Circle.AddContext(pContext, size); if (Saved == size) { //ok Id.Size = size; iter->second.m_Block.push_back(Id); iter->second.m_TotalSize += size; ret = true; } if (g_Circle.m_UsedSize > g_Circle.m_TotalSize / 2) { //make notify to Saving Thread g_LogThread.NotifyThreadWork(); } g_Circle.Thread_UnLock(); } Thread_UnLock(); return ret; } BlockMap g_BlockMap;