delphi的hashmap
delphi的hashmap
/// 支持D7,更低版本没有测试,支持跨OS
unit hashMap;
interface
uses
SysUtils;
type
PHashData = ^THashData;
THashData = record
KeyS: string;
KeyI: Int64;
Next: PHashData;
Data: Pointer;
end;
THashMap = class
private
FBucketsSize: Cardinal; // 桶大小
FBuckets: array of PHashData; // 桶
public
constructor Create(BucketsSize: Cardinal = 20000);
destructor destroy; override;
public
procedure SetValue(const key: string; val: Pointer); overload;
procedure SetValue(const key: integer; val: Pointer); overload;
function GetValue(const key: string; var val: Pointer): Boolean; overload;
function GetValue(const key: Integer; var val: Pointer): Boolean; overload;
end;
function hashOf(const p: Pointer; l: Integer): Integer; overload;
function hashOf(const s: string): Integer; overload;
implementation
function hashOf(const p: Pointer; l: Integer): Integer; overload;
var
ps: PInteger;
lr: Integer;
begin
Result := 0;
if l > 0 then
begin
ps := p;
lr := (l and $03);
l := (l and $FFFFFFFC);
while l > 0 do
begin
Result := ((Result shl 5) or (Result shr 27)) xor ps^;
Inc(ps);
Dec(l, 4);
end;
if lr <> 0 then
begin
l := 0;
Move(ps^, l, lr);
Result := ((Result shl 5) or (Result shr 27)) xor l;
end;
end;
end;
function hashOf(const s: string): Integer; overload;
begin
Result := hashOf(PChar(s), Length(s) * SizeOf(Char));
end;
{ THashMap }
constructor THashMap.Create(BucketsSize: Cardinal = 20000);
var
i: Integer;
begin
FBucketsSize := BucketsSize;
SetLength(FBuckets, FBucketsSize);
for i := 0 to FBucketsSize - 1 do
FBuckets[i] := nil;
end;
destructor THashMap.destroy;
var
I: Integer;
item, lNext: PHashData;
begin
for I := 0 to High(FBuckets) do
begin
lNext := FBuckets[I];
while lNext <> nil do
begin
item := lNext;
lNext := lNext.Next;
Dispose(item);
end;
end;
inherited;
end;
function THashMap.GetValue(const key: string; var val: Pointer): Boolean;
var
Idx: Cardinal;
Rec: PHashData;
HashV: Cardinal;
begin
Result := False;
HashV := Cardinal(hashOf(key));
Idx := HashV mod Cardinal(FBucketsSize);
Rec := FBuckets[Idx];
while Assigned(Rec) do
begin
if Rec.KeyS = key then
begin
val := Rec.Data;
Result := True;
Break;
end;
Rec := Rec.Next;
end;
end;
procedure THashMap.SetValue(const key: string; val: Pointer);
var
Idx: Integer;
Rec, MatchtedRec: PHashData;
hashVal: Cardinal;
begin
hashVal := Cardinal(hashof(key));
Idx := hashVal mod Cardinal(FBucketsSize);
Rec := FBuckets[Idx];
MatchtedRec := nil;
while Assigned(Rec) do
begin
if Rec.KeyS = key then
begin
MatchtedRec := Rec;
Break;
end;
Rec := Rec.Next;
end;
if MatchtedRec <> nil then
begin
MatchtedRec.Data := val;
end
else
begin
New(MatchtedRec);
MatchtedRec.KeyS := key;
MatchtedRec.Data := val;
MatchtedRec.Next := FBuckets[Idx];
FBuckets[Idx] := MatchtedRec;
end;
end;
function THashMap.GetValue(const key: Integer; var val: Pointer): Boolean;
var
Idx: Cardinal;
Rec: PHashData;
begin
Result := False;
Idx := Cardinal(key) mod FBucketsSize;
Rec := FBuckets[Idx];
while Assigned(Rec) do
begin
if Rec.KeyI = key then
begin
val := Rec.Data;
Result := True;
Break;
end;
Rec := Rec.Next;
end;
end;
procedure THashMap.SetValue(const key: integer; val: Pointer);
var
Idx: Integer;
Rec, MatchtedRec: PHashData;
begin
Idx := Cardinal(key) mod Cardinal(FBucketsSize);
Rec := FBuckets[Idx];
MatchtedRec := nil;
while Assigned(Rec) do
begin
if Rec.KeyI = key then
begin
MatchtedRec := Rec;
Break;
end;
Rec := Rec.Next;
end;
if MatchtedRec <> nil then
begin
MatchtedRec.Data := val;
end
else
begin
GetMem(MatchtedRec, SizeOf(THashData));
MatchtedRec.KeyI := key;
MatchtedRec.Data := val;
MatchtedRec.Next := FBuckets[Idx];
FBuckets[Idx] := MatchtedRec;
end;
end;
end.
本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/p/13644548.html

浙公网安备 33010602011771号