zoukankan      html  css  js  c++  java
  • 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.
    

      

  • 相关阅读:
    Java数组(1):数组与多维数组
    Java内部类(5):应用例
    Java内部类(4):静态内部类&接口内部类
    Java内部类(3):局部内部类
    Java内部类(2):普通的成员内部类
    Java内部类(1):概述
    Java中验证编码格式的一种方法
    Mybatis高级结果映射
    Mybatis Guide
    Java泛型(11):潜在类型机制
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/13644548.html
Copyright © 2011-2022 走看看