2
0

MemCacheVariantTest.dpr 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. program MemCacheVariantTest;
  2. {$APPTYPE CONSOLE}
  3. {$R *.res}
  4. uses
  5. System.SysUtils,
  6. Quick.Commons,
  7. Quick.Console,
  8. Quick.Threads,
  9. Quick.Chrono,
  10. Quick.Format,
  11. Quick.MemoryCache;
  12. type
  13. TMyObject = class
  14. private
  15. fTestStr : string;
  16. fTestInt : Integer;
  17. public
  18. property TestStr : string read fTestStr write fTestStr;
  19. property TestInt : Integer read fTestInt write fTestInt;
  20. end;
  21. var
  22. cache : IMemoryCache;
  23. valuestr : string;
  24. valueobj : TMyObject;
  25. valueobj2 : TMyObject;
  26. backgroundtasks : TBackgroundTasks;
  27. i : Integer;
  28. n : Integer;
  29. chrono : TChronometer;
  30. dummystr : string;
  31. arr : TArray<string>;
  32. arrobj : TArray<TMyObject>;
  33. begin
  34. ReportMemoryLeaksOnShutdown := True;
  35. backgroundtasks := TBackgroundTasks.Create(20,100);
  36. cache := TMemoryCache.Create(10);
  37. //cache := TMemoryCache.Create(10,nil,TCacheCompressorLZO.Create);
  38. cache.Compression := True;
  39. cache.OnEndPurgerJob := procedure(aRemovedEntries : Integer)
  40. begin
  41. cout(Format('Purger job finished (Removed: %s /CachedObjects: %s / CacheSize: %s)',[NumberToStr(aRemovedEntries),NumberToStr(cache.CachedObjects),FormatBytes(cache.CacheSize)]),ccMagenta);
  42. end;
  43. cache.OnPurgeJobError := procedure(const aErrorMsg : string)
  44. begin
  45. coutFmt('Error flushing cache expireds (%s)',[aErrorMsg],etError);
  46. end;
  47. //set string to cache
  48. cache.SetValue('one','one string');
  49. //set string to cache with expiration to 10 seconds
  50. cache.SetValue('other','another string',10);
  51. //set array of string
  52. cache.SetValue('myarray',['one','two','three','four']);
  53. //set object to cache
  54. valueobj := TMyObject.Create;
  55. try
  56. valueobj.TestStr := 'TestOk';
  57. valueobj.TestInt := 7;
  58. cache.SetValue('Obj1',valueobj);
  59. finally
  60. valueobj.Free;
  61. end;
  62. //set array of myobject
  63. valueobj := TMyObject.Create;
  64. try
  65. valueobj.TestStr := 'TestOk One';
  66. valueobj.TestInt := 7;
  67. arrobj := arrobj + [valueobj];
  68. cache.SetValue('arrayobj',TArray<TObject>(arrobj));
  69. finally
  70. valueobj.Free;
  71. end;
  72. arrobj := nil;
  73. //get string from cache
  74. //cache.TryGetValue<string>('one',valuestr);
  75. valuestr := cache.GetValue('one');
  76. coutFmt('Got Id(one) from cache: %s',[valuestr],etSuccess);
  77. //get other string from cache
  78. //cache.TryGetValue<string>('other',valueint);
  79. cache.TryGetValue('other',valuestr);
  80. coutFmt('Got Id(other) from cache: %s',[valuestr],etSuccess);
  81. //get object from cache
  82. valueobj2 := TMyObject.Create;
  83. try
  84. cache.TryGetValue('Obj1',valueobj2);
  85. coutFmt('Got Id(Obj1) from cache: (TestStr = %s / TestIn = %d)',[valueobj2.TestStr,valueobj2.TestInt],etSuccess);
  86. finally
  87. valueobj2.Free;
  88. end;
  89. //get array of string from cache
  90. cache.TryGetValue('myarray',arr);
  91. coutFmt('array of string[0] = %s',[arr[0]],etSuccess);
  92. //get array of myobject from cache
  93. cache.TryGetValue('arrayobj',TArray<TObject>(arrobj));
  94. coutFmt('array of MyObject[0].TestStr = %s',[arrobj[0].TestStr],etSuccess);
  95. chrono := TChronometer.Create(False);
  96. //concurrent read/writes
  97. dummystr := '';
  98. cout('Preparing data..',ccWhite);
  99. dummystr := RandomString(1024);
  100. n := 0;
  101. for i := 1 to 100000 do
  102. begin
  103. Inc(n);
  104. if n < 9 then
  105. begin
  106. backgroundtasks.AddTask(procedure(task : ITask)
  107. var a : string;
  108. begin
  109. if not cache.TryGetValue('1',a) then
  110. begin
  111. coutFmt('Value %d not in cache or expired',[1],etWarning);
  112. cache.SetValue('1',a,1000);
  113. end;
  114. //coutFmt('Get Id(1) from cache = %s',[a],etSuccess);
  115. end
  116. ).Run;
  117. end
  118. else
  119. begin
  120. n := 0;
  121. backgroundtasks.AddTask(procedure(task : ITask)
  122. var a : string;
  123. begin
  124. a := Random(1000000).ToString;
  125. cache.SetValue(a,dummystr + a,Random(5000));
  126. //coutFmt('Set Id(1) to cache = %s',[a],etSuccess);
  127. end
  128. ).Run;
  129. end;
  130. end;
  131. backgroundtasks.AddTask(procedure(task : ITask)
  132. var a : string;
  133. begin
  134. chrono.Stop;
  135. coutFmt('Performance: %s Combined cache IO Read/Writes in %s',[NumberToStr(i),chrono.ElapsedTime],etWarning);
  136. coutFmt('Cached Objects: %s / Cache Size: %s',[NumberToStr(cache.CachedObjects),FormatBytes(cache.CacheSize)],etInfo);
  137. //cache.Flush;
  138. end
  139. ).Run;
  140. cout('Stress caching test launched',ccWhite);
  141. backgroundtasks.Start;
  142. chrono.Start;
  143. cout('Wait to see how cache is expiring every 10 seconds or press <ENTER> to Exit',ccYellow);
  144. ConsoleWaitForEnterKey;
  145. coutFmt('Cached Objects: %s / Cache Size: %s',[NumberToStr(cache.CachedObjects),FormatBytes(cache.CacheSize)],etInfo);
  146. //cache.Free;
  147. chrono.Free;
  148. backgroundtasks.Free;
  149. end.