Files
MycLib/Src/Data/Myc.Data.Keyword.pas
T
Michael Schimmel dfe1f04333 Keywords
2025-10-30 15:23:34 +01:00

84 lines
1.9 KiB
ObjectPascal

unit Myc.Data.Keyword;
interface
uses
System.SysUtils,
System.Classes,
System.Generics.Collections,
System.SyncObjs;
type
// The runtime representation of an interned keyword
IKeyword = interface(IInterface)
function GetName: string;
property Name: string read GetName;
end;
// Factory and registry for all keywords (Flyweight Pattern)
TKeywordRegistry = record
strict private
type
TKeyword = class(TInterfacedObject, IKeyword)
private
FName: string;
function GetName: string;
public
constructor Create(const AName: string);
end;
strict private
class var
FLock: TSpinLock;
class var
FRegistry: TDictionary<string, IKeyword>;
class constructor Create;
class destructor Destroy;
public
// Gets or creates the interned keyword for the given name.
class function Intern(const AName: string): IKeyword; static;
end;
implementation
{ TKeywordRegistry.TKeyword }
constructor TKeywordRegistry.TKeyword.Create(const AName: string);
begin
inherited Create;
FName := AName;
end;
function TKeywordRegistry.TKeyword.GetName: string;
begin
Result := FName;
end;
{ TKeywordRegistry }
class constructor TKeywordRegistry.Create;
begin
FLock := TSpinLock.Create(false);
FRegistry := TDictionary<string, IKeyword>.Create;
end;
class destructor TKeywordRegistry.Destroy;
begin
FRegistry.Free;
end;
class function TKeywordRegistry.Intern(const AName: string): IKeyword;
begin
FLock.Enter;
try
if not FRegistry.TryGetValue(AName, Result) then
begin
Result := TKeyword.Create(AName);
FRegistry.Add(AName, Result);
end;
finally
FLock.Exit;
end;
end;
end.