在Delphi7 以下版本中,我们发现库是不带HashTable这个类的,而这个类在java中被应用得风生水起。
一直想用Delphi7开发简单的数据库处理程序,但是我不想用Delphi中的那些个自动化的控件,不可控,不自由。
于是参照java,自己开发了很多类,包含字符串处理的,集合类。
对于多线程编程,队列也是一个基本类,一并开发了。自己开发的类有一个好处,就是方法随便添加,根据需要可以自由优化。那些通用的类和方法,通常性能是很差的,就如一个循环队列,Delphi本身就没有,别人开发的,测试了下,性能低得很。对于大数据量来说,线程池调度、队列等算法就很有发挥空间。
原来对java哈希表感觉很是神奇,其查询速度快得出奇,后来看了下其原理,才清楚背后的数学逻辑。
自己学着编写了一下,感觉还是不错的。对不同的hash函数进行了可视化的测试。
用一个GRID控件显示,来看下hash值分布情况,一目了然。对于不同的key类型测试,当然越均匀越好。
unit RSHashtable;
interface
uses Windows,Classes, RSBase, sysutils;
type
{ TRSHashTable }
PPRSHashItem = ^PRSHashItem; //如果采用双向链表则不需要复指针。
PRSHashItem = ^TRSHashItem;
TRSHashItem = record
Next: PRSHashItem;
Key: string;
IntValue: Integer;
StrValue: String; //double 采用string保存,FloatToStr
Objvalue: TObject;
end;
TRSHashTable = class(TRSThreadObject)
private
FItemCount:cardinal;
FArraySize: cardinal;
FMaxTableSize:cardinal;
FMulti: boolean;
FAutoGrowth:boolean; //不容许自动增长则是线程安全的。
ArrayTable: array of PRSHashItem;
function createHashItem(const Key: string):PRSHashItem;
protected
function Find(const Key: string): PPRSHashItem;
function FindByCode(hashcode:cardinal;key:String): PPRSHashItem;
function HashOf(const Key: string): Cardinal; virtual;
public
constructor Create(Size: Integer = 256; multi:boolean = false; AutoGrowth:boolean=true);
destructor Destroy; override;
function GetInteger(const Key: String): Integer;
function GetString(const Key: String): String;
function GetObject(const Key: string): TObject;
function GetItem(const key:String): TRSHashItem;
function keyExists(const Key: String): boolean;
function GetArrayTable: Pointer;
function KeyToList(key:String;isStartWithKey:boolean=false):TStringList;
function ObjValueToList():TList;overload;
function ObjValueToListEx(key:String;isStartWithKey:boolean=false):TList;overload;
function KeyStrValueToList(key:String;isStartWithKey:boolean=false):TStringList;
function KeyIntValueToList(key:String;isStartWithKey:boolean=false):TStringList;
procedure Put(const Key: string; Value:Integer);overload;
procedure Put(const Key: string; Value:String);overload;
procedure Put(const Key: string; Value:TObject);overload;
procedure Clear;
procedure Remove(const Key: string);
procedure RemoveKey(const Key: string); //不释放对象
procedure RemoveAll(const Key: string);
procedure RemoveValue(const Key: string; aValue:String);
procedure SetSize(size:Cardinal);
procedure SetMaxTableSize(const size:Cardinal);
property count:cardinal read FItemCount;
property size:cardinal read FArraySize write SetSize;
property MaxTableSize:cardinal read FMaxTableSize write SetMaxTableSize;
end;
{ Iterator 迭代器通常不用作线程共享,因此没有实现线程安全}
TIterator = class
private
FTable: TRSHashTable;
ArrayTable: array of PRSHashItem;
crtItem: PRSHashItem;
crtIndex: cardinal;
key: String;
procedure findNextLink;
public
constructor Create(table: TRSHashTable;const key:String);
function next:boolean;
function getkey:String;
function getInteger:Integer;
function getString:String;
function getObject:TObject;