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

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

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

  1. unit uSocketHash;
  2.  
  3. //-- :
  4. //QQ
    5
  5. interface
  6.  
  7. uses SyncObjs;
  8.  
  9. type
  10. {$IF CompilerVersion >= 22} //XE=,=
  11. TSocket = NativeUInt;
  12. {$ELSE}
  13. TSocket = Integer;
  14. {$IFEND}
  15.  
  16. PPSocketHashItem = ^PSocketHashItem;
  17. PSocketHashItem = ^TSocketHashItem;
  18. TSocketHashItem = record
  19. Next: PSocketHashItem;
  20. Key : TSocket;
  21. Value:Pointer;
  22. end;
  23.  
  24. TSocketHash = class
  25. private
  26. FBucketPool:array of PSocketHashItem;
  27. Buckets: array of PSocketHashItem;
  28. function NewBucket():PSocketHashItem;
  29. procedure DisposeBucket(Value:PSocketHashItem);
  30. protected
  31. function Find(const Key: TSocket): PPSocketHashItem;
  32. function HashOf(const Key: TSocket): Cardinal; virtual;
  33. public
  34. constructor Create(Size: Cardinal = );
  35. destructor Destroy; override;
  36. function Add(const Key: TSocket; Value: Pointer):Integer;
  37. procedure Clear;
  38. procedure Remove(const Key: TSocket);
  39. function Modify(const Key: TSocket; Value: Pointer): Boolean;
  40. function ValueOf(const Key: TSocket): Pointer;
  41. end;
  42.  
  43. TThreadSocketHash = class //线程安全
  44. private
  45. FObj:TSocketHash;
  46. FCS:TCriticalSection;
  47. procedure Lock();
  48. procedure UnLock();
  49. public
  50. constructor Create(Size: Cardinal = );
  51. destructor Destroy; override;
  52. function Add(const Key: TSocket; Value: Pointer):Integer;
  53. procedure Clear;
  54. procedure Remove(const Key: TSocket);
  55. function Modify(const Key: TSocket; Value: Pointer): Boolean;
  56. function ValueOf(const Key: TSocket): Pointer;
  57. function GetAndRemove(const Key:TSocket):Pointer;
  58. end;
  59.  
  60. implementation
  61.  
  62. { TStringHash }
  63.  
  64. function TSocketHash.Add(const Key: TSocket; Value: Pointer):Integer;
  65. var
  66. Hash: Integer;
  67. Bucket: PSocketHashItem;
  68. begin
  69. Bucket:= NewBucket();
  70. if Bucket <> nil then
  71. begin
  72. Hash := HashOf(Key) mod Cardinal(Length(Buckets));
  73. Bucket^.Key := Key;
  74. Bucket^.Value := Value;
  75. Bucket^.Next := Buckets[Hash];
  76. Buckets[Hash] := Bucket;
  77. Result := Hash;
  78. end
  79. else Result := -;//空间满
  80. end;
  81.  
  82. procedure TSocketHash.Clear;
  83. var
  84. I: Integer;
  85. P, N: PSocketHashItem;
  86. begin
  87. for I := to Length(Buckets) - do
  88. begin
  89. P := Buckets[I];
  90. while P <> nil do
  91. begin
  92. N := P^.Next;
  93. // Dispose(P);
  94. DisposeBucket(P);
  95. P := N;
  96. end;
  97. Buckets[I] := nil;
  98. end;
  99. end;
  100.  
  101. constructor TSocketHash.Create(Size: Cardinal);
  102. var
  103. Index:Integer;
  104. PH:PSocketHashItem;
  105. begin
  106. inherited Create;
  107. SetLength(Buckets, Size);
  108. //\\
  109. SetLength(FBucketPool,Size); //:array of PSocketHashItem;
  110. for Index := Low(FBucketPool) to High(FBucketPool) do
  111. begin
  112. New(PH);
  113. PH^.Next := nil;
  114. PH^.Key := ;
  115. PH^.Value := nil;
  116. FBucketPool[Index] := PH;
  117. end;
  118. end;
  119.  
  120. destructor TSocketHash.Destroy;
  121. var
  122. Index:Integer;
  123. P:PSocketHashItem;
  124. begin
  125. Clear;
  126. for Index := Low(FBucketPool) to High(FBucketPool) do
  127. begin
  128. P := FBucketPool[Index];
  129. if P <> nil then Dispose(P);
  130. end;
  131. inherited Destroy;
  132. end;
  133.  
  134. procedure TSocketHash.DisposeBucket(Value: PSocketHashItem);
  135. var
  136. Index:Integer;
  137. begin
  138. for Index := Low(FBucketPool) to High(FBucketPool) do
  139. begin
  140. if FBucketPool[Index] = nil then
  141. begin
  142. FBucketPool[Index] := Value;
  143. Break;
  144. end;
  145. end;
  146. end;
  147.  
  148. function TSocketHash.Find(const Key: TSocket): PPSocketHashItem;
  149. var
  150. Hash: Integer;
  151. begin
  152. Hash := HashOf(Key) mod Cardinal(Length(Buckets));
  153. Result := @Buckets[Hash];
  154. while Result^ <> nil do
  155. begin
  156. if Result^.Key = Key then
  157. Exit
  158. else
  159. Result := @Result^.Next;
  160. end;
  161. end;
  162.  
  163. function TSocketHash.HashOf(const Key: TSocket): Cardinal;
  164. var
  165. I: Integer;
  166. P: PByte;
  167. begin
  168. Result := ;
  169. P := @Key;
  170. //for I := to Length(Key) do
  171. for I := to SizeOf(Key) do
  172. begin
  173. Result := ((Result shl ) or (Result shr (SizeOf(Result) * - ))) xor P^;
  174. Inc(P);
  175. end;
  176. //Ord(Key[I]);P^
  177. end;
  178.  
  179. function TSocketHash.Modify(const Key: TSocket; Value: Pointer): Boolean;
  180. var
  181. P: PSocketHashItem;
  182. begin
  183. P := Find(Key)^;
  184. if P <> nil then
  185. begin
  186. Result := True;
  187. P^.Value := Value;
  188. end
  189. else
  190. Result := False;
  191. end;
  192.  
  193. function TSocketHash.NewBucket: PSocketHashItem;
  194. var
  195. Index:Integer;
  196. begin
  197. Result := nil;
  198. for Index := Low(FBucketPool) to High(FBucketPool) do
  199. begin
  200. Result := FBucketPool[Index];
  201. if Result <> nil then
  202. begin
  203. FBucketPool[Index] := nil;
  204. Break;
  205. end;
  206. end;
  207. end;
  208.  
  209. procedure TSocketHash.Remove(const Key: TSocket);
  210. var
  211. P: PSocketHashItem;
  212. Prev: PPSocketHashItem;
  213. begin
  214. Prev := Find(Key);
  215. P := Prev^;
  216. if P <> nil then
  217. begin
  218. Prev^ := P^.Next;
  219. //Dispose(P);
  220. DisposeBucket(P);
  221. end;
  222. end;
  223.  
  224. function TSocketHash.ValueOf(const Key: TSocket): Pointer;
  225. var
  226. P: PSocketHashItem;
  227. begin
  228. P := Find(Key)^;
  229. if P <> nil then
  230. Result := P^.Value
  231. else
  232. Result := nil;// -;
  233. end;
  234.  
  235. { TThreadSocketHash }
  236.  
  237. function TThreadSocketHash.Add(const Key: TSocket; Value: Pointer):Integer;
  238. begin
  239. Lock();
  240. try
  241. Result := FObj.Add(Key,Value);
  242. finally
  243. UnLock();
  244. end;
  245. end;
  246.  
  247. procedure TThreadSocketHash.Clear;
  248. begin
  249. Lock();
  250. try
  251. FObj.Clear();
  252. finally
  253. UnLock();
  254. end;
  255. end;
  256.  
  257. constructor TThreadSocketHash.Create(Size: Cardinal);
  258. begin
  259. FObj := TSocketHash.Create(Size);
  260. FCS := TCriticalSection.Create();
  261. end;
  262.  
  263. destructor TThreadSocketHash.Destroy;
  264. begin
  265. FCS.Free();
  266. FObj.Free();
  267. inherited;
  268. end;
  269.  
  270. function TThreadSocketHash.GetAndRemove(const Key: TSocket): Pointer;
  271. begin
  272. Lock();
  273. try
  274. Result := FObj.ValueOf(Key);
  275. FObj.Remove(Key);
  276. finally
  277. UnLock();
  278. end;
  279. end;
  280.  
  281. procedure TThreadSocketHash.Lock;
  282. begin
  283. FCS.Enter();
  284. end;
  285.  
  286. function TThreadSocketHash.Modify(const Key: TSocket; Value: Pointer): Boolean;
  287. begin
  288. Lock();
  289. try
  290. FObj.Modify(Key,Value);
  291. finally
  292. UnLock();
  293. end;
  294. end;
  295.  
  296. procedure TThreadSocketHash.Remove(const Key: TSocket);
  297. begin
  298. Lock();
  299. try
  300. FObj.Remove(Key);
  301. finally
  302. UnLock();
  303. end;
  304. end;
  305.  
  306. procedure TThreadSocketHash.UnLock;
  307. begin
  308. FCS.Leave();
  309. end;
  310.  
  311. function TThreadSocketHash.ValueOf(const Key: TSocket): Pointer;
  312. begin
  313. Lock();
  314. try
  315. Result := FObj.ValueOf(Key);
  316. finally
  317. UnLock();
  318. end;
  319. end;
  320.  
  321. 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. C# 图像快速转化成byte[]和计算像素值

    public static unsafe byte[] ConvertTo8Byte(Bitmap img) { byte[] result = new byte[img.Width * img.He ...

  2. DNN学习笔记 最简单的皮肤制作

    说明: 在学习DNN时,使用的版本为 DNN8.参考资料:http://www.dnnsoftware.com/docs/designers/creating-themes/index.html 制作 ...

  3. 初次搭建spring boot 项目(实验楼-学习笔记)

    首先说一下springboot 的优点: 使用Spring Initializr可以在几秒钟就配置好一个Spring Boot应用. 对大量的框架都可以无缝集成,基本不需要配置或者很少的配置就可以运行 ...

  4. CDSN博客第一天

    CDSN博客第一天 今天是CSDN写博客的第一天. 2017/2/11 13:05:45

  5. iOS 8 提供 TestFlight 方便开发者测试软件 (转)

    原文地址:http://tech2ipo.com/66893 TestFlight / via iMore 作者: Nick Arnott   译者:翛凌 原文:iMore  iOS 应用程序的测试对 ...

  6. C++ Knowledge series Template & Class

    Function Function is composed of name, parameter (operand, type of operand), return value, body with ...

  7. 浅谈SQL Server中的事务日志(一)----事务日志的物理和逻辑构架

    简介 SQL Server中的事务日志无疑是SQL Server中最重要的部分之一.因为SQL SERVER利用事务日志来确保持久性(Durability)和事务回滚(Rollback).从而还部分确 ...

  8. 运行python文件报SyntaxError:Non-ASCII character '\xe7'

    以下是报错内容: 在文件页头加上: #coding=uft-8 ~解决了~ 记录一下(捂脸)

  9. 百度开源项目插件 - Echarts 图表

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  10. JavaScript如何转换数据库DateTime字段类型?

    Javascript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在html(标 ...