Usage.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <Configuration.h>
  5. #include <CoreMain.h>
  6. #include <Common.h>
  7. #include <Usage.h>
  8. //---------------------------------------------------------------------------
  9. #pragma package(smart_init)
  10. //---------------------------------------------------------------------------
  11. const UnicodeString LastInternalExceptionCounter(L"LastInternalException2");
  12. const UnicodeString LastUpdateExceptionCounter(L"LastUpdateException");
  13. //---------------------------------------------------------------------------
  14. __fastcall TUsage::TUsage(TConfiguration * Configuration)
  15. {
  16. FCriticalSection = new TCriticalSection();
  17. FConfiguration = Configuration;
  18. FValues = new TStringList();
  19. FValues->Delimiter = L'&';
  20. FValues->StrictDelimiter = true;
  21. FCollect = true;
  22. Default();
  23. }
  24. //---------------------------------------------------------------------------
  25. __fastcall TUsage::~TUsage()
  26. {
  27. delete FValues;
  28. delete FCriticalSection;
  29. }
  30. //---------------------------------------------------------------------------
  31. void __fastcall TUsage::Default()
  32. {
  33. TGuard Guard(FCriticalSection);
  34. FPeriodCounters.clear();
  35. FLifetimeCounters.clear();
  36. FValues->Clear();
  37. if (Collect) // optimization
  38. {
  39. Set(L"FirstUse", StandardTimestamp());
  40. Set(L"FirstVersion", IntToStr(FConfiguration->CompoundVersion));
  41. UpdateLastReport();
  42. }
  43. }
  44. //---------------------------------------------------------------------------
  45. void __fastcall TUsage::Load(THierarchicalStorage * Storage)
  46. {
  47. TGuard Guard(FCriticalSection);
  48. Default();
  49. if (Storage->OpenSubKey(L"Values", false))
  50. {
  51. TStrings * Names = new TStringList();
  52. try
  53. {
  54. Storage->GetValueNames(Names);
  55. for (int Index = 0; Index < Names->Count; Index++)
  56. {
  57. UnicodeString Name = Names->Strings[Index];
  58. Set(Name, Storage->ReadString(Name, L""));
  59. }
  60. Storage->CloseSubKey();
  61. }
  62. __finally
  63. {
  64. delete Names;
  65. }
  66. }
  67. Load(Storage, L"PeriodCounters", FPeriodCounters);
  68. Load(Storage, L"LifetimeCounters", FLifetimeCounters);
  69. }
  70. //---------------------------------------------------------------------------
  71. void __fastcall TUsage::Load(THierarchicalStorage * Storage,
  72. const UnicodeString& Name, TCounters & Counters)
  73. {
  74. if (Storage->OpenSubKey(Name, false))
  75. {
  76. TStrings * Names = new TStringList();
  77. try
  78. {
  79. Storage->GetValueNames(Names);
  80. for (int Index = 0; Index < Names->Count; Index++)
  81. {
  82. UnicodeString Name = Names->Strings[Index];
  83. Counters.insert(
  84. std::make_pair(Name, Storage->ReadInteger(Name, 0)));
  85. }
  86. Storage->CloseSubKey();
  87. }
  88. __finally
  89. {
  90. delete Names;
  91. }
  92. }
  93. }
  94. //---------------------------------------------------------------------------
  95. void __fastcall TUsage::Save(THierarchicalStorage * Storage) const
  96. {
  97. TGuard Guard(FCriticalSection);
  98. if (Storage->OpenSubKey(L"Values", true))
  99. {
  100. Storage->ClearValues();
  101. Storage->WriteValues(FValues, true);
  102. Storage->CloseSubKey();
  103. }
  104. Save(Storage, L"PeriodCounters", FPeriodCounters);
  105. Save(Storage, L"LifetimeCounters", FLifetimeCounters);
  106. }
  107. //---------------------------------------------------------------------------
  108. void __fastcall TUsage::Save(THierarchicalStorage * Storage,
  109. const UnicodeString & Name, const TCounters & Counters) const
  110. {
  111. if (Storage->OpenSubKey(Name, true))
  112. {
  113. Storage->ClearValues();
  114. TCounters::const_iterator i = Counters.begin();
  115. while (i != Counters.end())
  116. {
  117. Storage->WriteInteger(i->first, i->second);
  118. i++;
  119. }
  120. Storage->CloseSubKey();
  121. }
  122. }
  123. //---------------------------------------------------------------------------
  124. void __fastcall TUsage::Set(const UnicodeString & Key, const UnicodeString & Value)
  125. {
  126. if (Collect)
  127. {
  128. TGuard Guard(FCriticalSection);
  129. FValues->Values[Key] = Value;
  130. }
  131. }
  132. //---------------------------------------------------------------------------
  133. void __fastcall TUsage::Set(const UnicodeString & Key, int Value)
  134. {
  135. Set(Key, IntToStr(Value));
  136. }
  137. //---------------------------------------------------------------------------
  138. void __fastcall TUsage::Set(const UnicodeString & Key, bool Value)
  139. {
  140. Set(Key, Value ? 1 : 0);
  141. }
  142. //---------------------------------------------------------------------------
  143. UnicodeString __fastcall TUsage::Get(const UnicodeString & Key)
  144. {
  145. TGuard Guard(FCriticalSection);
  146. UnicodeString Result = FValues->Values[Key];
  147. Result.Unique();
  148. return Result;
  149. }
  150. //---------------------------------------------------------------------------
  151. void __fastcall TUsage::UpdateLastReport()
  152. {
  153. Set(L"LastReport", StandardTimestamp());
  154. }
  155. //---------------------------------------------------------------------------
  156. void __fastcall TUsage::Reset()
  157. {
  158. TGuard Guard(FCriticalSection);
  159. UpdateLastReport();
  160. FPeriodCounters.clear();
  161. ResetLastExceptions();
  162. }
  163. //---------------------------------------------------------------------------
  164. void __fastcall TUsage::UpdateCurrentVersion()
  165. {
  166. TGuard Guard(FCriticalSection);
  167. int CompoundVersion = FConfiguration->CompoundVersion;
  168. int PrevVersion = StrToIntDef(Get(L"CurrentVersion"), 0);
  169. if (PrevVersion != CompoundVersion)
  170. {
  171. Set(L"Installed", StandardTimestamp());
  172. }
  173. if (PrevVersion != 0)
  174. {
  175. if (PrevVersion < CompoundVersion)
  176. {
  177. Inc(L"Upgrades");
  178. }
  179. else if (PrevVersion > CompoundVersion)
  180. {
  181. Inc(L"Downgrades");
  182. }
  183. if (PrevVersion != CompoundVersion)
  184. {
  185. ResetLastExceptions();
  186. }
  187. }
  188. Set(L"CurrentVersion", CompoundVersion);
  189. }
  190. //---------------------------------------------------------------------------
  191. void __fastcall TUsage::ResetValue(const UnicodeString & Key)
  192. {
  193. int Index = FValues->IndexOfName(Key);
  194. if (Index >= 0)
  195. {
  196. FValues->Delete(Index);
  197. }
  198. }
  199. //---------------------------------------------------------------------------
  200. void __fastcall TUsage::ResetLastExceptions()
  201. {
  202. TGuard Guard(FCriticalSection);
  203. ResetValue(LastInternalExceptionCounter);
  204. ResetValue(LastUpdateExceptionCounter);
  205. }
  206. //---------------------------------------------------------------------------
  207. void __fastcall TUsage::Inc(const UnicodeString & Key, int Increment)
  208. {
  209. if (Collect)
  210. {
  211. TGuard Guard(FCriticalSection);
  212. Inc(Key, FPeriodCounters, Increment);
  213. Inc(Key, FLifetimeCounters, Increment);
  214. }
  215. }
  216. //---------------------------------------------------------------------------
  217. void __fastcall TUsage::Inc(const UnicodeString & Key, TCounters & Counters, int Increment)
  218. {
  219. TCounters::iterator i = Counters.find(Key);
  220. if (i != Counters.end())
  221. {
  222. i->second += Increment;
  223. }
  224. else
  225. {
  226. Counters.insert(std::make_pair(Key, Increment));
  227. }
  228. }
  229. //---------------------------------------------------------------------------
  230. void __fastcall TUsage::SetMax(const UnicodeString & Key, int Value)
  231. {
  232. if (Collect)
  233. {
  234. TGuard Guard(FCriticalSection);
  235. SetMax(Key, Value, FPeriodCounters);
  236. SetMax(Key, Value, FLifetimeCounters);
  237. }
  238. }
  239. //---------------------------------------------------------------------------
  240. void __fastcall TUsage::SetMax(const UnicodeString & Key, int Value,
  241. TCounters & Counters)
  242. {
  243. TCounters::iterator i = Counters.find(Key);
  244. if (i != Counters.end())
  245. {
  246. if (Value > i->second)
  247. {
  248. i->second = Value;
  249. }
  250. }
  251. else
  252. {
  253. Counters.insert(std::make_pair(Key, Value));
  254. }
  255. }
  256. //---------------------------------------------------------------------------
  257. void __fastcall TUsage::SetCollect(bool value)
  258. {
  259. TGuard Guard(FCriticalSection);
  260. if (Collect != value)
  261. {
  262. FCollect = value;
  263. if (!FCollect)
  264. {
  265. FPeriodCounters.clear();
  266. FLifetimeCounters.clear();
  267. FValues->Clear();
  268. }
  269. else
  270. {
  271. Default();
  272. }
  273. }
  274. }
  275. //---------------------------------------------------------------------------
  276. UnicodeString __fastcall TUsage::Serialize(const UnicodeString & Delimiter, const UnicodeString & Filter) const
  277. {
  278. TGuard Guard(FCriticalSection);
  279. UnicodeString Result;
  280. UnicodeString FilterUpper = Filter.UpperCase();
  281. for (int Index = 0; Index < FValues->Count; Index++)
  282. {
  283. Serialize(Result, FValues->Names[Index], FValues->ValueFromIndex[Index], Delimiter, FilterUpper);
  284. }
  285. Serialize(Result, L"Period", FPeriodCounters, Delimiter, FilterUpper);
  286. Serialize(Result, L"Lifetime", FLifetimeCounters, Delimiter, FilterUpper);
  287. return Result;
  288. }
  289. //---------------------------------------------------------------------------
  290. void __fastcall TUsage::Serialize(
  291. UnicodeString & List, const UnicodeString & Name, const TCounters & Counters,
  292. const UnicodeString & Delimiter, const UnicodeString & FilterUpper) const
  293. {
  294. TCounters::const_iterator i = Counters.begin();
  295. while (i != Counters.end())
  296. {
  297. Serialize(List, Name + i->first, IntToStr(i->second), Delimiter, FilterUpper);
  298. i++;
  299. }
  300. }
  301. //---------------------------------------------------------------------------
  302. void __fastcall TUsage::Serialize(
  303. UnicodeString & List, const UnicodeString & Name, const UnicodeString & Value,
  304. const UnicodeString & Delimiter, const UnicodeString & FilterUpper) const
  305. {
  306. if (FilterUpper.IsEmpty() ||
  307. (Name.UpperCase().Pos(FilterUpper) > 0) ||
  308. (Value.UpperCase().Pos(FilterUpper) > 0))
  309. {
  310. AddToList(List, FORMAT(L"%s=%s", (Name, Value)), Delimiter);
  311. }
  312. }
  313. //---------------------------------------------------------------------------
  314. int __fastcall TUsage::CalculateCounterSize(__int64 Size)
  315. {
  316. const int SizeCounterFactor = 10240;
  317. return (Size <= 0) ? 0 : (Size < SizeCounterFactor ? 1 : Size / SizeCounterFactor);
  318. }