mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-31 11:20:17 +02:00
Sparta: Remove SParta_Generics. Compiler now includes the Generics collection. Issue #39539.
This commit is contained in:
parent
2fbce3f5e6
commit
6d5520794e
File diff suppressed because it is too large
Load Diff
@ -1,655 +0,0 @@
|
||||
{%MainUnit generics.collections.pas}
|
||||
|
||||
{
|
||||
This file is part of the Free Pascal run time library.
|
||||
Copyright (c) 2014 by Maciej Izak (hnb)
|
||||
member of the Free Sparta development team (http://freesparta.com)
|
||||
|
||||
Copyright(c) 2004-2014 DaThoX
|
||||
|
||||
It contains the Free Pascal generics library
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
Acknowledgment
|
||||
|
||||
Thanks to Sphere 10 Software (http://sphere10.com) for sponsoring
|
||||
many new types and major refactoring of entire library
|
||||
|
||||
Thanks to mORMot (http://synopse.info) project for the best implementations
|
||||
of hashing functions like crc32c and xxHash32 :)
|
||||
|
||||
**********************************************************************}
|
||||
|
||||
{$WARNINGS OFF}
|
||||
type
|
||||
TEmptyRecord = record // special record for Dictionary TValue (Dictionary as Set)
|
||||
end;
|
||||
|
||||
{ TPair }
|
||||
|
||||
TPair<TKey, TValue> = record
|
||||
public
|
||||
Key: TKey;
|
||||
Value: TValue;
|
||||
class function Create(AKey: TKey; AValue: TValue): TPair<TKey, TValue>; static;
|
||||
end;
|
||||
|
||||
{ TCustomDictionary }
|
||||
|
||||
// bug #24283 and #24097 (forward declaration) - should be:
|
||||
// TCustomDictionary<CUSTOM_DICTIONARY_CONSTRAINTS> = class(TEnumerable<TPair<TKey, TValue> >);
|
||||
TCustomDictionary<CUSTOM_DICTIONARY_CONSTRAINTS> = class abstract
|
||||
public type
|
||||
// workaround... no generics types in generics types
|
||||
TDictionaryPair = TPair<TKey, TValue>;
|
||||
PDictionaryPair = ^TDictionaryPair;
|
||||
PKey = ^TKey;
|
||||
PValue = ^TValue;
|
||||
THashFactoryClass = THashFactory;
|
||||
protected
|
||||
FEqualityComparer: IEqualityComparer<TKey>;
|
||||
FKeys: TEnumerable<TKey>;
|
||||
FValues: TEnumerable<TValue>;
|
||||
FMaxLoadFactor: single;
|
||||
protected
|
||||
procedure SetCapacity(ACapacity: SizeInt); virtual; abstract;
|
||||
// bug #24283. workaround for this class because can't inherit from TEnumerable
|
||||
function DoGetEnumerator: TEnumerator<TDictionaryPair>; virtual; abstract; {override;}
|
||||
|
||||
procedure SetMaxLoadFactor(AValue: single); virtual; abstract;
|
||||
function GetLoadFactor: single; virtual; abstract;
|
||||
function GetCapacity: SizeInt; virtual; abstract;
|
||||
public
|
||||
property MaxLoadFactor: single read FMaxLoadFactor write SetMaxLoadFactor;
|
||||
property LoadFactor: single read GetLoadFactor;
|
||||
property Capacity: SizeInt read GetCapacity write SetCapacity;
|
||||
|
||||
procedure Clear; virtual; abstract;
|
||||
procedure Add(constref APair: TPair<TKey, TValue>); virtual; abstract;
|
||||
strict private // bug #24283. workaround for this class because can't inherit from TEnumerable
|
||||
function ToArray(ACount: SizeInt): TArray<TDictionaryPair>; overload;
|
||||
public
|
||||
function ToArray: TArray<TDictionaryPair>; virtual; final; {override; final; // bug #24283} overload;
|
||||
|
||||
constructor Create; virtual; overload;
|
||||
constructor Create(ACapacity: SizeInt); virtual; overload;
|
||||
constructor Create(ACapacity: SizeInt; const AComparer: IEqualityComparer<TKey>); virtual; overload;
|
||||
constructor Create(const AComparer: IEqualityComparer<TKey>); overload;
|
||||
constructor Create(ACollection: TEnumerable<TDictionaryPair>); virtual; overload;
|
||||
constructor Create(ACollection: TEnumerable<TDictionaryPair>; const AComparer: IEqualityComparer<TKey>); virtual; overload;
|
||||
{$IFDEF ENABLE_METHODS_WITH_TEnumerableWithPointers}
|
||||
constructor Create(ACollection: TEnumerableWithPointers<TDictionaryPair>); virtual; overload;
|
||||
constructor Create(ACollection: TEnumerableWithPointers<TDictionaryPair>; const AComparer: IEqualityComparer<TKey>); virtual; overload;
|
||||
{$ENDIF}
|
||||
|
||||
destructor Destroy; override;
|
||||
private
|
||||
FOnKeyNotify: TCollectionNotifyEvent<TKey>;
|
||||
FOnValueNotify: TCollectionNotifyEvent<TValue>;
|
||||
protected
|
||||
procedure UpdateItemsThreshold(ASize: SizeInt); virtual; abstract;
|
||||
|
||||
procedure KeyNotify(constref AKey: TKey; ACollectionNotification: TCollectionNotification); virtual;
|
||||
procedure ValueNotify(constref AValue: TValue; ACollectionNotification: TCollectionNotification); virtual;
|
||||
procedure PairNotify(constref APair: TDictionaryPair; ACollectionNotification: TCollectionNotification); inline;
|
||||
procedure SetValue(var AValue: TValue; constref ANewValue: TValue);
|
||||
public
|
||||
property OnKeyNotify: TCollectionNotifyEvent<TKey> read FOnKeyNotify write FOnKeyNotify;
|
||||
property OnValueNotify: TCollectionNotifyEvent<TValue> read FOnValueNotify write FOnValueNotify;
|
||||
protected // FItemsLength must be declared at the end of TCustomDictionary
|
||||
FItemsLength: SizeInt;
|
||||
public
|
||||
property Count: SizeInt read FItemsLength;
|
||||
end;
|
||||
|
||||
{ TCustomDictionaryEnumerator }
|
||||
|
||||
TCustomDictionaryEnumerator<T, CUSTOM_DICTIONARY_CONSTRAINTS> = class abstract(TEnumerator< T >)
|
||||
private
|
||||
FDictionary: TCustomDictionary<CUSTOM_DICTIONARY_CONSTRAINTS>;
|
||||
FIndex: SizeInt;
|
||||
protected
|
||||
function DoGetCurrent: T; override;
|
||||
function GetCurrent: T; virtual; abstract;
|
||||
public
|
||||
constructor Create(ADictionary: TCustomDictionary<CUSTOM_DICTIONARY_CONSTRAINTS>);
|
||||
end;
|
||||
|
||||
{ TDictionaryEnumerable }
|
||||
|
||||
TDictionaryEnumerable<TDictionaryEnumerator: TObject; TDictionaryPointersEnumerator, // ... inherits from TCustomDictionaryEnumerator. workaround...
|
||||
T, CUSTOM_DICTIONARY_CONSTRAINTS> = class abstract(TEnumerableWithPointers<T>)
|
||||
private
|
||||
FDictionary: TCustomDictionary<CUSTOM_DICTIONARY_CONSTRAINTS>;
|
||||
function GetCount: SizeInt;
|
||||
protected
|
||||
function GetPtrEnumerator: TEnumerator<PT>; override;
|
||||
function DoGetEnumerator: TDictionaryEnumerator; override;
|
||||
public
|
||||
constructor Create(ADictionary: TCustomDictionary<CUSTOM_DICTIONARY_CONSTRAINTS>);
|
||||
function ToArray: TArray<T>; override; final;
|
||||
property Count: SizeInt read GetCount;
|
||||
end;
|
||||
|
||||
// more info : http://en.wikipedia.org/wiki/Open_addressing
|
||||
|
||||
{ TOpenAddressingEnumerator }
|
||||
|
||||
TOpenAddressingEnumerator<T, OPEN_ADDRESSING_CONSTRAINTS> = class abstract(TCustomDictionaryEnumerator<T, CUSTOM_DICTIONARY_CONSTRAINTS>)
|
||||
protected
|
||||
function DoMoveNext: Boolean; override;
|
||||
end;
|
||||
|
||||
TOpenAddressingPointersEnumerator<TItem, PDictionaryPair> = class abstract(TEnumerator<PDictionaryPair>)
|
||||
private var
|
||||
FItems: ^TArray<TItem>;
|
||||
FIndex: SizeInt;
|
||||
protected
|
||||
function DoMoveNext: boolean; override;
|
||||
function DoGetCurrent: PDictionaryPair; override;
|
||||
function GetCurrent: PDictionaryPair; virtual;
|
||||
public
|
||||
constructor Create(var AItems);
|
||||
end;
|
||||
|
||||
TOpenAddressingPointersCollection<TPointersEnumerator, TItem, PDictionaryPair> = record
|
||||
private type
|
||||
PArray = ^TArray<TItem>;
|
||||
function Items: PArray; inline;
|
||||
function GetCount: SizeInt; inline;
|
||||
public
|
||||
function GetEnumerator: TPointersEnumerator;
|
||||
function ToArray: TArray<PDictionaryPair>;
|
||||
property Count: SizeInt read GetCount;
|
||||
end;
|
||||
|
||||
TOnGetMemoryLayoutKeyPosition = procedure(Sender: TObject; AKeyPos: UInt32) of object;
|
||||
|
||||
TOpenAddressing<OPEN_ADDRESSING_CONSTRAINTS> = class abstract(TCustomDictionary<CUSTOM_DICTIONARY_CONSTRAINTS>)
|
||||
private type
|
||||
PItem = ^TItem;
|
||||
TItem = record
|
||||
Hash: UInt32;
|
||||
Pair: TPair<TKey, TValue>;
|
||||
end;
|
||||
|
||||
TItemsArray = array of TItem;
|
||||
TPointersEnumerator = class(TOpenAddressingPointersEnumerator<TItem, PDictionaryPair>);
|
||||
TPointersCollection = TOpenAddressingPointersCollection<TPointersEnumerator, TItem, PDictionaryPair>;
|
||||
public type
|
||||
PPointersCollection = ^TPointersCollection;
|
||||
private var // FItems must be declared as first field
|
||||
FItems: TItemsArray;
|
||||
FItemsThreshold: SizeInt;
|
||||
|
||||
procedure Resize(ANewSize: SizeInt);
|
||||
procedure PrepareAddingItem;
|
||||
protected
|
||||
function RealItemsLength: SizeInt; virtual;
|
||||
function Rehash(ASizePow2: SizeInt; AForce: Boolean = False): boolean; virtual;
|
||||
function FindBucketIndex(constref AKey: TKey): SizeInt; overload; inline;
|
||||
function FindBucketIndex(constref AItems: TArray<TItem>; constref AKey: TKey; out AHash: UInt32): SizeInt; virtual; abstract; overload;
|
||||
public
|
||||
type
|
||||
// Enumerators
|
||||
TPairEnumerator = class(TOpenAddressingEnumerator<TDictionaryPair, OPEN_ADDRESSING_CONSTRAINTS>)
|
||||
protected
|
||||
function GetCurrent: TPair<TKey,TValue>; override;
|
||||
end;
|
||||
|
||||
TValueEnumerator = class(TOpenAddressingEnumerator<TValue, OPEN_ADDRESSING_CONSTRAINTS>)
|
||||
protected
|
||||
function GetCurrent: TValue; override;
|
||||
end;
|
||||
|
||||
TPValueEnumerator = class(TOpenAddressingEnumerator<PValue, OPEN_ADDRESSING_CONSTRAINTS>)
|
||||
protected
|
||||
function GetCurrent: PValue; override;
|
||||
end;
|
||||
|
||||
TKeyEnumerator = class(TOpenAddressingEnumerator<TKey, OPEN_ADDRESSING_CONSTRAINTS>)
|
||||
protected
|
||||
function GetCurrent: TKey; override;
|
||||
end;
|
||||
|
||||
TPKeyEnumerator = class(TOpenAddressingEnumerator<PKey, OPEN_ADDRESSING_CONSTRAINTS>)
|
||||
protected
|
||||
function GetCurrent: PKey; override;
|
||||
end;
|
||||
|
||||
// Collections
|
||||
TValueCollection = class(TDictionaryEnumerable<TValueEnumerator, TPValueEnumerator, TValue, CUSTOM_DICTIONARY_CONSTRAINTS>);
|
||||
|
||||
TKeyCollection = class(TDictionaryEnumerable<TKeyEnumerator, TPKeyEnumerator, TKey, CUSTOM_DICTIONARY_CONSTRAINTS>);
|
||||
|
||||
// bug #24283 - workaround related to lack of DoGetEnumerator
|
||||
function GetEnumerator: TPairEnumerator; reintroduce;
|
||||
private
|
||||
function GetKeys: TKeyCollection;
|
||||
function GetValues: TValueCollection;
|
||||
function GetPointers: PPointersCollection; inline;
|
||||
private
|
||||
function GetItem(const AKey: TKey): TValue; inline;
|
||||
procedure SetItem(const AKey: TKey; const AValue: TValue); inline;
|
||||
procedure AddItem(var AItem: TItem; constref AKey: TKey; constref AValue: TValue; const AHash: UInt32); inline;
|
||||
protected
|
||||
// useful for using dictionary as array
|
||||
function DoRemove(AIndex: SizeInt; ACollectionNotification: TCollectionNotification): TValue; virtual;
|
||||
function DoAdd(constref AKey: TKey; constref AValue: TValue): SizeInt; virtual;
|
||||
|
||||
procedure UpdateItemsThreshold(ASize: SizeInt); override;
|
||||
|
||||
procedure SetCapacity(ACapacity: SizeInt); override;
|
||||
// bug #24283 - can't descadent from TEnumerable
|
||||
function DoGetEnumerator: TEnumerator<TDictionaryPair>; override;
|
||||
procedure SetMaxLoadFactor(AValue: single); override;
|
||||
function GetLoadFactor: single; override;
|
||||
function GetCapacity: SizeInt; override;
|
||||
public
|
||||
// many constructors because bug #25607
|
||||
constructor Create(ACapacity: SizeInt; const AComparer: IEqualityComparer<TKey>); override; overload;
|
||||
|
||||
procedure Add(constref APair: TPair<TKey, TValue>); override; overload;
|
||||
procedure Add(constref AKey: TKey; constref AValue: TValue); overload; inline;
|
||||
procedure Remove(constref AKey: TKey);
|
||||
function ExtractPair(constref AKey: TKey): TPair<TKey, TValue>;
|
||||
procedure Clear; override;
|
||||
procedure TrimExcess;
|
||||
function TryGetValue(constref AKey: TKey; out AValue: TValue): Boolean;
|
||||
procedure AddOrSetValue(constref AKey: TKey; constref AValue: TValue);
|
||||
function ContainsKey(constref AKey: TKey): Boolean; inline;
|
||||
function ContainsValue(constref AValue: TValue): Boolean; overload;
|
||||
function ContainsValue(constref AValue: TValue; const AEqualityComparer: IEqualityComparer<TValue>): Boolean; virtual; overload;
|
||||
|
||||
property Items[Index: TKey]: TValue read GetItem write SetItem; default;
|
||||
property Keys: TKeyCollection read GetKeys;
|
||||
property Values: TValueCollection read GetValues;
|
||||
property Ptr: PPointersCollection read GetPointers;
|
||||
|
||||
procedure GetMemoryLayout(const AOnGetMemoryLayoutKeyPosition: TOnGetMemoryLayoutKeyPosition);
|
||||
end;
|
||||
|
||||
TOpenAddressingLP<OPEN_ADDRESSING_CONSTRAINTS> = class(TOpenAddressing<OPEN_ADDRESSING_CONSTRAINTS>)
|
||||
private type // for workaround Lazarus bug #25613
|
||||
_TItem = record
|
||||
Hash: UInt32;
|
||||
Pair: TPair<TKey, TValue>;
|
||||
end;
|
||||
protected
|
||||
procedure NotifyIndexChange(AFrom, ATo: SizeInt); virtual;
|
||||
function DoRemove(AIndex: SizeInt; ACollectionNotification: TCollectionNotification): TValue; override;
|
||||
function FindBucketIndex(constref AItems: TArray<TItem>; constref AKey: TKey; out AHash: UInt32): SizeInt; override; overload;
|
||||
end;
|
||||
|
||||
// More info and TODO
|
||||
// https://github.com/OpenHFT/UntitledCollectionsProject/wiki/Tombstones-purge-from-hashtable:-theory-and-practice
|
||||
|
||||
TOpenAddressingTombstones<OPEN_ADDRESSING_CONSTRAINTS> = class abstract(TOpenAddressing<OPEN_ADDRESSING_CONSTRAINTS>)
|
||||
private
|
||||
FTombstonesCount: SizeInt;
|
||||
protected
|
||||
function Rehash(ASizePow2: SizeInt; AForce: Boolean = False): boolean; override;
|
||||
function RealItemsLength: SizeInt; override;
|
||||
|
||||
function FindBucketIndexOrTombstone(constref AItems: TArray<TItem>; constref AKey: TKey;
|
||||
out AHash: UInt32): SizeInt; virtual; abstract;
|
||||
|
||||
function DoRemove(AIndex: SizeInt; ACollectionNotification: TCollectionNotification): TValue; override;
|
||||
function DoAdd(constref AKey: TKey; constref AValue: TValue): SizeInt; override;
|
||||
public
|
||||
property TombstonesCount: SizeInt read FTombstonesCount;
|
||||
procedure ClearTombstones; virtual;
|
||||
procedure Clear; override;
|
||||
end;
|
||||
|
||||
TOpenAddressingSH<OPEN_ADDRESSING_CONSTRAINTS> = class(TOpenAddressingTombstones<OPEN_ADDRESSING_CONSTRAINTS>)
|
||||
private type // for workaround Lazarus bug #25613
|
||||
_TItem = record
|
||||
Hash: UInt32;
|
||||
Pair: TPair<TKey, TValue>;
|
||||
end;
|
||||
protected
|
||||
function FindBucketIndex(constref AItems: TArray<TItem>; constref AKey: TKey;
|
||||
out AHash: UInt32): SizeInt; override; overload;
|
||||
function FindBucketIndexOrTombstone(constref AItems: TArray<TItem>; constref AKey: TKey;
|
||||
out AHash: UInt32): SizeInt; override;
|
||||
end;
|
||||
|
||||
TOpenAddressingQP<OPEN_ADDRESSING_CONSTRAINTS> = class(TOpenAddressingSH<OPEN_ADDRESSING_CONSTRAINTS>)
|
||||
private
|
||||
FPrimaryNumberAsSizeApproximation: SizeInt;
|
||||
protected
|
||||
procedure UpdateItemsThreshold(ASize: SizeInt); override;
|
||||
function FindBucketIndex(constref AItems: TArray<TItem>;
|
||||
constref AKey: TKey; out AHash: UInt32): SizeInt; override; overload;
|
||||
function FindBucketIndexOrTombstone(constref AItems: TArray<TItem>;
|
||||
constref AKey: TKey; out AHash: UInt32): SizeInt; override;
|
||||
end;
|
||||
|
||||
TOpenAddressingDH<OPEN_ADDRESSING_CONSTRAINTS> = class(TOpenAddressingTombstones<OPEN_ADDRESSING_CONSTRAINTS>)
|
||||
private type // for workaround Lazarus bug #25613
|
||||
_TItem = record
|
||||
Hash: UInt32;
|
||||
Pair: TPair<TKey, TValue>;
|
||||
end;
|
||||
private
|
||||
R: UInt32;
|
||||
protected
|
||||
procedure UpdateItemsThreshold(ASize: SizeInt); override;
|
||||
function FindBucketIndex(constref AItems: TArray<TItem>; constref AKey: TKey;
|
||||
out AHash: UInt32): SizeInt; override; overload;
|
||||
function FindBucketIndexOrTombstone(constref AItems: TArray<TItem>; constref AKey: TKey;
|
||||
out AHash: UInt32): SizeInt; override;
|
||||
strict protected
|
||||
constructor Create(ACapacity: SizeInt; const AComparer: IEqualityComparer<TKey>); override; overload;
|
||||
constructor Create(const AComparer: IEqualityComparer<TKey>); reintroduce; overload;
|
||||
constructor Create(ACollection: TEnumerable<TDictionaryPair>; const AComparer: IEqualityComparer<TKey>); override; overload;
|
||||
{$IFDEF ENABLE_METHODS_WITH_TEnumerableWithPointers}
|
||||
constructor Create(ACollection: TEnumerableWithPointers<TDictionaryPair>; const AComparer: IEqualityComparer<TKey>); override; overload;
|
||||
{$ENDIF}
|
||||
public // bug #26181 (redundancy of constructors)
|
||||
constructor Create(ACapacity: SizeInt); override; overload;
|
||||
constructor Create(ACollection: TEnumerable<TDictionaryPair>); override; overload;
|
||||
{$IFDEF ENABLE_METHODS_WITH_TEnumerableWithPointers}
|
||||
constructor Create(ACollection: TEnumerableWithPointers<TDictionaryPair>); override; overload;
|
||||
{$ENDIF}
|
||||
constructor Create(ACapacity: SizeInt; const AComparer: IExtendedEqualityComparer<TKey>); virtual; overload;
|
||||
constructor Create(const AComparer: IExtendedEqualityComparer<TKey>); overload;
|
||||
constructor Create(ACollection: TEnumerable<TDictionaryPair>; const AComparer: IExtendedEqualityComparer<TKey>); virtual; overload;
|
||||
{$IFDEF ENABLE_METHODS_WITH_TEnumerableWithPointers}
|
||||
constructor Create(ACollection: TEnumerableWithPointers<TDictionaryPair>; const AComparer: IExtendedEqualityComparer<TKey>); virtual; overload;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
TDeamortizedDArrayCuckooMapEnumerator<T, CUCKOO_CONSTRAINTS> = class abstract(TCustomDictionaryEnumerator<T, CUSTOM_DICTIONARY_CONSTRAINTS>)
|
||||
private type // for workaround Lazarus bug #25613
|
||||
TItem = record
|
||||
Hash: UInt32;
|
||||
Pair: TPair<TKey, TValue>;
|
||||
end;
|
||||
TItemsArray = array of TItem;
|
||||
private
|
||||
FMainIndex: SizeInt;
|
||||
protected
|
||||
function DoMoveNext: Boolean; override;
|
||||
public
|
||||
constructor Create(ADictionary: TCustomDictionary<CUSTOM_DICTIONARY_CONSTRAINTS>);
|
||||
end;
|
||||
|
||||
TDeamortizedDArrayPointersEnumerator<TCuckooCfg, TItemsArray, TItemsDArray, TQueueDictionary, PDictionaryPair> = class abstract(TEnumerator<PDictionaryPair>)
|
||||
private var // FItems must be declared as first field and FQueue as second
|
||||
FItems: ^TItemsDArray;
|
||||
FQueue: TQueueDictionary;
|
||||
FIndex: SizeInt;
|
||||
FMainIndex: SizeInt;
|
||||
protected
|
||||
function DoMoveNext: boolean; override;
|
||||
function DoGetCurrent: PDictionaryPair; override;
|
||||
function GetCurrent: PDictionaryPair; virtual;
|
||||
public
|
||||
constructor Create(var AItems; AQueue: TQueueDictionary; ACount: SizeInt);
|
||||
end;
|
||||
|
||||
TDeamortizedDArrayPointersCollection<TPointersEnumerator, TItemsDArray, TQueueDictionary, PDictionaryPair> = record
|
||||
private type
|
||||
PArray = ^TItemsDArray;
|
||||
function Items: PArray; inline;
|
||||
function GetCount: SizeInt; inline;
|
||||
function GetQueue: TQueueDictionary; inline;
|
||||
public
|
||||
function GetEnumerator: TPointersEnumerator;
|
||||
function ToArray: TArray<PDictionaryPair>;
|
||||
property Count: SizeInt read GetCount;
|
||||
end;
|
||||
|
||||
// more info :
|
||||
// http://arxiv.org/abs/0903.0391
|
||||
|
||||
TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS> = class(TCustomDictionary<CUSTOM_DICTIONARY_CONSTRAINTS>)
|
||||
private const // Lookup Result
|
||||
LR_NIL = -1;
|
||||
LR_QUEUE = -2;
|
||||
private type
|
||||
PItem = ^TItem;
|
||||
TItem = record
|
||||
Hash: UInt32;
|
||||
Pair: TPair<TKey, TValue>;
|
||||
end;
|
||||
TValueForQueue = TItem;
|
||||
|
||||
TQueueDictionary = class(TOpenAddressingLP<TKey, TValueForQueue, TDefaultHashFactory, TLinearProbing>)
|
||||
private type // for workaround Lazarus bug #25613
|
||||
_TItem = record
|
||||
Hash: UInt32;
|
||||
Pair: TPair<TKey, TValueForQueue>;
|
||||
end;
|
||||
private
|
||||
FIdx: TList<UInt32>; // list to keep order
|
||||
protected
|
||||
procedure NotifyIndexChange(AFrom, ATo: SizeInt); override;
|
||||
function Rehash(ASizePow2: SizeInt; AForce: Boolean = False): Boolean; override;
|
||||
public
|
||||
procedure InsertIntoBack(AItem: Pointer);
|
||||
procedure InsertIntoHead(AItem: Pointer);
|
||||
function IsEmpty: Boolean;
|
||||
function Pop: Pointer;
|
||||
constructor Create(ACapacity: SizeInt; const AComparer: IEqualityComparer<TKey>); override; overload;
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
// cycle-detection mechanism class
|
||||
TCDM = class(TOpenAddressingSH<TKey, TEmptyRecord, TDefaultHashFactory, TLinearProbing>);
|
||||
TItemsArray = array of TItem;
|
||||
TItemsDArray = array[0..Pred(TCuckooCfg.D)] of TItemsArray;
|
||||
TPointersEnumerator = class(TDeamortizedDArrayPointersEnumerator<TCuckooCfg, TItemsArray, TItemsDArray, TQueueDictionary, PDictionaryPair>);
|
||||
TPointersCollection = TDeamortizedDArrayPointersCollection<TPointersEnumerator, TItemsDArray, TQueueDictionary, PDictionaryPair>;
|
||||
public type
|
||||
PPointersCollection = ^TPointersCollection;
|
||||
private var
|
||||
FItems: TItemsDArray;
|
||||
FQueue: TQueueDictionary; // probably can be optimized - hash TItem give information from TItem.Hash for cuckoo ...
|
||||
// currently is kept in "TQueueDictionary = class(TOpenAddressingSH<TKey, TItem, ...>"
|
||||
|
||||
FCDM: TCDM; // cycle-detection mechanism
|
||||
FItemsThreshold: SizeInt;
|
||||
// sadly there is bug #24848 for class var ...
|
||||
{class} var
|
||||
CUCKOO_SIGN, CUCKOO_INDEX_SIZE, CUCKOO_HASH_SIGN: UInt32;
|
||||
// CUCKOO_MAX_ITEMS_LENGTH: <- to do : calc max length for items based on CUCKOO sign
|
||||
// maybe some CDM bloom filter?
|
||||
|
||||
procedure Resize(ANewSize: SizeInt);
|
||||
procedure Rehash(ASizePow2: SizeInt);
|
||||
procedure PrepareAddingItem;
|
||||
protected
|
||||
procedure UpdateItemsThreshold(ASize: SizeInt); override;
|
||||
function Lookup(constref AKey: TKey; var AHashListOrIndex: PUInt32): SizeInt; inline; overload;
|
||||
function Lookup(constref AItems: TItemsDArray; constref AKey: TKey; var AHashListOrIndex: PUInt32): SizeInt; virtual; overload;
|
||||
public
|
||||
type
|
||||
// Enumerators
|
||||
TPairEnumerator = class(TDeamortizedDArrayCuckooMapEnumerator<TDictionaryPair, CUCKOO_CONSTRAINTS>)
|
||||
protected
|
||||
function GetCurrent: TPair<TKey,TValue>; override;
|
||||
end;
|
||||
|
||||
TValueEnumerator = class(TDeamortizedDArrayCuckooMapEnumerator<TValue, CUCKOO_CONSTRAINTS>)
|
||||
protected
|
||||
function GetCurrent: TValue; override;
|
||||
end;
|
||||
|
||||
TPValueEnumerator = class(TDeamortizedDArrayCuckooMapEnumerator<PValue, CUCKOO_CONSTRAINTS>)
|
||||
protected
|
||||
function GetCurrent: PValue; override;
|
||||
end;
|
||||
|
||||
TKeyEnumerator = class(TDeamortizedDArrayCuckooMapEnumerator<TKey, CUCKOO_CONSTRAINTS>)
|
||||
protected
|
||||
function GetCurrent: TKey; override;
|
||||
end;
|
||||
|
||||
TPKeyEnumerator = class(TDeamortizedDArrayCuckooMapEnumerator<PKey, CUCKOO_CONSTRAINTS>)
|
||||
protected
|
||||
function GetCurrent: PKey; override;
|
||||
end;
|
||||
|
||||
// Collections
|
||||
TValueCollection = class(TDictionaryEnumerable<TValueEnumerator, TPValueEnumerator, TValue, CUSTOM_DICTIONARY_CONSTRAINTS>);
|
||||
|
||||
TKeyCollection = class(TDictionaryEnumerable<TKeyEnumerator, TPKeyEnumerator, TKey, CUSTOM_DICTIONARY_CONSTRAINTS>);
|
||||
|
||||
// bug #24283 - workaround related to lack of DoGetEnumerator
|
||||
function GetEnumerator: TPairEnumerator; reintroduce;
|
||||
private
|
||||
function GetKeys: TKeyCollection;
|
||||
function GetValues: TValueCollection;
|
||||
function GetPointers: PPointersCollection; inline;
|
||||
private
|
||||
function GetItem(const AKey: TKey): TValue; inline;
|
||||
procedure SetItem(const AKey: TKey; const AValue: TValue); overload; inline;
|
||||
procedure SetItem(constref AValue: TValue; const AHashListOrIndex: PUInt32; ALookupResult: SizeInt); overload;
|
||||
|
||||
procedure AddItem(constref AItems: TItemsDArray; constref AKey: TKey; constref AValue: TValue; const AHashList: PUInt32); overload;
|
||||
procedure DoAdd(const AKey: TKey; const AValue: TValue; const AHashList: PUInt32); overload; inline;
|
||||
function DoRemove(const AHashListOrIndex: PUInt32; ALookupResult: SizeInt;
|
||||
ACollectionNotification: TCollectionNotification): TValue;
|
||||
|
||||
function GetQueueCount: SizeInt;
|
||||
protected
|
||||
procedure SetCapacity(ACapacity: SizeInt); override;
|
||||
// bug #24283 - can't descadent from TEnumerable
|
||||
function DoGetEnumerator: TEnumerator<TDictionaryPair>; override;
|
||||
procedure SetMaxLoadFactor(AValue: single); override;
|
||||
function GetLoadFactor: single; override;
|
||||
function GetCapacity: SizeInt; override;
|
||||
strict protected // bug #26181
|
||||
constructor Create(ACapacity: SizeInt; const AComparer: IEqualityComparer<TKey>); override; overload;
|
||||
constructor Create(const AComparer: IEqualityComparer<TKey>); reintroduce; overload;
|
||||
constructor Create(ACollection: TEnumerable<TDictionaryPair>; const AComparer: IEqualityComparer<TKey>); override; overload;
|
||||
{$IFDEF ENABLE_METHODS_WITH_TEnumerableWithPointers}
|
||||
constructor Create(ACollection: TEnumerableWithPointers<TDictionaryPair>; const AComparer: IEqualityComparer<TKey>); override; overload;
|
||||
{$ENDIF}
|
||||
public
|
||||
// TODO: function TryFlushQueue(ACount: SizeInt): SizeInt;
|
||||
|
||||
constructor Create; override; overload;
|
||||
constructor Create(ACapacity: SizeInt); override; overload;
|
||||
constructor Create(ACollection: TEnumerable<TDictionaryPair>); override; overload;
|
||||
{$IFDEF ENABLE_METHODS_WITH_TEnumerableWithPointers}
|
||||
constructor Create(ACollection: TEnumerableWithPointers<TDictionaryPair>); override; overload;
|
||||
{$ENDIF}
|
||||
constructor Create(ACapacity: SizeInt; const AComparer: IExtendedEqualityComparer<TKey>); virtual; overload;
|
||||
constructor Create(const AComparer: IExtendedEqualityComparer<TKey>); overload;
|
||||
constructor Create(ACollection: TEnumerable<TDictionaryPair>; const AComparer: IExtendedEqualityComparer<TKey>); virtual; overload;
|
||||
{$IFDEF ENABLE_METHODS_WITH_TEnumerableWithPointers}
|
||||
constructor Create(ACollection: TEnumerableWithPointers<TDictionaryPair>; const AComparer: IExtendedEqualityComparer<TKey>); virtual; overload;
|
||||
{$ENDIF}
|
||||
destructor Destroy; override;
|
||||
|
||||
procedure Add(constref APair: TPair<TKey, TValue>); override; overload;
|
||||
procedure Add(constref AKey: TKey; constref AValue: TValue); overload;
|
||||
procedure Remove(constref AKey: TKey);
|
||||
function ExtractPair(constref AKey: TKey): TPair<TKey, TValue>;
|
||||
procedure Clear; override;
|
||||
procedure TrimExcess;
|
||||
function TryGetValue(constref AKey: TKey; out AValue: TValue): Boolean;
|
||||
procedure AddOrSetValue(constref AKey: TKey; constref AValue: TValue);
|
||||
function ContainsKey(constref AKey: TKey): Boolean; inline;
|
||||
function ContainsValue(constref AValue: TValue): Boolean; overload;
|
||||
function ContainsValue(constref AValue: TValue; const AEqualityComparer: IEqualityComparer<TValue>): Boolean; virtual; overload;
|
||||
|
||||
property Items[Index: TKey]: TValue read GetItem write SetItem; default;
|
||||
property Keys: TKeyCollection read GetKeys;
|
||||
property Values: TValueCollection read GetValues;
|
||||
property Ptr: PPointersCollection read GetPointers;
|
||||
|
||||
property QueueCount: SizeInt read GetQueueCount;
|
||||
procedure GetMemoryLayout(const AOnGetMemoryLayoutKeyPosition: TOnGetMemoryLayoutKeyPosition);
|
||||
end;
|
||||
|
||||
TDictionaryOwnerships = set of (doOwnsKeys, doOwnsValues);
|
||||
|
||||
TObjectDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS> = class(TDeamortizedDArrayCuckooMap<CUCKOO_CONSTRAINTS>)
|
||||
private
|
||||
FOwnerships: TDictionaryOwnerships;
|
||||
protected
|
||||
procedure KeyNotify(constref AKey: TKey; ACollectionNotification: TCollectionNotification); override;
|
||||
procedure ValueNotify(constref AValue: TValue; ACollectionNotification: TCollectionNotification); override;
|
||||
public
|
||||
// can't be as "Create(AOwnerships: TDictionaryOwnerships; ACapacity: SizeInt = 0)"
|
||||
// because bug #25607
|
||||
constructor Create(AOwnerships: TDictionaryOwnerships); overload;
|
||||
constructor Create(AOwnerships: TDictionaryOwnerships; ACapacity: SizeInt); overload;
|
||||
constructor Create(AOwnerships: TDictionaryOwnerships;
|
||||
const AComparer: IExtendedEqualityComparer<TKey>); overload;
|
||||
constructor Create(AOwnerships: TDictionaryOwnerships; ACapacity: SizeInt;
|
||||
const AComparer: IExtendedEqualityComparer<TKey>); overload;
|
||||
end;
|
||||
|
||||
TObjectOpenAddressingLP<OPEN_ADDRESSING_CONSTRAINTS> = class(TOpenAddressingLP<OPEN_ADDRESSING_CONSTRAINTS>)
|
||||
private
|
||||
FOwnerships: TDictionaryOwnerships;
|
||||
protected
|
||||
procedure KeyNotify(constref AKey: TKey; ACollectionNotification: TCollectionNotification); override;
|
||||
procedure ValueNotify(constref AValue: TValue; ACollectionNotification: TCollectionNotification); override;
|
||||
public
|
||||
// can't be as "Create(AOwnerships: TDictionaryOwnerships; ACapacity: SizeInt = 0)"
|
||||
// because bug #25607
|
||||
constructor Create(AOwnerships: TDictionaryOwnerships); overload;
|
||||
constructor Create(AOwnerships: TDictionaryOwnerships; ACapacity: SizeInt); overload;
|
||||
constructor Create(AOwnerships: TDictionaryOwnerships;
|
||||
const AComparer: IEqualityComparer<TKey>); overload;
|
||||
constructor Create(AOwnerships: TDictionaryOwnerships; ACapacity: SizeInt;
|
||||
const AComparer: IEqualityComparer<TKey>); overload;
|
||||
end;
|
||||
|
||||
// useful generics overloads
|
||||
TOpenAddressingLP<TKey, TValue, THashFactory> = class(TOpenAddressingLP<TKey, TValue, THashFactory, TLinearProbing>);
|
||||
TOpenAddressingLP<TKey, TValue> = class(TOpenAddressingLP<TKey, TValue, TDefaultHashFactory, TLinearProbing>);
|
||||
|
||||
TObjectOpenAddressingLP<TKey, TValue, THashFactory> = class(TObjectOpenAddressingLP<TKey, TValue, THashFactory, TLinearProbing>);
|
||||
TObjectOpenAddressingLP<TKey, TValue> = class(TObjectOpenAddressingLP<TKey, TValue, TDefaultHashFactory, TLinearProbing>);
|
||||
|
||||
// Linear Probing with Tombstones (LPT)
|
||||
TOpenAddressingLPT<TKey, TValue, THashFactory> = class(TOpenAddressingSH<TKey, TValue, THashFactory, TLinearProbing>);
|
||||
TOpenAddressingLPT<TKey, TValue> = class(TOpenAddressingSH<TKey, TValue, TDefaultHashFactory, TLinearProbing>);
|
||||
|
||||
TOpenAddressingQP<TKey, TValue, THashFactory> = class(TOpenAddressingQP<TKey, TValue, THashFactory, TQuadraticProbing>);
|
||||
TOpenAddressingQP<TKey, TValue> = class(TOpenAddressingQP<TKey, TValue, TDefaultHashFactory, TQuadraticProbing>);
|
||||
|
||||
TOpenAddressingDH<TKey, TValue, THashFactory> = class(TOpenAddressingDH<TKey, TValue, THashFactory, TDoubleHashing>);
|
||||
TOpenAddressingDH<TKey, TValue> = class(TOpenAddressingDH<TKey, TValue, TDelphiDoubleHashFactory, TDoubleHashing>);
|
||||
|
||||
TCuckooD2<TKey, TValue, THashFactory> = class(TDeamortizedDArrayCuckooMap<TKey, TValue, THashFactory, TDeamortizedCuckooHashingCfg_D2>);
|
||||
TCuckooD2<TKey, TValue> = class(TDeamortizedDArrayCuckooMap<TKey, TValue, TDelphiDoubleHashFactory, TDeamortizedCuckooHashingCfg_D2>);
|
||||
|
||||
TCuckooD4<TKey, TValue, THashFactory> = class(TDeamortizedDArrayCuckooMap<TKey, TValue, THashFactory, TDeamortizedCuckooHashingCfg_D4>);
|
||||
TCuckooD4<TKey, TValue> = class(TDeamortizedDArrayCuckooMap<TKey, TValue, TDelphiQuadrupleHashFactory, TDeamortizedCuckooHashingCfg_D4>);
|
||||
|
||||
TCuckooD6<TKey, TValue, THashFactory> = class(TDeamortizedDArrayCuckooMap<TKey, TValue, THashFactory, TDeamortizedCuckooHashingCfg_D6>);
|
||||
TCuckooD6<TKey, TValue> = class(TDeamortizedDArrayCuckooMap<TKey, TValue, TDelphiSixfoldHashFactory, TDeamortizedCuckooHashingCfg_D6>);
|
||||
|
||||
TObjectCuckooD2<TKey, TValue, THashFactory> = class(TObjectDeamortizedDArrayCuckooMap<TKey, TValue, THashFactory, TDeamortizedCuckooHashingCfg_D2>);
|
||||
TObjectCuckooD2<TKey, TValue> = class(TObjectDeamortizedDArrayCuckooMap<TKey, TValue, TDelphiDoubleHashFactory, TDeamortizedCuckooHashingCfg_D2>);
|
||||
|
||||
TObjectCuckooD4<TKey, TValue, THashFactory> = class(TObjectDeamortizedDArrayCuckooMap<TKey, TValue, THashFactory, TDeamortizedCuckooHashingCfg_D4>);
|
||||
TObjectCuckooD4<TKey, TValue> = class(TObjectDeamortizedDArrayCuckooMap<TKey, TValue, TDelphiQuadrupleHashFactory, TDeamortizedCuckooHashingCfg_D4>);
|
||||
|
||||
TObjectCuckooD6<TKey, TValue, THashFactory> = class(TObjectDeamortizedDArrayCuckooMap<TKey, TValue, THashFactory, TDeamortizedCuckooHashingCfg_D6>);
|
||||
TObjectCuckooD6<TKey, TValue> = class(TObjectDeamortizedDArrayCuckooMap<TKey, TValue, TDelphiSixfoldHashFactory, TDeamortizedCuckooHashingCfg_D6>);
|
||||
|
||||
// for normal programmers to normal use =)
|
||||
TDictionary<TKey, TValue> = class(TOpenAddressingLP<TKey, TValue>);
|
||||
TObjectDictionary<TKey, TValue> = class(TObjectOpenAddressingLP<TKey, TValue>);
|
||||
|
||||
TFastHashMap<TKey, TValue> = class(TCuckooD2<TKey, TValue>);
|
||||
TFastObjectHashMap<TKey, TValue> = class(TObjectCuckooD2<TKey, TValue>);
|
||||
|
||||
THashMap<TKey, TValue> = class(TCuckooD4<TKey, TValue>);
|
||||
TObjectHashMap<TKey, TValue> = class(TObjectCuckooD4<TKey, TValue>);
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,146 +0,0 @@
|
||||
{
|
||||
This file is part of the Free Pascal/NewPascal run time library.
|
||||
Copyright (c) 2014 by Maciej Izak (hnb)
|
||||
member of the NewPascal development team (http://newpascal.org)
|
||||
|
||||
Copyright(c) 2004-2018 DaThoX
|
||||
|
||||
It contains the generics collections library
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
**********************************************************************}
|
||||
|
||||
unit sparta_Generics.Helpers;
|
||||
|
||||
{$MODE DELPHI}{$H+}
|
||||
{$MODESWITCH TYPEHELPERS}
|
||||
{$OVERFLOWCHECKS OFF}
|
||||
{$RANGECHECKS OFF}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils;
|
||||
|
||||
type
|
||||
{ TValueAnsiStringHelper }
|
||||
|
||||
TValueAnsiStringHelper = record helper for AnsiString
|
||||
function ToLower: AnsiString; inline;
|
||||
end;
|
||||
|
||||
{ TValuewideStringHelper }
|
||||
|
||||
TValueWideStringHelper = record helper for WideString
|
||||
function ToLower: WideString; inline;
|
||||
end;
|
||||
|
||||
{ TValueUnicodeStringHelper }
|
||||
|
||||
TValueUnicodeStringHelper = record helper for UnicodeString
|
||||
function ToLower: UnicodeString; inline;
|
||||
end;
|
||||
|
||||
{ TValueShortStringHelper }
|
||||
|
||||
TValueShortStringHelper = record helper for ShortString
|
||||
function ToLower: ShortString; inline;
|
||||
end;
|
||||
|
||||
{ TValueUTF8StringHelper }
|
||||
|
||||
TValueUTF8StringHelper = record helper for UTF8String
|
||||
function ToLower: UTF8String; inline;
|
||||
end;
|
||||
|
||||
{ TValueRawByteStringHelper }
|
||||
|
||||
TValueRawByteStringHelper = record helper for RawByteString
|
||||
function ToLower: RawByteString; inline;
|
||||
end;
|
||||
|
||||
{ TValueUInt32Helper }
|
||||
|
||||
TValueUInt32Helper = record helper for UInt32
|
||||
class function GetSignMask: UInt32; static; inline;
|
||||
class function GetSizedSignMask(ABits: Byte): UInt32; static; inline;
|
||||
class function GetBitsLength: Byte; static; inline;
|
||||
|
||||
const
|
||||
SIZED_SIGN_MASK: array[1..32] of UInt32 = (
|
||||
$80000000, $C0000000, $E0000000, $F0000000, $F8000000, $FC000000, $FE000000, $FF000000,
|
||||
$FF800000, $FFC00000, $FFE00000, $FFF00000, $FFF80000, $FFFC0000, $FFFE0000, $FFFF0000,
|
||||
$FFFF8000, $FFFFC000, $FFFFE000, $FFFFF000, $FFFFF800, $FFFFFC00, $FFFFFE00, $FFFFFF00,
|
||||
$FFFFFF80, $FFFFFFC0, $FFFFFFE0, $FFFFFFF0, $FFFFFFF8, $FFFFFFFC, $FFFFFFFE, $FFFFFFFF);
|
||||
BITS_LENGTH = 32;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TRawDataStringHelper }
|
||||
|
||||
function TValueAnsiStringHelper.ToLower: AnsiString;
|
||||
begin
|
||||
Result := LowerCase(Self);
|
||||
end;
|
||||
|
||||
{ TValueWideStringHelper }
|
||||
|
||||
function TValueWideStringHelper.ToLower: WideString;
|
||||
begin
|
||||
Result := LowerCase(Self);
|
||||
end;
|
||||
|
||||
{ TValueUnicodeStringHelper }
|
||||
|
||||
function TValueUnicodeStringHelper.ToLower: UnicodeString;
|
||||
begin
|
||||
Result := LowerCase(Self);
|
||||
end;
|
||||
|
||||
{ TValueShortStringHelper }
|
||||
|
||||
function TValueShortStringHelper.ToLower: ShortString;
|
||||
begin
|
||||
Result := LowerCase(Self);
|
||||
end;
|
||||
|
||||
{ TValueUTF8StringHelper }
|
||||
|
||||
function TValueUTF8StringHelper.ToLower: UTF8String;
|
||||
begin
|
||||
Result := LowerCase(Self);
|
||||
end;
|
||||
|
||||
{ TValueRawByteStringHelper }
|
||||
|
||||
function TValueRawByteStringHelper.ToLower: RawByteString;
|
||||
begin
|
||||
Result := LowerCase(Self);
|
||||
end;
|
||||
|
||||
{ TValueUInt32Helper }
|
||||
|
||||
class function TValueUInt32Helper.GetSignMask: UInt32;
|
||||
begin
|
||||
Result := $80000000;
|
||||
end;
|
||||
|
||||
class function TValueUInt32Helper.GetSizedSignMask(ABits: Byte): UInt32;
|
||||
begin
|
||||
Result := SIZED_SIGN_MASK[ABits];
|
||||
end;
|
||||
|
||||
class function TValueUInt32Helper.GetBitsLength: Byte;
|
||||
begin
|
||||
Result := BITS_LENGTH;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -1,227 +0,0 @@
|
||||
{
|
||||
This file is part of the Free Pascal/NewPascal run time library.
|
||||
Copyright (c) 2014 by Maciej Izak (hnb)
|
||||
member of the NewPascal development team (http://newpascal.org)
|
||||
|
||||
Copyright(c) 2004-2018 DaThoX
|
||||
|
||||
It contains the generics collections library
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
**********************************************************************}
|
||||
|
||||
unit sparta_Generics.MemoryExpanders;
|
||||
// Memory expanders
|
||||
|
||||
{$mode delphi}
|
||||
{$MACRO ON}
|
||||
{$OVERFLOWCHECKS OFF}
|
||||
{$RANGECHECKS OFF}
|
||||
{.$WARN 5024 OFF}
|
||||
{.$WARN 4079 OFF}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils;
|
||||
|
||||
type
|
||||
TProbeSequence = class
|
||||
public
|
||||
end;
|
||||
|
||||
{ TLinearProbing }
|
||||
|
||||
TLinearProbing = class(TProbeSequence)
|
||||
public
|
||||
class function Probe(I, Hash: UInt32): UInt32; static; inline;
|
||||
|
||||
const MAX_LOAD_FACTOR = 1;
|
||||
const DEFAULT_LOAD_FACTOR = 0.75;
|
||||
end;
|
||||
|
||||
{ TQuadraticProbing }
|
||||
|
||||
TQuadraticProbing = class(TProbeSequence)
|
||||
public
|
||||
class function Probe(I, Hash: UInt32): UInt32; static; inline;
|
||||
|
||||
const MAX_LOAD_FACTOR = 0.5;
|
||||
const DEFAULT_LOAD_FACTOR = 0.5;
|
||||
end;
|
||||
|
||||
{ TDoubleHashing }
|
||||
|
||||
TDoubleHashing = class(TProbeSequence)
|
||||
public
|
||||
class function Probe(I, Hash1: UInt32; Hash2: UInt32 = 1): UInt32; static; inline;
|
||||
|
||||
const MAX_LOAD_FACTOR = 1;
|
||||
const DEFAULT_LOAD_FACTOR = 0.85;
|
||||
end;
|
||||
|
||||
const
|
||||
// http://stackoverflow.com/questions/757059/position-of-least-significant-bit-that-is-set
|
||||
// MultiplyDeBruijnBitPosition[uint32(((numberInt32 and -numberInt32) * $077CB531)) shr 27]
|
||||
MultiplyDeBruijnBitPosition: array[0..31] of Int32 =
|
||||
(
|
||||
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
|
||||
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
|
||||
);
|
||||
|
||||
// http://primes.utm.edu/lists/2small/0bit.html
|
||||
// http://www.math.niu.edu/~rusin/known-math/98/pi_x
|
||||
// http://oeis.org/A014234/
|
||||
PrimaryNumbersJustLessThanPowerOfTwo: array[0..31] of UInt32 =
|
||||
(
|
||||
0, 1, 3, 7, 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
|
||||
);
|
||||
|
||||
// http://oeis.org/A014210
|
||||
// http://oeis.org/A203074
|
||||
PrimaryNumbersJustBiggerThanPowerOfTwo: array[0..31] of UInt32 = (
|
||||
2,3,5,11,17,37,67,131,257,521,1031,2053,4099,
|
||||
8209,16411,32771,65537,131101,262147,524309,
|
||||
1048583,2097169,4194319,8388617,16777259,33554467,
|
||||
67108879,134217757,268435459,536870923,1073741827,
|
||||
2147483659);
|
||||
|
||||
// Fibonacci numbers
|
||||
FibonacciNumbers: array[0..44] of UInt32 = (
|
||||
{0,1,1,2,3,}0,5,8,13,21,34,55,89,144,233,377,610,987,
|
||||
1597,2584,4181,6765,10946,17711,28657,46368,75025,
|
||||
121393,196418,317811,514229,832040,1346269,
|
||||
2178309,3524578,5702887,9227465,14930352,24157817,
|
||||
39088169, 63245986, 102334155, 165580141, 267914296,
|
||||
433494437, 701408733, 1134903170, 1836311903, 2971215073,
|
||||
{! not fib number - this is memory limit} 4294967295);
|
||||
|
||||
// Largest prime not exceeding Fibonacci(n)
|
||||
// http://oeis.org/A138184/list
|
||||
// http://www.numberempire.com/primenumbers.php
|
||||
PrimaryNumbersJustLessThanFibonacciNumbers: array[0..44] of UInt32 = (
|
||||
{! not correlated to fib number. For empty table} 0,
|
||||
5,7,13,19,31,53,89,139,233,373,607,983,1597,
|
||||
2579,4177,6763,10939,17707,28657,46351,75017,
|
||||
121379,196387,317797,514229,832003,1346249,
|
||||
2178283,3524569,5702867,9227443,14930341,24157811,
|
||||
39088157,63245971,102334123,165580123,267914279,
|
||||
433494437,701408717,1134903127,1836311879,2971215073,
|
||||
{! not correlated to fib number - this is prime memory limit} 4294967291);
|
||||
|
||||
// Smallest prime >= n-th Fibonacci number.
|
||||
// http://oeis.org/A138185
|
||||
PrimaryNumbersJustBiggerThanFibonacciNumbers: array[0..44] of UInt32 = (
|
||||
{! not correlated to fib number. For empty table} 0,
|
||||
5,11,13,23,37,59,89,149,233,379,613,
|
||||
991,1597,2591,4201,6779,10949,17713,28657,46381,
|
||||
75029,121403,196429,317827,514229,832063,1346273,
|
||||
2178313,3524603,5702897,9227479,14930387,24157823,
|
||||
39088193,63245989,102334157,165580147,267914303,
|
||||
433494437,701408753,1134903179,1836311951,2971215073,
|
||||
{! not correlated to fib number - this is prime memory limit} 4294967291);
|
||||
|
||||
type
|
||||
|
||||
{ TCuckooHashingCfg }
|
||||
|
||||
TCuckooHashingCfg = class
|
||||
public
|
||||
const D = 2;
|
||||
const MAX_LOAD_FACTOR = 0.5;
|
||||
|
||||
class function LoadFactor(M: Integer): Integer; virtual;
|
||||
end;
|
||||
|
||||
TStdCuckooHashingCfg = class(TCuckooHashingCfg)
|
||||
public
|
||||
const MAX_LOOP = 1000;
|
||||
end;
|
||||
|
||||
TDeamortizedCuckooHashingCfg = class(TCuckooHashingCfg)
|
||||
public
|
||||
const L = 5;
|
||||
end;
|
||||
|
||||
TDeamortizedCuckooHashingCfg_D2 = TDeamortizedCuckooHashingCfg;
|
||||
|
||||
{ TDeamortizedCuckooHashingCfg_D4 }
|
||||
|
||||
TDeamortizedCuckooHashingCfg_D4 = class(TDeamortizedCuckooHashingCfg)
|
||||
public
|
||||
const D = 4;
|
||||
const L = 20;
|
||||
const MAX_LOAD_FACTOR = 0.9;
|
||||
|
||||
class function LoadFactor(M: Integer): Integer; override;
|
||||
end;
|
||||
|
||||
{ TDeamortizedCuckooHashingCfg_D6 }
|
||||
|
||||
TDeamortizedCuckooHashingCfg_D6 = class(TDeamortizedCuckooHashingCfg)
|
||||
public
|
||||
const D = 6;
|
||||
const L = 170;
|
||||
const MAX_LOAD_FACTOR = 0.99;
|
||||
|
||||
class function LoadFactor(M: Integer): Integer; override;
|
||||
end;
|
||||
|
||||
TL5CuckooHashingCfg = class(TCuckooHashingCfg)
|
||||
public
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TDeamortizedCuckooHashingCfg_D6 }
|
||||
|
||||
class function TDeamortizedCuckooHashingCfg_D6.LoadFactor(M: Integer): Integer;
|
||||
begin
|
||||
Result:=Pred(Round(MAX_LOAD_FACTOR*M));
|
||||
end;
|
||||
|
||||
{ TDeamortizedCuckooHashingCfg_D4 }
|
||||
|
||||
class function TDeamortizedCuckooHashingCfg_D4.LoadFactor(M: Integer): Integer;
|
||||
begin
|
||||
Result:=Pred(Round(MAX_LOAD_FACTOR*M));
|
||||
end;
|
||||
|
||||
{ TCuckooHashingCfg }
|
||||
|
||||
class function TCuckooHashingCfg.LoadFactor(M: Integer): Integer;
|
||||
begin
|
||||
Result := Pred(M shr 1);
|
||||
end;
|
||||
|
||||
{ TLinearProbing }
|
||||
|
||||
class function TLinearProbing.Probe(I, Hash: UInt32): UInt32;
|
||||
begin
|
||||
Result := (Hash + I)
|
||||
end;
|
||||
|
||||
{ TQuadraticProbing }
|
||||
|
||||
class function TQuadraticProbing.Probe(I, Hash: UInt32): UInt32;
|
||||
begin
|
||||
Result := (Hash + Sqr(I));
|
||||
end;
|
||||
|
||||
{ TDoubleHashingNoMod }
|
||||
|
||||
class function TDoubleHashing.Probe(I, Hash1: UInt32; Hash2: UInt32): UInt32;
|
||||
begin
|
||||
Result := Hash1 + I * Hash2;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -1,37 +0,0 @@
|
||||
{
|
||||
This file is part of the Free Pascal/NewPascal run time library.
|
||||
Copyright (c) 2014 by Maciej Izak (hnb)
|
||||
member of the NewPascal development team (http://newpascal.org)
|
||||
|
||||
Copyright(c) 2004-2018 DaThoX
|
||||
|
||||
It contains the generics collections library
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
**********************************************************************}
|
||||
|
||||
unit sparta_Generics.Strings;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
resourcestring
|
||||
SArgumentOutOfRange = 'Argument out of range';
|
||||
SArgumentNilNode = 'Node is nil';
|
||||
SDuplicatesNotAllowed = 'Duplicates not allowed in dictionary';
|
||||
SCollectionInconsistency = 'Collection inconsistency';
|
||||
SCollectionDuplicate = 'Collection does not allow duplicates';
|
||||
SDictionaryKeyDoesNotExist = 'Dictionary key does not exist';
|
||||
SItemNotFound = 'Item not found';
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
|
@ -1,61 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<Package Version="4">
|
||||
<PathDelim Value="\"/>
|
||||
<Name Value="sparta_Generics"/>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="source\inc"/>
|
||||
<OtherUnitFiles Value="source"/>
|
||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)\"/>
|
||||
</SearchPaths>
|
||||
</CompilerOptions>
|
||||
<Files Count="8">
|
||||
<Item1>
|
||||
<Filename Value="source\sparta_generics.collections.pas"/>
|
||||
<UnitName Value="Generics.Collections"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<Filename Value="source\sparta_generics.defaults.pas"/>
|
||||
<UnitName Value="Generics.Defaults"/>
|
||||
</Item2>
|
||||
<Item3>
|
||||
<Filename Value="source\sparta_generics.hashes.pas"/>
|
||||
<UnitName Value="Generics.Hashes"/>
|
||||
</Item3>
|
||||
<Item4>
|
||||
<Filename Value="source\sparta_generics.helpers.pas"/>
|
||||
<UnitName Value="Generics.Helpers"/>
|
||||
</Item4>
|
||||
<Item5>
|
||||
<Filename Value="source\sparta_generics.memoryexpanders.pas"/>
|
||||
<UnitName Value="Generics.MemoryExpanders"/>
|
||||
</Item5>
|
||||
<Item6>
|
||||
<Filename Value="source\sparta_generics.strings.pas"/>
|
||||
<UnitName Value="Generics.Strings"/>
|
||||
</Item6>
|
||||
<Item7>
|
||||
<Filename Value="source\inc\generics.dictionaries.inc"/>
|
||||
<Type Value="Include"/>
|
||||
</Item7>
|
||||
<Item8>
|
||||
<Filename Value="source\inc\generics.dictionariesh.inc"/>
|
||||
<Type Value="Include"/>
|
||||
</Item8>
|
||||
</Files>
|
||||
<RequiredPkgs Count="1">
|
||||
<Item1>
|
||||
<PackageName Value="FCL"/>
|
||||
</Item1>
|
||||
</RequiredPkgs>
|
||||
<UsageOptions>
|
||||
<UnitPath Value="$(PkgOutDir)"/>
|
||||
</UsageOptions>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
</PublishOptions>
|
||||
</Package>
|
||||
</CONFIG>
|
@ -1,17 +0,0 @@
|
||||
{ This file was automatically created by Lazarus. Do not edit!
|
||||
This source is only used to compile and install the package.
|
||||
}
|
||||
|
||||
unit sparta_Generics;
|
||||
|
||||
{$warn 5023 off : no warning about unused units}
|
||||
interface
|
||||
|
||||
uses
|
||||
sparta_Generics.Collections, sparta_Generics.Defaults,
|
||||
sparta_Generics.Hashes, sparta_Generics.Helpers,
|
||||
sparta_Generics.MemoryExpanders, sparta_Generics.Strings;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
@ -46,16 +46,13 @@
|
||||
<UnitName Value="sparta_abstractresizer"/>
|
||||
</Item8>
|
||||
</Files>
|
||||
<RequiredPkgs Count="3">
|
||||
<Item1>
|
||||
<PackageName Value="sparta_Generics"/>
|
||||
</Item1>
|
||||
<RequiredPkgs Count="2">
|
||||
<Item2>
|
||||
<PackageName Value="LCL"/>
|
||||
</Item2>
|
||||
<Item3>
|
||||
<Item1>
|
||||
<PackageName Value="FCL"/>
|
||||
</Item3>
|
||||
</Item1>
|
||||
</RequiredPkgs>
|
||||
<UsageOptions>
|
||||
<UnitPath Value="$(PkgOutDir)"/>
|
||||
|
@ -1 +0,0 @@
|
||||
$(LazarusDir)/components/sparta/generics/sparta_generics.lpk
|
Loading…
Reference in New Issue
Block a user