⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _hashtable.inc_h

📁 Delphi Generic Algorytms library - Maps, Lists, Hashmaps, Datastructures.
💻 INC_H
字号:
(*
 * DGL(The Delphi Generic Library)
 *
 * Copyright (c) 2004
 * HouSisong@263.net
 *
 * This material is provided "as is", with absolutely no warranty expressed
 * or implied. Any use is at your own risk.
 *
 * Permission to use or copy this software for any purpose is hereby granted
 * without fee, provided the above notices are retained on all copies.
 * Permission to modify the code and to distribute modified code is granted,
 * provided the above notices are retained, and a notice that the code was
 * modified is included with the above copyright notice.
 *
 *)

//------------------------------------------------------------------------------
// _THashTableBase\_THashBaseIterator的声明
// Create by HouSisong, 2004.03.05
//------------------------------------------------------------------------------
                           
//_HashTable.inc_pas ; _HashTable.inc_h

{$ifndef __HashTable_inc_h_}
{$define __HashTable_inc_h_}

{$I DGLIntf.inc_h}

type
  _HashKeyType   = _KeyType;
  _HashValueType = _ValueType;
  _PHashValueType = ^_HashValueType;

const
  csHashKey_Error = 'Hash Key is not within the valid range.';
  //csHashIterator_Error = 'Hash iterator is not within the valid range.';
type
  EHashKeyRangeError = class(Exception);//uses SysUtils! //对不存在的元素进行删除或读取(写是合法的)时触发
  //EHashIteratorRangeError = class(Exception);

//------------------------------------------------------------------------------
// _THashTableBase

//var testTHashNodeCount:integer=0;


type  //开链hash桶(链表)
  _PPHashNode = ^_PHashNode;
  _PHashNode  = ^_THashNode;
  _THashNode = record
    PNext      : _PHashNode;
    Key        : _HashKeyType;
    Value      : _HashValueType;
  end;
  _TPHashNodeDArray=array of _PHashNode;

    _PPHashNode_OnlySet = ^_PHashNode_OnlySet;
    _PHashNode_OnlySet  = ^_THashNode_OnlySet;
    _THashNode_OnlySet = record
      PNext     : _PHashNode;
      Key       : _HashKeyType;
      //利用F_DGL_OnlySet定义节约一点内存:) 对于一些自动类型和很大的结构(Record)此优化比较有意义
    end;

const                        //32 bit
  _csHashCapacityList:array[0..32] of Cardinal=
                (
                31 ,    //1
                31 ,    //2
                31 ,    //3
                31 ,    //7
                31 ,    //13
                31 ,
                61 ,
                127 ,
                251 ,
                509 ,
                1021 ,
                2039 ,
                4093 ,
                8191 ,
                16381 ,
                32749 ,
                65521 ,
                131071 ,
                262139 ,
                524287 ,
                1048573 ,
                2097143 ,
                4194301 ,
                8388593 ,
                16777213 ,
                33554393 ,
                67108859 ,
                134217689 ,
                268435399 ,
                536870909 ,
                1073741789 ,
                2147483647 ,
                4294967291
                );
  const  _csDefaultHashCapacityIndex = 5;
  function GetBigHashCapacityIndex(const Capacity:Cardinal;const CapacityIndex:Byte=_csDefaultHashCapacityIndex):Byte;
  
type
  _THashBaseIterator = class;  //hash Iterator

  //_THashTableBase内部维护的简易迭代器
  _TTagHashIterator =  record
    ArrayIndex  : integer;
    pPNode      : _PPHashNode;
  end;

  _THashTableBase = class;
  _tmpHashIt_Data = object  //内存结构等价于:_IIterator
    _ObjIteratorClass : _DGL_TObjIteratorClass;
    FBase   : _THashTableBase;
    FNodeIt : _TTagHashIterator;
  end;
  _PtmpHashIt_Data = ^_tmpHashIt_Data;

  //----------------------------------------------------------------------------
  // 作用描述: Hash表,Hash容器的基础实现,用它可以扩展出HashSet\HashMultiSet\HashMap\HashMultiMap
  // 主要方法:SetCapacity      : 设置Hash表内的节点数组大小
  //           DecCapacity      :自动缩减Hash表内的节点数组大小
  //           CountRange       :统计有相同Key的元素个数,并返回其区间
  //           InsertNode       :插入一个新的节点,确定性的
  //           UniqueInsertNode、UniqueInsert   :如果不存该Key值则执行插入操作,否则:如果传递了Value值则替换原来的key对应的值,否则什么也不做;
  //           MultiInsertNode、MultiInsert     : 不论表中是否已经存在该Key值,执行插入操作,等价于InsertNode
  //           FindItem         :查找具有Key值的元素位置,不存在时返回ItEnd
  //           DeleteNode       :从表中删除一个节点
  //           Previous         :使_TTagHashIterator向前移动一个位置
  //           Next             :使_TTagHashIterator向后移动一个位置
  //           IsEndIt          : 判断是否是ItEnd位置
  //           IsEqualIt        :判断两个位置是否相同
  //
  //           ItBegin          :表中第一个元素的位置
  //           ItEnd            :表中最后一个元素的下一个位置
  //           Reserve          :预留元素空间
  //           Clear            :清空容器
  //           Size             :返回容器中的元素个数
  //           Capacity         :返回容器的当前容积
  //           GetItemValue     :根据Key值返回对应的Value值,如果不存在该Key值,则触发EHashKeyRangeError异常
  //           Swap             :交换两个容器中的元素
  //           remove       :删除值与Value相同的元素,返回删除的个数
  //           EraseKey         :删除键值与Key相同的元素,返回删除的个数
  //           Erase            : 删除某位置上的元素、或删除某区间内的元素
  //           Count            :统计有相同Key的元素个数
  //           FindKey          :查找某键值的第一次出现位置
  //           LowerBound       : 返回某键值的第一个可安插位置
  //           UpperBound       : 返回某键值的最后一个可安插位置
  //           EqualRange       : 返回某键值的可安插的第一个和最后一个位置
  // 使用方式:
  // 注意事项: 内部实现,外部不要直接使用
  // 作    者: HouSisong , 2004.09.08
  // [相关资料]: (如果有的话)
  // [维护记录]: (类发布后,其修改需要记录下来:修改人、时间、主要原因内容)
  //----------------------------------------------------------------------------
  _THashTableBase = class(TObject)
  private
    FDataList     : _TPHashNodeDArray;
    FCount        : Cardinal;
    FCapacity     : Cardinal;
    FCapacityIndex: Byte; //0..32
    FAlwaysReserveIndex: Byte;
    F_DGL_OnlySet : boolean;
    procedure   SetCapacityIndex(const NewCapacityIndex: Byte);
    procedure   DecCapacity();
    function    CountRange(const Key:_HashKeyType;out ItBegin,ItEnd:_TTagHashIterator):integer;
    function    getNewNode(const Key: _HashKeyType;const Value: _HashValueType): _PHashNode;overload;   {$ifdef _DGL_Inline} inline; {$endif}   //todo: Warning inline on if _ValueType if "object" then error!!!
    function    getNewNode(const Key: _HashKeyType): _PHashNode;overload;  {$ifdef _DGL_Inline} inline; {$endif}
    procedure   DisposeNode(const pHashNode: _PHashNode);   {$ifdef _DGL_Inline} inline; {$endif}
  protected
    procedure   UniqueInsertNode(pPHashNode:_PPHashNode;const Key: _HashKeyType;const Value: _HashValueType);overload;  {$ifdef _DGL_Inline} inline; {$endif}  //todo: Warning inline on if _ValueType if "object" then error!!!
    procedure   MultiInsertNode(pPHashNode: _PPHashNode;const Key: _HashKeyType;const Value: _HashValueType);  overload;   {$ifdef _DGL_Inline} inline; {$endif}   //todo: Warning inline on if _ValueType if "object" then error!!!
    procedure   UniqueInsertNode(pPHashNode:_PPHashNode;const Key: _HashKeyType);overload;     {$ifdef _DGL_Inline} inline; {$endif}
    procedure   MultiInsertNode(pPHashNode: _PPHashNode;const Key: _HashKeyType); overload;   {$ifdef _DGL_Inline} inline; {$endif}
    function    FindItem(const Key:_HashKeyType):_TTagHashIterator;     {$ifdef _DGL_Inline} inline; {$endif}
    procedure   DeleteNode(const pPHashNode: _PPHashNode);    {$ifdef _DGL_Inline} inline; {$endif}

    class procedure  Previous(const HashTable:_THashTableBase;var It : _TTagHashIterator);   {$ifdef _DGL_Inline} inline; {$endif}
    class procedure  Next(const HashTable:_THashTableBase;var It : _TTagHashIterator);       {$ifdef _DGL_Inline} inline; {$endif}
    class function   IsEndIt(const It : _TTagHashIterator):boolean;                           {$ifdef _DGL_Inline} inline; {$endif}
    class function   IsEqualIt(const It0,It1 : _TTagHashIterator):boolean;
    procedure setAlwaysReserve(const aAlwaysReserveSize: Cardinal);   {$ifdef _DGL_Inline} inline; {$endif}
    function getAlwaysReserveSize():Cardinal;    {$ifdef _DGL_Inline} inline; {$endif}
  public
    constructor Create(const IsOnlySet : boolean) ;//use defunlt function Pointer
    destructor  Destroy; override;
  public
    function  ItBegin(): _TTagHashIterator;            {$ifdef _DGL_Inline} inline; {$endif}
    function  ItEnd(): _TTagHashIterator;               {$ifdef _DGL_Inline} inline; {$endif}
    procedure Reserve(const ReserveSize: Cardinal);       {$ifdef _DGL_Inline} inline; {$endif}
    procedure UniqueInsert(const Key: _HashKeyType;const Value: _HashValueType); overload;  //todo: Warning inline on if _ValueType if "object" then error!!!
    procedure MultiInsert(const Key: _HashKeyType;const Value: _HashValueType);overload;    //todo: Warning inline on if _ValueType if "object" then error!!!
    procedure UniqueInsert(const Key: _HashKeyType); overload;                            {$ifdef _DGL_Inline} inline; {$endif}
    procedure MultiInsert(const Key: _HashKeyType);overload;                              {$ifdef _DGL_Inline} inline; {$endif}
    procedure Clear(); virtual;
    property  AlwaysReserveSize:Cardinal read getAlwaysReserveSize write setAlwaysReserve;
    function  Size():Cardinal;                                                            {$ifdef _DGL_Inline} inline; {$endif}
    property  Capacity: Cardinal read FCapacity;
    function  GetItemValue(const Key: _HashKeyType): _HashValueType;                      {$ifdef _DGL_Inline} inline; {$endif}
    procedure Swap(HastTable:_THashTableBase);                                             {$ifdef _DGL_Inline} inline; {$endif}

    function  EraseValue(const Value: _HashValueType): integer;  overload;                  {$ifdef _DGL_Inline} inline; {$endif}
    function  EraseValue(const Key: _HashKeyType;const Value: _HashValueType): integer;  overload;     {$ifdef _DGL_Inline} inline; {$endif}
    function  EraseKey(const Key: _HashKeyType): integer;  overload;            {$ifdef _DGL_Inline} inline; {$endif}
    procedure Erase(const ItPos:_IIterator);  overload;                         // {$ifdef _DGL_Inline} inline; {$endif}
    procedure Erase(const ItBegin,ItEnd: _IIterator);  overload;               //

    function  Count(const Key:_HashKeyType):integer;
    function  FindKey(const Key:_HashKeyType):_TTagHashIterator;                  {$ifdef _DGL_Inline} inline; {$endif}
    function  FindValue(const Value:_HashValueType):_TTagHashIterator;
    function  LowerBound(const Key:_HashKeyType):_TTagHashIterator;//==FindKey
    function  UpperBound(const Key:_HashKeyType):_TTagHashIterator;
    procedure EqualRange(const Key:_HashKeyType;out ItBegin,ItEnd:_TTagHashIterator);    {$ifdef _DGL_Inline} inline; {$endif} 

  end;

  //----------------------------------------------------------------------------
  // 作用描述: _THashTableBase的迭代器,供使用_THashTableBase的其他对外容器使用
  // 主要方法:(参见_IMapIterator的说明)
  // 使用方式:
  // 注意事项:
  // 作    者: HouSisong , 2004.09.08
  // [相关资料]: (如果有的话)
  // [维护记录]: (类发布后,其修改需要记录下来:修改人、时间、主要原因内容)
  //----------------------------------------------------------------------------
  //hash Iterator
  _THashBaseIterator = class(_TAbstractIterator)  
  private
    //FBase   : _THashTableBase;   //_Data0
    //FNodeIt : _TTagHashIterator; //_Data1,_Data2
  public
    class procedure ItCreate(var SelfItData:_IIterator;const base:_THashTableBase;const NodeIt:_TTagHashIterator);overload;     //{$ifdef _DGL_Inline} inline; {$endif}

    class function  IteratorTraits():TIteratorTraits; override;
    class function    GetValue(const SelfItData:_IIterator): _HashValueType;override;
    class procedure   SetValue(const SelfItData:_IIterator;const Value: _HashValueType); override;
    class function    Map_GetKey(const SelfItData:_IIterator): _HashKeyType;override;

    class procedure   Next(var SelfItData:_IIterator); overload; override;
    class function    IsEqual(const SelfItData:_IIterator;const Iterator:_IIterator):boolean;override;
    class procedure   Previous(var SelfItData:_IIterator); override;
  end;

{$endif } // __HashTable_inc_h_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -