通信服务器哈希Socket查找(Delphi)
在Socket通信服务器的开发中,我们经常会需要Socket与某个结构体指针进行绑定。当连接量很大时,意味着需要个高效的查找方法
Delphi中提供了哈希算法类,以此类为基础,修改出Socket专用Map类。
源码下载 http://files.cnblogs.com/lwm8246/uSocketHash.rar
unit uSocketHash; //-- :
5
interface uses SyncObjs; type
{$IF CompilerVersion >= 22} //XE=,=
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 = );
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 = );
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 { TStringHash } 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 := -;//空间满
end; procedure TSocketHash.Clear;
var
I: Integer;
P, N: PSocketHashItem;
begin
for I := to Length(Buckets) - do
begin
P := Buckets[I];
while P <> nil do
begin
N := P^.Next;
// Dispose(P);
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 := ;
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 := ;
P := @Key;
//for I := to Length(Key) do
for I := to SizeOf(Key) do
begin
Result := ((Result shl ) or (Result shr (SizeOf(Result) * - ))) xor P^;
Inc(P);
end;
//Ord(Key[I]);P^
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;
//Dispose(P);
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;// -;
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
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.
通信服务器哈希Socket查找(Delphi)的更多相关文章
- 哈希表查找(散列表查找) c++实现HashMap
算法思想: 哈希表 什么是哈希表 在前面讨论的各种结构(线性表.树等)中,记录在结构中的相对位置是随机的,和记录的关键字之间不存在确定的关系,因此,在结构中查找记录时需进行一系列和关键字的比较.这一类 ...
- HDU 4334 Trouble(哈希|线性查找)
给定五个集合.问是否能从五个集合各取一个元素,使得元素之和为0. 这道题有两种做法,一种是哈希,然而之前没写过哈希.....比赛后从大神那copy了一份. 这里说还有一种. 对于这五个集合分为三组.1 ...
- DLL里面socket(Delphi的代码)
http://hi.baidu.com/game_base/item/f617e4136414148889a956ed 本文简单介绍了当前Windows支持的各种Socket I/O模型,如果你发 ...
- Delphi的Socket编程步骤(repulish)
转贴自:http://topic.csdn.net/t/20010727/16/212155.html ClientSocket 和ServerSocket几个重要的属性: 1.client和se ...
- Delphi的Socket编程步骤
ClientSocket 和ServerSocket几个重要的属性: 1.client和server都有port属性,需要一致才能互相通信 2.client有Address属性,使用时填写对方 ...
- poj 3349:Snowflake Snow Snowflakes(哈希查找,求和取余法+拉链法)
Snowflake Snow Snowflakes Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 30529 Accep ...
- 利用Delphi编写Socket通信程序
一.Delphi与Socket 计算机网络是由一系列网络通信协议组成的,其中的核心协议是传输层的TCP/IP和UDP协议.TCP是面向连接的,通信双方保持一条通路,好比目前的电话线,使用telnet登 ...
- 查找->动态查找表->哈希表
文字描述 哈希表定义 在前面讨论的各种查找算法中,都是建立在“比较”的基础上.记录的关键字和记录在结构中的相对位置不存在确定的关系,查找的效率依赖于查找过程中所进行的比较次数.而理想的情况是希望不经过 ...
- Delphi与Socket
一.Delphi与Socket计算机网络是由一系列网络通信协议组成的,其中的核心协议是传输层的TCPIP和UDP协议.TCP是面向连接的,通信双方保持一条通路,好比目前的电话线,使用telnet登陆B ...
随机推荐
- spring boot Configuration Annotation Proessor not found in classpath
出现spring boot Configuration Annotation Proessor not found in classpath的提示是在用了@ConfigurationPropertie ...
- centreon公司推出的check plugin pack
文档 http://documentation.centreon.com/docs/centreon-plugins/en/latest/ (epel) # yum install nagios-pl ...
- springboot/springmvc转换器
常用的转换器 String转Date转换器(用于接受日期参数自动转换成Date类型便于后台数据处理) /** * 全局handler前日期统一处理 * @author zhanghang * @dat ...
- CentOS 7.0 各版本下载说明 新增Everything版
CentOS-7.0-1406有很多可供选择的版本,对初学者来说,不知如何选择,下面做简单的介绍: CentOS-7.0-1406-x86_64-DVD.iso 标准安装版,一般下载这个就可以了 Ce ...
- mysql : 修改数据库权限
解决步骤 第一步,点击用户 注意!!! 编辑权限,在我们设置权限之前,我们需要先重新加载才能生效, 如果不用编辑的话,直接按重新载入编辑,这个相当于保存. 中文意思(注意看那段话) 第二步 选择要处理 ...
- Last_IO_Errno: 1062
主键冲突的错误 1062 模拟错误: 在主库上操作: create table test100(id int not null,name varchar(20),primary key(id) ...
- 空间最短路径,BFS(POJ3278)
题目链接:http://poj.org/problem?id=3278 #include <cstdio> #include <queue> #include <stri ...
- caffe RandomOrderChannels
就是将rgb图的3个channel随机打乱顺序,给定一个概率值是否执行这个操作,v系列模型的概率一般都设置的为0 void RandomOrderChannels(const cv::Mat& ...
- Linux下C程序进程地址空间布局[转]
我们在学习C程序开发时经常会遇到一些概念:代码段.数据段.BSS段(Block Started by Symbol) .堆(heap)和栈(stack).先看一张教材上的示意图(来源,<UNIX ...
- centos安装django
1.如果默认安装的是python2.6,先升级至python2.7 参考:http://www.cnblogs.com/tiger2soft/p/5677843.html 2.安装pip 先下载get ...