📄 复件 udihasmapclientchannel.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 + -