zoukankan      html  css  js  c++  java
  • 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.
    

      

  • 相关阅读:
    [论文理解] MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications
    [论文理解] Connectionist Text Proposal Network
    [期末复习] 数据结构期末复习
    [机器视觉] 实际场景字提取
    [论文理解]Deep Residual Learning for Image Recognition
    [学习笔记] AD笔记
    [OpenMP] 并行计算入门
    [Docker] Docker安装和简单指令
    python初级装饰器编写
    web页面简单布局的修改,测试中的应用
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/14640889.html
Copyright © 2011-2022 走看看