沙吊 發表於 2020-9-10 11:08:00

delphi的hashmap

<p>delphi的hashmap</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">/// 支持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 &gt; 0 then
begin
    ps := p;
    lr := (l and $03);
    l := (l and $FFFFFFFC);
    while l &gt; 0 do
    begin
      Result := ((Result shl 5) or (Result shr 27)) xor ps^;
      Inc(ps);
      Dec(l, 4);
    end;
    if lr &lt;&gt; 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 := nil;
end;

destructor THashMap.destroy;
var
I: Integer;
item, lNext: PHashData;
begin
for I := 0 to High(FBuckets) do
begin
    lNext := FBuckets;
    while lNext &lt;&gt; 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;
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;
MatchtedRec := nil;
while Assigned(Rec) do
begin
    if Rec.KeyS = key then
    begin
      MatchtedRec := Rec;
      Break;
    end;
    Rec := Rec.Next;
end;
if MatchtedRec &lt;&gt; nil then
begin
    MatchtedRec.Data := val;
end
else
begin
    New(MatchtedRec);
    MatchtedRec.KeyS := key;
    MatchtedRec.Data := val;
    MatchtedRec.Next := FBuckets;
    FBuckets := 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;
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;
MatchtedRec := nil;
while Assigned(Rec) do
begin
    if Rec.KeyI = key then
    begin
      MatchtedRec := Rec;
      Break;
    end;
    Rec := Rec.Next;
end;
if MatchtedRec &lt;&gt; nil then
begin
    MatchtedRec.Data := val;
end
else
begin
    GetMem(MatchtedRec, SizeOf(THashData));
    MatchtedRec.KeyI := key;
    MatchtedRec.Data := val;
    MatchtedRec.Next := FBuckets;
    FBuckets := MatchtedRec;
end;
end;

end.
</pre>
</div>
<p>  </p>

</div>
<div id="MySignature" role="contentinfo">
    <p>本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/p/13644548.html</p><br><br>
来源:https://www.cnblogs.com/hnxxcxg/p/13644548.html
頁: [1]
查看完整版本: delphi的hashmap