delphi模拟redis单元

  1 unit g_uSdRedis;
  2 
  3 interface
  4 
  5 uses
  6   Windows,
  7   Messages,
  8   SysUtils,
  9   Variants,
 10   Classes,
 11   Graphics,
 12   Controls,
 13   Forms,
 14   Dialogs,
 15   IniFiles,
 16   StdCtrls,
 17   DateUtils;
 18 
 19 const
 20   C_FORMAT_DATETIME_STLY_1 = 'yyyy-mm-dd hh:nn:ss.zzzz';
 21   C_FORMAT_DATETIME_STLY_2 = 'yyyy-mm-dd hh:nn:ss';
 22   C_FORMAT_DATETIME_STLY_3 = 'yyyymmddhhnnss';
 23   C_DEFAULT_EXPIRETIME = 1 * 60;
 24   C_MAXLIMIT_COUNTS = 10000;
 25 
 26 var
 27   g_uMyRedis: THashedStringList;
 28   g_uExpireTime: Integer = 1 * 60;
 29 
 30  function getLockRedis(lockKey: string): string;
 31   
 32  function addLockRedis(lockKey: string; expired: Integer): Boolean;
 33 
 34  function delLockRedis(lockKey: string; nMaxLimitCounts: Integer): Boolean;
 35 
 36  function delForceLockRedis(lockKey: string; nMaxLimitCounts: Integer): Boolean;
 37  
 38 implementation
 39 
 40 function initLoadHashMapParams(): Boolean;
 41 begin
 42   if not Assigned(g_uMyRedis) then
 43     g_uMyRedis := THashedStringList.Create;
 44     
 45   // 从配置文件中读取失效时间
 46   g_uExpireTime := 10;
 47 end;
 48 
 49 function descHashMapParams(): Boolean;
 50 begin
 51   if Assigned(g_uMyRedis) then
 52     FreeAndNil(g_uMyRedis);
 53 end;
 54 
 55 function addTimeSeconds(currTime: TDateTime; addSeconds: Integer): TDateTime;
 56 begin
 57   if addSeconds <= 0 then
 58   begin
 59     addSeconds := 1;
 60   end;
 61   Result := IncSecond(currTime, addSeconds);
 62 end;
 63 
 64 function getRedis(key: string): string;
 65 var
 66   iIndex: Integer;
 67   sTmp: string;
 68 begin
 69   Result := '';
 70   try
 71     iIndex := g_uMyRedis.IndexOfName(key);
 72     if iIndex < 0 then
 73     begin
 74       Exit;
 75     end;
 76     sTmp := g_uMyRedis.Values[key];
 77     Result := sTmp;
 78   except
 79     on e:Exception do
 80     begin
 81       ShowMessage('【异常】通知:' + e.Message);
 82       Exit;
 83     end;
 84   end;
 85 end;
 86 
 87 function setRedis(key: string; expired: Integer): Boolean;
 88 var
 89   iIndex: Integer;
 90   nTime: Integer;
 91   sTmp: string;
 92 begin
 93   Result := False;
 94   try
 95     iIndex := g_uMyRedis.IndexOfName(key);
 96     if iIndex >= 0 then
 97     begin
 98       g_uMyRedis.Delete(iIndex);
 99     end;
100     nTime := DateTimeToTimeStamp(addTimeSeconds(Now,expired)).Time;
101     sTmp := IntToStr(nTime);
102     g_uMyRedis.Add(key + '=' + sTmp);
103     Result := True;
104   except
105     on e:Exception do
106     begin
107       ShowMessage('【异常】通知:' + e.Message);
108       Exit;
109     end;
110   end;
111 end;
112 
113 function setNXRedis(key: string; value: string): Boolean;
114 var
115   iIndex: Integer;
116   nTime: Integer;
117   sTmp: string;
118 begin
119   Result := False;
120   try
121     iIndex := g_uMyRedis.IndexOfName(key);
122     if iIndex >= 0 then
123     begin
124       Exit;
125     end;
126     g_uMyRedis.Add(key + '=' + value);
127     Result := True;
128   except
129     on e:Exception do
130     begin
131       ShowMessage('【异常】通知:' + e.Message);
132       Exit;
133     end;
134   end;
135 end;
136 
137 function getSetRedis(key: string; value: string): String;
138 var
139   iIndex: Integer;
140   iDiffTime: Integer;
141   sTmp: string;
142   sNowDateTime: string;
143 begin
144   Result := '';
145   try
146     sTmp := '';
147     iIndex := g_uMyRedis.IndexOfName(key);
148     if iIndex >= 0 then
149     begin
150       sTmp := g_uMyRedis.Values[key];
151       g_uMyRedis.Delete(iIndex);
152     end;
153     g_uMyRedis.Add(key + '=' + value);
154     Result := sTmp;
155   except
156     on e:Exception do
157     begin
158       ShowMessage('【异常】通知:' + e.Message);
159       Exit;
160     end;
161   end;
162 end;
163 
164 function acquireLockRedis(lockKey: string; expired: Integer): Boolean;
165 var
166   iIndex: Integer;
167   nOldTime: Integer;
168   nNowTime: Integer;
169   nTime: Integer;
170   bRetBool: Boolean;
171   sOldDateTime: string;
172   sNowDateTime: string;
173   sTmp: string;
174 begin
175   Result := False;
176   try
177     if expired < 0 then
178     begin
179       expired := C_DEFAULT_EXPIRETIME;
180     end;
181     nTime := DateTimeToTimeStamp(addTimeSeconds(Now,expired)).Time;
182     sNowDateTime := IntToStr(nTime);
183     bRetBool := setNXRedis(lockKey, sNowDateTime);
184     if bRetBool then
185     begin
186       Result := True;
187       Exit;
188     end;
189     sOldDateTime := getRedis(lockKey);
190     nOldTime := StrToInt(sOldDateTime);
191     nNowTime := DateTimeToTimeStamp(Now).Time;
192     if nOldTime < nNowTime then
193     begin
194       sTmp := getSetRedis(lockKey, sNowDateTime);
195       if StrToInt(sTmp) = nOldTime then
196       begin
197         Result := True;
198         Exit;
199       end;
200     end;
201   except
202     on e:Exception do
203     begin
204       ShowMessage('【异常】通知:' + e.Message);
205       Exit;
206     end;
207   end;
208 end;
209 
210 function releaseLockRedis(lockKey: string): Boolean;
211 var
212   iIndex: Integer;
213 begin
214   Result := False;
215   try
216     iIndex := g_uMyRedis.IndexOfName(lockKey);
217     if iIndex < 0 then
218     begin
219       Result := True;
220       Exit;
221     end;
222     g_uMyRedis.Delete(iIndex);
223     Result := True;
224   except
225     on e:Exception do
226     begin
227       ShowMessage('【异常】通知:' + e.Message);
228       Exit;
229     end;
230   end;
231 end;
232 
233 function getLockRedis(lockKey: string): string;
234 var
235   iIndex1,iIndex2: Integer;
236   sTmp1: string;
237   sTmp2: string;
238   sKey: string;
239   sValue: string;
240   a: TTimeStamp;
241 begin
242   Result := '';
243   try
244     iIndex1 := g_uMyRedis.IndexOfName(lockKey);
245     if iIndex1 < 0 then
246     begin
247       Exit;
248     end;
249 
250     sTmp1 := g_uMyRedis.Strings[iIndex1];
251     sTmp2 := '';
252     iIndex2 := Pos('=', sTmp1);
253     if iIndex2 > 0 then
254     begin
255       sKey := Copy(sTmp1,1,iIndex2-1);
256       sValue := Copy(sTmp1,iIndex2+1,Length(sTmp1)-iIndex2);
257       a.Time := StrToInt(sValue);
258       a.Date := DateTimeToTimeStamp(Now).Date;
259       sTmp2 := FormatDateTime('yyyy-mm-dd hh:nn:ss.zzzz', TimeStampToDateTime(a));
260     end;
261     Result := sTmp1 + '' + sTmp2 + '';
262   except
263     on e:Exception do
264     begin
265       ShowMessage('【异常】通知:' + e.Message);
266       Exit;
267     end;
268   end;
269 end;
270 
271 function addLockRedis(lockKey: string; expired: Integer): Boolean;
272 var
273   iIndex: Integer;
274   nOldTime: Integer;
275   nNowTime: Integer;
276   bRetBool: Boolean;
277   sOldDateTime: string;
278   sNowDateTime: string;
279   sTmp: string;
280 begin
281   Result := False;
282   try
283     if expired < 0 then
284     begin
285       expired := C_DEFAULT_EXPIRETIME;
286     end;
287     Result := acquireLockRedis(lockKey, expired);
288   except
289     on e:Exception do
290     begin
291       ShowMessage('【异常】通知:' + e.Message);
292       Exit;
293     end;
294   end;
295 end;
296 
297 function delLockRedis(lockKey: string; nMaxLimitCounts: Integer): Boolean;
298 var
299   i: Integer;
300   nTime: Integer;
301   iSize: Integer;
302   nIndex: Integer;
303   sTmp: string;
304   sKey: string;
305   sValue: string;
306 begin
307   Result := False;
308   try
309     if lockKey <> '' then
310     begin
311       if getRedis(lockKey) <> '' then
312       begin
313         sTmp := g_uMyRedis.Values[lockKey];
314         nTime := StrToInt(sTmp);
315         if DateTimeToTimeStamp(Now).Time > nTime then
316         begin
317           releaseLockRedis(lockKey);
318         end;
319       end;
320     end;
321     iSize := g_uMyRedis.Count;
322     if iSize > nMaxLimitCounts then
323     begin
324       if (nMaxLimitCounts <= 0)
325       and (nMaxLimitCounts >= 100000) then
326       begin
327         nMaxLimitCounts := C_MAXLIMIT_COUNTS;
328       end;
329       for i := iSize-1 downto 0 do
330       begin
331         sTmp := g_uMyRedis.Strings[i];
332         nIndex := Pos('=',sTmp);
333         if nIndex > 0 then
334         begin
335           sKey := Copy(sTmp,1,nIndex-1);
336           sValue := Copy(sTmp,nIndex+1,Length(sTmp)-nIndex);
337           nTime := StrToInt(sValue);
338           if DateTimeToTimeStamp(Now).Time > nTime then
339           begin
340             releaseLockRedis(sKey);
341           end;
342         end;
343       end;
344     end;
345     Result := True;
346   except
347     on e:Exception do
348     begin
349       ShowMessage('【异常】通知:' + e.Message);
350       Exit;
351     end;
352   end;
353 end;
354 
355 function delForceLockRedis(lockKey: string; nMaxLimitCounts: Integer): Boolean;
356 var
357   i: Integer;
358   nTime: Integer;
359   iSize: Integer;
360   nIndex: Integer;
361   sTmp: string;
362   sKey: string;
363   sValue: string;
364 begin
365   Result := False;
366   try
367     if lockKey <> '' then
368     begin
369       if getRedis(lockKey) <> '' then
370       begin
371         releaseLockRedis(lockKey);
372       end;
373     end;
374     iSize := g_uMyRedis.Count;
375     if iSize > nMaxLimitCounts then
376     begin
377       if (nMaxLimitCounts <= 0)
378       and (nMaxLimitCounts >= 100000) then
379       begin
380         nMaxLimitCounts := C_MAXLIMIT_COUNTS;
381       end;
382       for i := iSize-1 downto 0 do
383       begin
384         sTmp := g_uMyRedis.Strings[i];
385         nIndex := Pos('=',sTmp);
386         if nIndex > 0 then
387         begin
388           sKey := Copy(sTmp,1,nIndex-1);
389           sValue := Copy(sTmp,nIndex+1,Length(sTmp)-nIndex);
390           nTime := StrToInt(sValue);
391           if DateTimeToTimeStamp(Now).Time > nTime then
392           begin
393             releaseLockRedis(sKey);
394           end;
395         end;
396       end;
397     end;
398     Result := True;
399   except
400     on e:Exception do
401     begin
402       ShowMessage('【异常】通知:' + e.Message);
403       Exit;
404     end;
405   end;
406 end;
407 
408 
409 initialization
410   initLoadHashMapParams;
411 
412 
413 finalization
414   descHashMapParams();
415 
416 end.
 1 unit Unit1;
 2 
 3 interface
 4 
 5 uses
 6   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 7   Dialogs, IniFiles, StdCtrls, JclHashMaps, g_uSdRedis;
 8 
 9 type
10   TForm1 = class(TForm)
11     btn1: TButton;
12     edt1: TEdit;
13     btn2: TButton;
14     btn3: TButton;
15     procedure btn1Click(Sender: TObject);
16     procedure btn2Click(Sender: TObject);
17     procedure btn3Click(Sender: TObject);
18   private
19     { Private declarations }
20   public
21     { Public declarations }
22   end;
23 
24 var
25   Form1: TForm1;
26 
27 implementation
28 
29 {$R *.dfm}
30 
31 procedure TForm1.btn1Click(Sender: TObject);
32 var
33   i, aSize: Integer;
34   bRet: Boolean;
35 begin
36   edt1.Text := '';
37   bRet := addLockRedis('AB123', 10);
38   try
39     edt1.Text := '开始加锁->';
40   finally
41     delLockRedis('AB123', 1);
42   end;
43   edt1.Text := edt1.Text + '结束加锁->' + getLockRedis('AB123') + '#' + BoolToStr(bRet,True);
44 end;
45 
46 procedure TForm1.btn2Click(Sender: TObject);
47 var
48   i, aSize: Integer;
49 begin
50   edt1.Text := '';
51   addLockRedis('AB456', 10);
52   try
53     edt1.Text := '开始加锁->';
54   finally
55     delLockRedis('AB456', 1);
56   end;
57   edt1.Text := edt1.Text + '结束加锁->' + getLockRedis('AB456');
58 end;
59 
60 procedure TForm1.btn3Click(Sender: TObject);
61 var
62   i, aSize: Integer;
63 begin
64   edt1.Text := '';
65   addLockRedis('AB789', 10);
66   try
67     edt1.Text := '开始加锁->';
68   finally
69     delLockRedis('AB789', 1);
70   end;
71   edt1.Text := edt1.Text + '结束加锁->' + getLockRedis('AB789');
72 end;
73 
74 end.

 

posted @ 2023-12-22 17:18  襄阳古城  阅读(13)  评论(0编辑  收藏  举报