通信服务器哈希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 ...
随机推荐
- 安装Android模拟器Genymotion【Android学习入门】
安装Android模拟器Genymotion 推荐教程:一个强大的Android模拟器Genymotion具体内容如下: 相信很多Android开发者一定受够了速度慢.体验差效率及其地下的官方模拟器了 ...
- [转]linux tcp/ip调优
LINUX tcp/ip性能调优 On 2011年03月15日, in linux, tips, by netoearth 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接 ...
- java之Socket传递图片
客户端: package client; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import ...
- Typora使用
Typora使用 1.介绍 typora是一款不错的软件. 1.1 基本使用 html js css python java vb 1.2 无序列表 a b c d e f 1.3 java代码 pu ...
- Canvas 中drawImage 绘制不出图片
在使用Canvas的drawImage绘制图片时,却发现绘制不出图片,原因是图片是异步加载,图片加载完再绘制. //html <img src="1.png" /> & ...
- 开源框架 epics,开源画面编辑软件 edm
epics Experimental Physics and Industrial Control System 一套开源软件框架,实验物理和工业控制系统 http://www.aps.anl.gov ...
- nodejs的一些概念
上一节我们几乎是扫通http请求和响应的整个闭环,包括请求时候的头信息和服务器返回时候的头信息和状态码等等,这些在node的http中都能获取到,并且有相应都接口组装这些信息和返回它们,同时这些htt ...
- 【转】Android开发学习笔记(一)——初识Android
对于一名程序员来说,“自顶向下”虽然是一种最普通不过的分析问题和解决问题的方式,但其却是简单且较为有效的一种.所以,将其应用到Android的学习中来,不至于将自己的冲动演变为一种盲目和不知所措. 根 ...
- list 用法的随手记
在list 用法中.1. add是直接添加 一个变量.不能添加一个 集合元素,比如数组 这种写法是错误的 ,因为不能添加集合 这种写法是对的,因为直接添加元素 2. 但是addrannge 是添加一个 ...
- EF 连接数据库 Mysql (database first ) 一个表对应一个模型
准备工作 1.下载vs2015 2.下载mysql2017 3.安装 1.创建数据库 2. 将数据库映射成模型 3创建aspx 文件. 写下窗体内容的代码 hello_worldEntities en ...