socket hash
socket hash
unit uSocketHash; interface uses SyncObjs; type {$IF CompilerVersion >= 22} //XE=22,2010=21 TSocket = NativeUInt; {$ELSE} TSocket = Integer; {$IFEND} PPSocketHashItem = ^PSocketHashItem; PSocketHashItem = ^TSocketHashItem; TSocketHashItem = record Next: PSocketHashItem; Key : TSocket; Value:Pointer; end; TSocketHash = class private FBucketPool:array of PSocketHashItem; Buckets: array of PSocketHashItem; function NewBucket():PSocketHashItem; procedure DisposeBucket(Value:PSocketHashItem); protected function Find(const Key: TSocket): PPSocketHashItem; function HashOf(const Key: TSocket): Cardinal; virtual; public constructor Create(Size: Cardinal = 256); destructor Destroy; override; function Add(const Key: TSocket; Value: Pointer):Integer; procedure Clear; procedure Remove(const Key: TSocket); function Modify(const Key: TSocket; Value: Pointer): Boolean; function ValueOf(const Key: TSocket): Pointer; end; TThreadSocketHash = class private FObj:TSocketHash; FCS:TCriticalSection; procedure Lock(); procedure UnLock(); public constructor Create(Size: Cardinal = 256); destructor Destroy; override; function Add(const Key: TSocket; Value: Pointer):Integer; procedure Clear; procedure Remove(const Key: TSocket); function Modify(const Key: TSocket; Value: Pointer): Boolean; function ValueOf(const Key: TSocket): Pointer; function GetAndRemove(const Key:TSocket):Pointer; end; implementation function TSocketHash.Add(const Key: TSocket; Value: Pointer):Integer; var Hash: Integer; Bucket: PSocketHashItem; begin Bucket:= NewBucket(); if Bucket <> nil then begin Hash := HashOf(Key) mod Cardinal(Length(Buckets)); Bucket^.Key := Key; Bucket^.Value := Value; Bucket^.Next := Buckets[Hash]; Buckets[Hash] := Bucket; Result := Hash; end else Result := -1;//空间满 end; procedure TSocketHash.Clear; var I: Integer; P, N: PSocketHashItem; begin for I := 0 to Length(Buckets) - 1 do begin P := Buckets[I]; while P <> nil do begin N := P^.Next; DisposeBucket(P); P := N; end; Buckets[I] := nil; end; end; constructor TSocketHash.Create(Size: Cardinal); var Index:Integer; PH:PSocketHashItem; begin inherited Create; SetLength(Buckets, Size); SetLength(FBucketPool,Size); //:array of PSocketHashItem; for Index := Low(FBucketPool) to High(FBucketPool) do begin New(PH); PH^.Next := nil; PH^.Key := 0; PH^.Value := nil; FBucketPool[Index] := PH; end; end; destructor TSocketHash.Destroy; var Index:Integer; P:PSocketHashItem; begin Clear; for Index := Low(FBucketPool) to High(FBucketPool) do begin P := FBucketPool[Index]; if P <> nil then Dispose(P); end; inherited Destroy; end; procedure TSocketHash.DisposeBucket(Value: PSocketHashItem); var Index:Integer; begin for Index := Low(FBucketPool) to High(FBucketPool) do begin if FBucketPool[Index] = nil then begin FBucketPool[Index] := Value; Break; end; end; end; function TSocketHash.Find(const Key: TSocket): PPSocketHashItem; var Hash: Integer; begin Hash := HashOf(Key) mod Cardinal(Length(Buckets)); Result := @Buckets[Hash]; while Result^ <> nil do begin if Result^.Key = Key then Exit else Result := @Result^.Next; end; end; function TSocketHash.HashOf(const Key: TSocket): Cardinal; var I: Integer; P: PByte; begin Result := 0; P := @Key; for I := 1 to SizeOf(Key) do begin Result := ((Result shl 2) or (Result shr (SizeOf(Result) * 8 - 2))) xor P^; Inc(P); end; end; function TSocketHash.Modify(const Key: TSocket; Value: Pointer): Boolean; var P: PSocketHashItem; begin P := Find(Key)^; if P <> nil then begin Result := True; P^.Value := Value; end else Result := False; end; function TSocketHash.NewBucket: PSocketHashItem; var Index:Integer; begin Result := nil; for Index := Low(FBucketPool) to High(FBucketPool) do begin Result := FBucketPool[Index]; if Result <> nil then begin FBucketPool[Index] := nil; Break; end; end; end; procedure TSocketHash.Remove(const Key: TSocket); var P: PSocketHashItem; Prev: PPSocketHashItem; begin Prev := Find(Key); P := Prev^; if P <> nil then begin Prev^ := P^.Next; DisposeBucket(P); end; end; function TSocketHash.ValueOf(const Key: TSocket): Pointer; var P: PSocketHashItem; begin P := Find(Key)^; if P <> nil then Result := P^.Value else Result := nil;// -1; end; { TThreadSocketHash } function TThreadSocketHash.Add(const Key: TSocket; Value: Pointer):Integer; begin Lock(); try Result := FObj.Add(Key,Value); finally UnLock(); end; end; procedure TThreadSocketHash.Clear; begin Lock(); try FObj.Clear(); finally UnLock(); end; end; constructor TThreadSocketHash.Create(Size: Cardinal); begin FObj := TSocketHash.Create(Size); FCS := TCriticalSection.Create(); end; destructor TThreadSocketHash.Destroy; begin FCS.Free(); FObj.Free(); inherited; end; function TThreadSocketHash.GetAndRemove(const Key: TSocket): Pointer; begin Lock(); try Result := FObj.ValueOf(Key); FObj.Remove(Key); finally UnLock(); end; end; procedure TThreadSocketHash.Lock; begin FCS.Enter(); end; function TThreadSocketHash.Modify(const Key: TSocket; Value: Pointer): Boolean; begin Lock(); try Result := FObj.Modify(Key,Value); finally UnLock(); end; end; procedure TThreadSocketHash.Remove(const Key: TSocket); begin Lock(); try FObj.Remove(Key); finally UnLock(); end; end; procedure TThreadSocketHash.UnLock; begin FCS.Leave(); end; function TThreadSocketHash.ValueOf(const Key: TSocket): Pointer; begin Lock(); try Result := FObj.ValueOf(Key); finally UnLock(); end; end; end.
本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/p/14640889.html