CircleBuff.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. #include "stdafx.h"
  2. #include "CircleBuff.h"
  3. #include "LogFileSaveThread.h"
  4. #include <algorithm>
  5. #define TIMEOUT_FILE_OP (500)
  6. CircleBuff g_Circle;
  7. CircleBuff::CircleBuff()
  8. {
  9. m_UsedSize = 0;
  10. m_BasePos = 0;
  11. m_HeadPos = 0;
  12. m_TotalSize = 1024 * 1024 * 8;
  13. m_pBuff = new char[m_TotalSize];//8M
  14. }
  15. CircleBuff::~CircleBuff()
  16. {
  17. if (m_pBuff)
  18. {
  19. delete[]m_pBuff;
  20. }
  21. m_pBuff = NULL;
  22. }
  23. bool CircleBuff::SetCacheSize(DWORD Size)
  24. {
  25. if (m_pBuff && m_TotalSize > Size)
  26. {
  27. return true;
  28. }
  29. if (m_pBuff)
  30. {
  31. delete[]m_pBuff;
  32. }
  33. m_pBuff = new char[Size];
  34. if (m_pBuff != NULL)
  35. {
  36. m_TotalSize = Size;
  37. return true;
  38. }
  39. m_TotalSize = 0;
  40. return false;
  41. }
  42. bool CircleBuff::CopyContext(char *pContext, DWORD ContextSize, DWORD Offset, DWORD OffsetSize)
  43. {
  44. if (ContextSize < OffsetSize || ContextSize == 0)
  45. {
  46. return false;
  47. }
  48. DWORD copied = min((m_TotalSize - Offset), OffsetSize);
  49. memcpy(pContext, &(m_pBuff[Offset]), copied);
  50. if (copied == OffsetSize)
  51. {
  52. return true;
  53. }
  54. memcpy(&(pContext[copied]), &(m_pBuff[0]), OffsetSize - copied);
  55. return true;
  56. }
  57. DWORD CircleBuff::AddContext(const char *pContext, DWORD Size)
  58. {
  59. DWORD copied = 0;
  60. if (m_TotalSize > (Size + m_UsedSize))
  61. {
  62. if (m_HeadPos >= m_BasePos)
  63. {
  64. copied = min((m_TotalSize - m_HeadPos), Size);
  65. memcpy(&m_pBuff[m_HeadPos], pContext, copied);
  66. if (copied == Size)
  67. {
  68. //done here
  69. m_HeadPos += copied;
  70. if (m_HeadPos == m_TotalSize)
  71. {
  72. m_HeadPos = 0;
  73. }
  74. }
  75. else
  76. {
  77. //it must be overloaded
  78. memcpy(&m_pBuff[0], &pContext[copied], Size - copied);
  79. m_HeadPos = Size - copied;
  80. }
  81. }
  82. else
  83. {
  84. memcpy(&m_pBuff[m_HeadPos], pContext, Size);
  85. m_HeadPos += Size;
  86. }
  87. m_UsedSize += Size;
  88. copied = Size;
  89. }
  90. return copied;
  91. }
  92. //----------------------------------
  93. BlockMap::BlockMap()
  94. {
  95. m_FileIdx = 0;
  96. }
  97. BlockMap::~BlockMap()
  98. {
  99. }
  100. bool BlockMap::ChangeFilePath(DWORD FileId,const char *pFilePath)
  101. {
  102. bool ret = false;
  103. Thread_Lock();
  104. map<DWORD, BlockInfo>::iterator iter = m_Block.find(FileId);
  105. if (iter != m_Block.end())
  106. {
  107. iter->second.m_FileName = pFilePath;
  108. ret = true;
  109. }
  110. Thread_UnLock();
  111. return ret;
  112. }
  113. DWORD BlockMap::CreateLogFile(const char *pFilePath)
  114. {
  115. DWORD ret = 0;
  116. string filenameLow = pFilePath;
  117. transform(filenameLow.begin(), filenameLow.end(), filenameLow.begin(), tolower);
  118. Thread_Lock();
  119. //find match filename
  120. map<DWORD, BlockInfo>::iterator iter = m_Block.begin();
  121. while (iter != m_Block.end())
  122. {
  123. if (iter->second.m_FileName == filenameLow)
  124. {
  125. //we found one
  126. ret = iter->first;
  127. break;
  128. }
  129. ++iter;
  130. }
  131. if (ret == 0)
  132. {
  133. BlockInfo info;
  134. info.m_FileName = filenameLow;
  135. m_Block[++m_FileIdx] = info;
  136. ret = m_FileIdx;
  137. }
  138. Thread_UnLock();
  139. return ret;
  140. }
  141. void BlockMap::ClearMapInfo()
  142. {
  143. map<DWORD, BlockInfo>::iterator iter = m_Block.begin();
  144. while (iter != m_Block.end())
  145. {
  146. iter->second.m_Block.clear();
  147. iter->second.m_TotalSize = 0;
  148. ++iter;
  149. }
  150. }
  151. bool BlockMap::WriteLogFile(DWORD Id, LOGFILESTATUS &Pattern, const char *pContext, DWORD size)
  152. {
  153. bool ret = false;
  154. BlockInfo info;
  155. if (Thread_Lock(TIMEOUT_FILE_OP) != WAIT_OBJECT_0)
  156. {
  157. return ret;
  158. }
  159. map<DWORD, BlockInfo>::iterator iter = m_Block.find(Id);
  160. if (iter != m_Block.end())
  161. {
  162. //found one
  163. if (iter->second.m_FileStatus.InitStatus == false)
  164. {
  165. iter->second.m_FileStatus = Pattern;
  166. }
  167. //lock circle
  168. if (g_Circle.Thread_Lock(TIMEOUT_FILE_OP) != WAIT_OBJECT_0)
  169. {
  170. Thread_UnLock();
  171. return ret;
  172. }
  173. //g_Circle.Thread_Lock();
  174. //update circle
  175. BLOCKID Id;
  176. Id.Offset = g_Circle.m_HeadPos;
  177. DWORD Saved = g_Circle.AddContext(pContext, size);
  178. if (Saved == size)
  179. {
  180. //ok
  181. Id.Size = size;
  182. iter->second.m_Block.push_back(Id);
  183. iter->second.m_TotalSize += size;
  184. ret = true;
  185. }
  186. if (g_Circle.m_UsedSize > g_Circle.m_TotalSize / 2)
  187. {
  188. //make notify to Saving Thread
  189. g_LogThread.NotifyThreadWork();
  190. }
  191. g_Circle.Thread_UnLock();
  192. }
  193. Thread_UnLock();
  194. return ret;
  195. }
  196. BlockMap g_BlockMap;