⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 复件 udihasmapclientchannel.pas

📁 楠楠写的DBiocp例子都是源码
💻 PAS
字号:
unit uDIHasMapClientChannel;

interface

uses
  Windows, SysUtils, uCriticalSection, uDIClientChannel;

type
  //节点 Has结构
  PPClientChannelNode = ^PClientChannelNode;
  PClientChannelNode = ^TClientChannelNode;
  TClientChannelNode = record
    Next: PClientChannelNode;             //后一个节点
    Key: string;
    pDIChannel: TDIClientChannel;         //值
  end;


  //上下文管理队列
  TDIHasMapClientChannel = Class
  private
    m_nMapClientChannelCount:         DWORD;                //数量
    FHasMapClientChannelLock:         TCriticalSection;     //锁
    FClientChannelMap: array of PClientChannelNode;         //结点
  private
    function FindClientChannel(const Key: String): PPClientChannelNode;
    function HashOf(const Key: string): Cardinal; virtual;
    function GetHasCount: DWORD;
  public
    //增加
    function AddClientChannel(const Key: string; FClientChannel: TDIClientChannel): Boolean;
    function RemoveClientChannel(const Key: string): Boolean;
    function GetClientChannelCount: DWORD;
    function GetTopClientChannel: TDIClientChannel;
  public
    constructor Create;
    procedure SetHasMapSize(Size: DWORD = 65535);
    destructor Destroy; override;
  end;

implementation
  uses uFileLogger;

constructor TDIHasMapClientChannel.Create;
begin
  inherited Create;
  m_nMapClientChannelCount := 0;
  FHasMapClientChannelLock := TCriticalSection.Create;
end;

destructor TDIHasMapClientChannel.Destroy;
begin
  FreeAndNIL(FHasMapClientChannelLock);
  inherited Destroy;
end;

procedure TDIHasMapClientChannel.SetHasMapSize(Size: DWORD);
begin
  try
    FHasMapClientChannelLock.Lock;
    if Size>0 then SetLength(FClientChannelMap, Size);
  finally
    FHasMapClientChannelLock.UnLock;
  end;
end;

function TDIHasMapClientChannel.GetHasCount: DWORD;
begin
  try
    FHasMapClientChannelLock.Lock;
    Result := Length(FClientChannelMap);
  finally
    FHasMapClientChannelLock.UnLock;
  end;
end;

function TDIHasMapClientChannel.GetClientChannelCount: DWORD;
begin
  try
    FHasMapClientChannelLock.Lock;
    Result := m_nMapClientChannelCount;
  finally
    FHasMapClientChannelLock.UnLock;
  end;
end;

function TDIHasMapClientChannel.HashOf(const Key: string): Cardinal;
var
  I: Integer;
begin
  Result := 0;
  for I := 1 to Length(Key) do
  Result := ((Result shl 2) or (Result shr (SizeOf(Result) * 8 - 2))) xor Ord(Key[I]);
end;

function TDIHasMapClientChannel.AddClientChannel(const Key: string; FClientChannel: TDIClientChannel): Boolean;
var
  Hash: Integer;
  pNode: PClientChannelNode;
begin
  try
    FHasMapClientChannelLock.Lock;

    Hash := HashOf(Key) mod Cardinal(Length(FClientChannelMap));
    New(pNode);
    pNode^.Key := Key;
    pNode^.pDIChannel := FClientChannel;
    pNode^.Next := FClientChannelMap[Hash];
    FClientChannelMap[Hash] := pNode;
    //数量加一
    Inc(m_nMapClientChannelCount);
    Result := TRUE;

    _FileLogger.WriteLogMsg('AddClientChannel, Key:'+ Key +
                            ' 上下文数量:'+IntToStr(m_nMapClientChannelCount));
    
  finally
    FHasMapClientChannelLock.UnLock;
  end;
end;

function TDIHasMapClientChannel.FindClientChannel(const Key: String): PPClientChannelNode;
var
  Hash: Integer;
begin
  Hash := HashOf(Key) mod Cardinal(Length(FClientChannelMap));
  Result := @FClientChannelMap[Hash];
  while (Result^ <> nil) do
  begin
    if Result^.Key = Key then
      Break
    else
      Result := @Result^.Next;
  end;
end;

function TDIHasMapClientChannel.RemoveClientChannel(const Key: string): Boolean;
var
  pNode: PClientChannelNode;
  pPrevNode: PPClientChannelNode;
begin
  try
    FHasMapClientChannelLock.Lock;

    pPrevNode := FindClientChannel(Key);
    pNode := pPrevNode^;
    if pNode <> nil then
    begin
      //返回值
      Result := TRUE;

      //删除节点
      pPrevNode^ := pNode^.Next;
      Dispose(pNode);
      //数量减一
      Dec(m_nMapClientChannelCount);

       _FileLogger.WriteLogMsg('RemoveClientChannel成功, Key:'+ Key +
                               ' 上下文数量:'+IntToStr(m_nMapClientChannelCount));
    end
    else
    begin
      Result := FALSE;
      _FileLogger.WriteLogMsg('RemoveClientChannel->FindClientChannel 失败, Key:'+ Key +
                             ' 上下文数量:'+IntToStr(m_nMapClientChannelCount));
    end;

   finally
    FHasMapClientChannelLock.UnLock;
  end;
end;

function TDIHasMapClientChannel.GetTopClientChannel: TDIClientChannel;
var
  i: Integer;
  pNode: PClientChannelNode;
  pPrevNode: PPClientChannelNode;
begin
  try
    FHasMapClientChannelLock.Lock;
    
    for i:=0 to 65535 do begin
      pNode := FindClientChannel(IntToStr(i))^;
      if pNode <> nil then begin
        //返回值
        Result := pNode^.pDIChannel;
        //删除节点
        pPrevNode^ := pNode^.Next;
        Dispose(pNode);
        //数量减一
        Dec(m_nMapClientChannelCount);

        Break;
      end;
    end;

   finally
    FHasMapClientChannelLock.UnLock;
  end;
end;


end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -