在Socket通信服务器的开发中,我们经常会需要Socket与某个结构体指针进行绑定。当连接量很大时,意味着需要个高效的查找方法
Delphi中提供了哈希算法类,以此类为基础,修改出Socket专用Map类。
源码下载 https://files.cnblogs.com/lwm8246/uSocketHash.rar
1 unit uSocketHash;
2
3 //2014-03-29 17:05
4 //QQ 287413288 5
6 interface
7
8 uses SyncObjs;
9
10 type
11 {$IF CompilerVersion >= 22} //XE=22,2010=21
12 TSocket = NativeUInt;
13 {$ELSE}
14 TSocket = Integer;
15 {$IFEND}
16
17 PPSocketHashItem = ^PSocketHashItem;
18 PSocketHashItem = ^TSocketHashItem;
19 TSocketHashItem = record
20 Next: PSocketHashItem;
21 Key : TSocket;
22 Value:Pointer;
23 end;
24
25 TSocketHash = class
26 private
27 FBucketPool:array of PSocketHashItem;
28 Buckets: array of PSocketHashItem;
29 function NewBucket():PSocketHashItem;
30 procedure DisposeBucket(Value:PSocketHashItem);
31 protected
32 function Find(const Key: TSocket): PPSocketHashItem;
33 function HashOf(const Key: TSocket): Cardinal; virtual;
34 public
35 constructor Create(Size: Cardinal = 256);
36 destructor Destroy; override;
37 function Add(const Key: TSocket; Value: Pointer):Integer;
38 procedure Clear;
39 procedure Remove(const Key: TSocket);
40 function Modify(const Key: TSocket; Value: Pointer): Boolean;
41 function ValueOf(const Key: TSocket): Pointer;
42 end;
43
44 TThreadSocketHash = class //线程安全
45 private
46 FObj:TSocketHash;
47 FCS:TCriticalSection;
48 procedure Lock();
49 procedure UnLock();
50 public
51 constructor Create(Size: Cardinal = 256);
52 destructor Destroy; override;
53 function Add(const Key: TSocket; Value: Pointer):Integer;
54 procedure Clear;
55 procedure Remove(const Key: TSocket);
56 function Modify(const Key: TSocket; Value: Pointer): Boolean;
57 function ValueOf(const Key: TSocket): Pointer;
58 function GetAndRemove(const Key:TSocket):Pointer;
59 end;
60
61
62 implementation
63
64 { TStringHash }
65
66 function TSocketHash.Add(const Key: TSocket; Value: Pointer):Integer;
67 var
68 Hash: Integer;
69 Bucket: PSocketHashItem;
70 begin
71 Bucket:= NewBucket();
72 if Bucket <> nil then
73 begin
74 Hash := HashOf(Key) mod Cardinal(Length(Buckets));
75 Bucket^.Key := Key;
76 Bucket^.Value := Value;
77 Bucket^.Next := Buckets[Hash];
78 Buckets[Hash] := Bucket;
79 Result := Hash;
80 end
81 else Result := -1;//空间满
82 end;
83
84 procedure TSocketHash.Clear;
85 var
86 I: Integer;
87 P, N: PSocketHashItem;
88 begin
89 for I := 0 to Length(Buckets) - 1 do
90 begin
91 P := Buckets[I];
92 while P <> nil do
93 begin
94 N := P^.Next;
95 // Dispose(P);
96 DisposeBucket(P);
97 P := N;
98 end;
99 Buckets[I] := nil;
100 end;
101 end;
102
103 constructor TSocketHash.Create(Size: Cardinal);
104 var
105 Index:Integer;
106 PH:PSocketHashItem;
107 begin
108 inherited Create;
109 SetLength(Buckets, Size);
110 //\\
111 SetLength(FBucketPool,Size); //:array of PSocketHashItem;
112 for Index := Low(FBucketPool) to High(FBucketPool) do
113 begin
114 New(PH);
115 PH^.Next := nil;
116 PH^.Key := 0;
117 PH^.Value := nil;
118 FBucketPool[Index] := PH;
119 end;
120 end;
121
122 destructor TSocketHash.Destroy;
123 var
124 Index:Integer;
125 P:PSocketHashItem;
126 begin
127 Clear;
128 for Index := Low(FBucketPool) to High(FBucketPool) do
129 begin
130 P := FBucketPool[Index];
131 if P <> nil then Dispose(P);
132 end;
133 inherited Destroy;
134 end;
135
136 procedure TSocketHash.DisposeBucket(Value: PSocketHashItem);
137 var
138 Index:Integer;
139 begin
140 for Index := Low(FBucketPool) to High(FBucketPool) do
141 begin
142 if FBucketPool[Index] = nil then
143 begin
144 FBucketPool[Index] := Value;
145 Break;
146 end;
147 end;
148 end;
149
150 function TSocketHash.Find(const Key: TSocket): PPSocketHashItem;
151 var
152 Hash: Integer;
153 begin
154 Hash := HashOf(Key) mod Cardinal(Length(Buckets));
155 Result := @Buckets[Hash];
156 while Result^ <> nil do
157 begin
158 if Result^.Key = Key then
159 Exit
160 else
161 Result := @Result^.Next;
162 end;
163 end;
164
165 function TSocketHash.HashOf(const Key: TSocket): Cardinal;
166 var
167 I: Integer;
168 P: PByte;
169 begin
170 Result := 0;
171 P := @Key;
172 //for I := 1 to Length(Key) do
173 for I := 1 to SizeOf(Key) do
174 begin
175 Result := ((Result shl 2) or (Result shr (SizeOf(Result) * 8 - 2))) xor P^;
176 Inc(P);
177 end;
178 //Ord(Key[I]);P^
179 end;
180
181 function TSocketHash.Modify(const Key: TSocket; Value: Pointer): Boolean;
182 var
183 P: PSocketHashItem;
184 begin
185 P := Find(Key)^;
186 if P <> nil then
187 begin
188 Result := True;
189 P^.Value := Value;
190 end
191 else
192 Result := False;
193 end;
194
195 function TSocketHash.NewBucket: PSocketHashItem;
196 var
197 Index:Integer;
198 begin
199 Result := nil;
200 for Index := Low(FBucketPool) to High(FBucketPool) do
201 begin
202 Result := FBucketPool[Index];
203 if Result <> nil then
204 begin
205 FBucketPool[Index] := nil;
206 Break;
207 end;
208 end;
209 end;
210
211 procedure TSocketHash.Remove(const Key: TSocket);
212 var
213 P: PSocketHashItem;
214 Prev: PPSocketHashItem;
215 begin
216 Prev := Find(Key);
217 P := Prev^;
218 if P <> nil then
219 begin
220 Prev^ := P^.Next;
221 //Dispose(P);
222 DisposeBucket(P);
223 end;
224 end;
225
226 function TSocketHash.ValueOf(const Key: TSocket): Pointer;
227 var
228 P: PSocketHashItem;
229 begin
230 P := Find(Key)^;
231 if P <> nil then
232 Result := P^.Value
233 else
234 Result := nil;// -1;
235 end;
236
237
238
239 { TThreadSocketHash }
240
241 function TThreadSocketHash.Add(const Key: TSocket; Value: Pointer):Integer;
242 begin
243 Lock();
244 try
245 Result := FObj.Add(Key,Value);
246 finally
247 UnLock();
248 end;
249 end;
250
251 procedure TThreadSocketHash.Clear;
252 begin
253 Lock();
254 try
255 FObj.Clear();
256 finally
257 UnLock();
258 end;
259 end;
260
261 constructor TThreadSocketHash.Create(Size: Cardinal);
262 begin
263 FObj := TSocketHash.Create(Size);
264 FCS := TCriticalSection.Create();
265 end;
266
267 destructor TThreadSocketHash.Destroy;
268 begin
269 FCS.Free();
270 FObj.Free();
271 inherited;
272 end;
273
274 function TThreadSocketHash.GetAndRemove(const Key: TSocket): Pointer;
275 begin
276 Lock();
277 try
278 Result := FObj.ValueOf(Key);
279 FObj.Remove(Key);
280 finally
281 UnLock();
282 end;
283 end;
284
285 procedure TThreadSocketHash.Lock;
286 begin
287 FCS.Enter();
288 end;
289
290 function TThreadSocketHash.Modify(const Key: TSocket; Value: Pointer): Boolean;
291 begin
292 Lock();
293 try
294 FObj.Modify(Key,Value);
295 finally
296 UnLock();
297 end;
298 end;
299
300 procedure TThreadSocketHash.Remove(const Key: TSocket);
301 begin
302 Lock();
303 try
304 FObj.Remove(Key);
305 finally
306 UnLock();
307 end;
308 end;
309
310 procedure TThreadSocketHash.UnLock;
311 begin
312 FCS.Leave();
313 end;
314
315 function TThreadSocketHash.ValueOf(const Key: TSocket): Pointer;
316 begin
317 Lock();
318 try
319 Result := FObj.ValueOf(Key);
320 finally
321 UnLock();
322 end;
323 end;
324
325 end.
|
请发表评论