Contains classes used to manage dynamic sets or associative arrays.

dynhasharray.pp extends the functionality of Pascal by offering alternative data structure: set like array (the order is not kept) with fast find/delete. Its size can change automatically during the execution of the program. The price is that it is somewhat slower than a number indexes access of an array.

This unit defines TDynHashArray, which is very similar to a TList, since it also stores pointer/objects.

It supports Add, Remove, Contains, First, Count and Clear.

Because of the hashing nature the operations adding, removing and finding is done in constant time on average.

Inner structure:

There are three parts:

  • The array itself (FItems). Every entry is a pointer to the first TDynHashArrayItem of a list with the same hash index. The first item of every same index list is the list beginning and its IsOverflow flag is set to false. All other items are overflow items. To get all items with the same hash index, do a FindHashItem. Then search through all "Next" items until Next is nil or its IsOverflow flag is set to false.
  • The items beginning with FFirstItem is a 2-way-connected list of TDynHashArrayItem. This list contains all used items.
  • To reduce GetMem/FreeMem calls, free items are cached.

Issues:

The maximum capacity is the PrimeNumber. You can store more items, but the performance decreases. The best idea is to provide your own hash function.

Important: Items in the TDynHashArray must not change their key. When changing the key of an item, remove it and add it after the change.

dynhasharray.pp is part of the LazUtils package.

Type for hash function. Each hash function specified by the user has to have these parameters Defines a hash function implemented as an object procedure. Defines a Pointer function type used to get the key value for a hash item in TDynHashArray.

TOnGetKeyForHashItem is the type used for the OnGetKeyForHashItem property in TDynHashArray.

Defines a Boolean function type used to enumerate hash items in TDynHashArray. Pointer to a TDynHashArrayItem instance. Record type with pointers to the current, previous, and next has items in a linked list. Pointer to an element to be stored in the array. It points to the next element in the doubly linked list. It points to the previous element in the doubly linked list. False if it is the first element of the linked list. Options for how this class should work. It will use cached result if available in IndexOfKey. Turns on a cache for contains operations. Set type used to store values from TDynHashArrayOption. Name of the class that store all functions and data for an hashed array.

TDynHashArray is a class which is similar to TList which allows both pointers and objects to be maintained in its internal storage. It includes common methods like Add, Remove, Contains, First, Count and Clear. Because of its hashing nature, the add, remove, and find operations are done in constant time on average.

Inner structure:

There are three parts:

  1. The array itself (FItems). Every entry is a pointer to the first TDynHashArrayItem of a list with the same hash index. The first item of every same index list is the list beginning and its IsOverflow flag is set to false. All other items are overflow items. To get all items with the same hash index, do a FindHashItem. Then search through all "Next" items until Next is nil or its IsOverflow flag is set to false.
  2. The items beginning with FFirstItem is a 2-way-connected list of TDynHashArrayItem. This list contains all used items.
  3. To reduce GetMem/FreeMem calls, free items are cached.

Issues:

The maximum capacity is the PrimeNumber. You can store more items, but the performance decreases. The best idea is to provide your own hash function.

Important: Items in the TDynHashArray must not change their key. When changing the key of an item, remove it and add it after the change.

Array pointing to link lists. Number of elements stored. The minimum number of items that will be allocated for an array.

The size of the array can be changed anytime. However, even if a size is given by FCapacity is smaller than this minimum number, then this minimum number of items will be allocated. This is done for efficiency and speed.

The size of the array cannot be larger than this number.

FCapacity is overridden by this number, if that is larger than this.

It contains the cached key. It contains the cached index derived from the key. The lower element limit for reallocation.

The number of elements allocated are halved if the number of elements in the array goes below this number.

The upper element count limit for reallocation.

The number of elements allocated are doubled if the number of elements in the array reaches this number.

The pointer to the user-defined hash function. Optional user-defined function for converting keys. Optional user-defined hash function which can be SlowAlternativeHashMethod. Changes the number of items (pre-)allocated. Specify your own hash function to be used by the class.

The hash function has to convert a string into a number in a random fashion.

Rebuilds the internal data structures.

It is called anytime when there is a change that makes it necessary. E.g. hash function changes or because of dynamic reallocation.

Sets the cache. The cache is set as given by the parameters. Constructor for the class instance.

Create is the overloaded constructor for the class instance. Overloaded variants are provided which set the initial value in MinCapacity to either a default or a user-specified value. The parameter-less version sets the initial value in MinCapacity to 10, but it is automagically increased to 137.

MaxCapacity is set to an arbitrarily large prime number defined in the implementation for class.

Create allocates memory needed to store the number of TDynHashArrayItem entries specified in its Capacity property. The allocated memory is zero-filled prior to use.

Initial value used as the minimum capacity for the class instance. Destructor for the class instance.

Destroy is the overridden destructor for the class instance. It calls the Clear method to remove cache entries for the list, and to free the pointers to the TDynHashArrayItem entries starting at FirstHashItem.

Adds an item to the set/array.

An example:

uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, dynhasharray,strings; var A:TDynHashArray; s:pchar; begin A := TDynHashArray.Create; s := StrNew ('u'); A.Add(s); if A.Contains(s) then writeln('1:it contains s.'); writeln('1:count:',A.Count); A.Clear; if A.Contains(s) then writeln('2:it contains s.'); writeln('2:count:',A.Count); ReadLn; StrDispose(s);
Returns True if the item is in the set.

An example:

uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, dynhasharray,strings; var A: TDynHashArray; s: pchar; begin A := TDynHashArray.Create; s := StrNew ('u'); A.Add(s); if A.Contains(s) then writeln('1:it contains s.'); writeln('1:count:',A.Count); A.Clear; if A.Contains(s) then writeln('2:it contains s.'); writeln('2:count:',A.Count); ReadLn; StrDispose(s);
Returns True if the item is in the set.(through OnGetKeyForHashItem). Removes an element from the set/hash array.

An example:

{$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, dynhasharray,strings; var A:TDynHashArray; s:pchar; s2:pchar; begin A:=TDynHashArray.Create; s:=StrNew ('u'); s2:=StrNew ('i'); A.Add(s); A.Add(s2); if A.Contains(s2) then writeln('1:it contains s2.'); writeln('1:count:',A.Count); A.Remove(s2); if A.Contains(s2) then writeln('2:it contains s2.'); writeln('2:count:',A.Count); ReadLn; StrDispose(s);StrDispose(s2); end.
Removes all elements from the set/hash array.

An example:

uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, dynhasharray,strings; var A:TDynHashArray; s:pchar; begin A:=TDynHashArray.Create; s:=StrNew ('u'); A.Add(s); if A.Contains(s) then writeln('1:it contains s.'); writeln('1:count:',A.Count); A.Clear; if A.Contains(s) then writeln('2:it contains s.'); writeln('2:count:',A.Count); ReadLn; StrDispose(s);
Clears the FContainsCache cache. Returns the first item or nil. Number of elements stored in the set/array.

An example:

uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Classes, dynhasharray,strings; var A:TDynHashArray; s:pchar; begin A:=TDynHashArray.Create; s:=StrNew ('u'); A.Add(s); if A.Contains(s) then writeln('1:it contains s.'); writeln('1:count:',A.Count); A.Clear; if A.Contains(s) then writeln('2:it contains s.'); writeln('2:count:',A.Count); ReadLn; StrDispose(s);
Returns calculated index from Item through OnGetKeyForHashItem. Returns calculated index from Item. It uses user-defined hash functions or built-in algorithm Finds an item as PDynHashArrayItem among all items. Finds an item as PDynHashArrayItem among all items (through OnGetKeyForHashItem). Finds an item among all items (through OnGetKeyForHashItem). Gets a link list from the "main" array FItems by index. So it returns a link list which can be processed. Deletes a PDynHashArrayItem from link list. Copies all items into a given TList. Calls the specified function for each of the items in the hash array. Boolean function type called for the hash items. Another hash function that can be used. Check if data in TDynHashArray are OK. Returns a number indicating the nature of inconsistency. 0 means OK. Prints out essential data to aid debugging TDynHashArray. Pointer which provides access to the first TDynHashArrayItem stored in the hash array. The minimum number of items that will be allocated for an array.

The size of the array can be changed at any time. However, even if a size is given for Capacity that is smaller than this minimum number, then this minimum number of items will be allocated. This is done for efficiency and speed.

The size of the array cannot be larger than this number. FCapacity is overridden by this number, if that is larger than this. Space is allocated for this number of items. The pointer to the user-defined hash function. The pointer to the user-defined hash function. User-defined function to obtain a key from an item.

If this function is specified,then it is possible to use this class as an associative array. Otherwise, it implements a set.

Set of TDynHashArrayOption values enabled for the class instance. Custom memory manager for TDynHashArrayItem instances. Removes references to the specified hash item and adds it to the free list. Allocates and initializes a new hash item for the memory manager. Minimum size for the internal free list storage.

Ensures that MinimumFreeCount cannot be set to a negative value.

Threshold at which items in the free list are released. Number of hash items allocated by the memory manager. Disposes of hash items in the free list. Constructor for the class instance. Destructor for the class instance. Ensures that Count matches the actual number of entries in the free list. Prints out essential data to aid debugging DynHashArrayItemMemManager. Raised if index is invalid in IndexOfKey. The index can be invalid if user-defined/custom function are faulty. A small memory manager.