在Socket通信服务器的开发中,我们经常会需要Socket与某个结构体指针进行绑定。当连接量很大时,意味着需要个高效的查找方法

Delphi中提供了哈希算法类,以此类为基础,修改出Socket专用Map类。

源码下载 http://files.cnblogs.com/lwm8246/uSocketHash.rar

 unit uSocketHash;

 //-- :
//QQ
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)的更多相关文章

  1. 哈希表查找(散列表查找) c++实现HashMap

    算法思想: 哈希表 什么是哈希表 在前面讨论的各种结构(线性表.树等)中,记录在结构中的相对位置是随机的,和记录的关键字之间不存在确定的关系,因此,在结构中查找记录时需进行一系列和关键字的比较.这一类 ...

  2. HDU 4334 Trouble(哈希|线性查找)

    给定五个集合.问是否能从五个集合各取一个元素,使得元素之和为0. 这道题有两种做法,一种是哈希,然而之前没写过哈希.....比赛后从大神那copy了一份. 这里说还有一种. 对于这五个集合分为三组.1 ...

  3. DLL里面socket(Delphi的代码)

    http://hi.baidu.com/game_base/item/f617e4136414148889a956ed   本文简单介绍了当前Windows支持的各种Socket I/O模型,如果你发 ...

  4. Delphi的Socket编程步骤(repulish)

    转贴自:http://topic.csdn.net/t/20010727/16/212155.html ClientSocket 和ServerSocket几个重要的属性:   1.client和se ...

  5. Delphi的Socket编程步骤

    ClientSocket 和ServerSocket几个重要的属性:   1.client和server都有port属性,需要一致才能互相通信   2.client有Address属性,使用时填写对方 ...

  6. poj 3349:Snowflake Snow Snowflakes(哈希查找,求和取余法+拉链法)

    Snowflake Snow Snowflakes Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 30529   Accep ...

  7. 利用Delphi编写Socket通信程序

    一.Delphi与Socket 计算机网络是由一系列网络通信协议组成的,其中的核心协议是传输层的TCP/IP和UDP协议.TCP是面向连接的,通信双方保持一条通路,好比目前的电话线,使用telnet登 ...

  8. 查找->动态查找表->哈希表

    文字描述 哈希表定义 在前面讨论的各种查找算法中,都是建立在“比较”的基础上.记录的关键字和记录在结构中的相对位置不存在确定的关系,查找的效率依赖于查找过程中所进行的比较次数.而理想的情况是希望不经过 ...

  9. Delphi与Socket

    一.Delphi与Socket计算机网络是由一系列网络通信协议组成的,其中的核心协议是传输层的TCPIP和UDP协议.TCP是面向连接的,通信双方保持一条通路,好比目前的电话线,使用telnet登陆B ...

随机推荐

  1. wait/notify

    某面试题,实现一个生产者——消费者模型 题目:采用多线程技术,通过wait/notify,设计实现一个符合生产者和消费者问题的程序,对某一个对象(枪膛)进行操作,其最大容量是20颗子弹,生产者线程是一 ...

  2. SQLServer查询语句收集

    常用的SQLServer查询语句,有空可以多练习一下,增加记忆,可以提高工作效率! 1.数据操作 Select      --从数据库表中检索数据行和列Insert      --向数据库表添加新数据 ...

  3. java读取指定package下的所有class

     JAVA如何扫描一个包下面的所有类,并加载到内存中去? spring中有一个<context:component-scan base-package="com.controller& ...

  4. 洛谷 P2814 家谱

    题目背景 现代的人对于本家族血统越来越感兴趣. 题目描述 给出充足的父子关系,请你编写程序找到某个人的最早的祖先. 输入输出格式 输入格式: 输入由多行组成,首先是一系列有关父子关系的描述,其中每一组 ...

  5. ERP和C4C中的function location

    SAP ERP里的Functional Locations,下载到SAP Cloud for Customer后成为类型为'Functional Location'的Installation Poin ...

  6. .net core 2.0以上版本加载appsettings.json

    这里需要的一个关键类: Microsoft.Extensions.Configuration; 可以从nuget包获得 如果缺少该类,会造成无法实例化调用方法: ConfigurationBuilde ...

  7. NYOJ(325)+NYOJ(456),01背包

    题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=325 http://acm.nyist.net/JudgeOnline/problem. ...

  8. PHP APC安装与使用

    先要解决一下httpd-devel依赖库问题 yum install cyrus-sasl-devel db4-devel openldap apr apr-util apr-util-devel p ...

  9. sublime text 3 python 控制台输出中文乱码解决方案

    自建的python运行环境如下:python3 找到python3.sublime-build文件打开,在文件中加入"env": { "PYTHONIOENCODING& ...

  10. 某寺庙,有小和尚、老和尚若干。有一水缸,由小和尚用水桶从井中提水入缸,老和尚用水桶从缸里取水饮用。水缸可容10桶水,水取自同一井中。水井径窄,每次只能容一个水桶取水。水桶总数为3个。每次入、取缸水仅为1桶,且不可以同时进行。试用P、V操作给出小和尚、老和尚动作的算法描述。

    寺庙和尚打水 设信号量mutex_gang, mutex_jing, gang_empty, gang_full, count分别表示使用缸互斥, 使用井互斥, 缸空, 缸满, 水桶总个数 semap ...