Keywords
This commit is contained in:
@@ -4,6 +4,8 @@ interface
|
||||
|
||||
uses
|
||||
System.SysUtils,
|
||||
System.Generics.Collections,
|
||||
System.Generics.Defaults,
|
||||
Myc.Data.Decimal,
|
||||
Myc.Data.Series,
|
||||
Myc.Data.Keyword;
|
||||
@@ -92,21 +94,22 @@ type
|
||||
TScalarTuple = TArray<TScalar>;
|
||||
|
||||
// A field definition for a scalar record.
|
||||
TScalarRecordField = TKeywordMapping<TScalar.TKind>.TField;
|
||||
TScalarRecordDefinition = TKeywordMapping<TScalar.TKind>;
|
||||
TScalarRecordField = TPair<IKeyword, TScalar.TKind>;
|
||||
IScalarRecordDefinition = IKeywordMapping<TScalar.TKind>;
|
||||
TScalarRecordRegistry = TKeywordMappingRegistry<TScalar.TKind>;
|
||||
|
||||
// A record of scalar values, based on a definition.
|
||||
TScalarRecord = record
|
||||
public
|
||||
constructor Create(const ADef: TScalarRecordDefinition; const AFields: TArray<TScalar.TValue>);
|
||||
function GetDef: TScalarRecordDefinition; inline;
|
||||
constructor Create(const ADef: IScalarRecordDefinition; const AFields: TArray<TScalar.TValue>);
|
||||
function GetDef: IScalarRecordDefinition; inline;
|
||||
function GetFields: TArray<TScalar.TValue>; inline;
|
||||
function GetKeys(const Key: IKeyword): TScalar;
|
||||
property Def: TScalarRecordDefinition read GetDef;
|
||||
property Def: IScalarRecordDefinition read GetDef;
|
||||
property Fields: TArray<TScalar.TValue> read GetFields;
|
||||
property Keys[const Key: IKeyword]: TScalar read GetKeys; default;
|
||||
strict private
|
||||
FDef: TScalarRecordDefinition;
|
||||
FDef: IScalarRecordDefinition;
|
||||
FFields: TArray<TScalar.TValue>;
|
||||
end;
|
||||
|
||||
@@ -142,22 +145,21 @@ type
|
||||
IRecordSeries = interface
|
||||
{$region 'private'}
|
||||
function GetCount: Int64;
|
||||
function GetDef: TScalarRecordDefinition;
|
||||
function GetItems(Idx: Integer): TScalarRecord;
|
||||
function GetDef: IScalarRecordDefinition;
|
||||
function GetTotalCount: Int64;
|
||||
function GetFields(const Key: IKeyword): ISeries;
|
||||
{$endregion}
|
||||
procedure Add(const Item: TScalarRecord; Lookback: Int64 = -1);
|
||||
function CreateMemberSeries(const Key: IKeyword): ISeries;
|
||||
property Count: Int64 read GetCount;
|
||||
property Def: TScalarRecordDefinition read GetDef;
|
||||
property Items[Idx: Integer]: TScalarRecord read GetItems; default;
|
||||
property Def: IScalarRecordDefinition read GetDef;
|
||||
property Fields[const Key: IKeyword]: ISeries read GetFields; default;
|
||||
property TotalCount: Int64 read GetTotalCount;
|
||||
end;
|
||||
|
||||
// A time series of scalar records, optimized for memory and access speed.
|
||||
TScalarRecordSeries = class(TInterfacedObject, IRecordSeries)
|
||||
type
|
||||
TMemberSeries = class(TInterfacedObject, ISeries)
|
||||
TMemberSeries = class(TObject, ISeries)
|
||||
private
|
||||
FRecordSeries: TScalarRecordSeries;
|
||||
FKind: TScalar.TKind;
|
||||
@@ -165,26 +167,29 @@ type
|
||||
function GetCount: Int64;
|
||||
function GetItems(Idx: Integer): TScalar;
|
||||
function GetTotalCount: Int64;
|
||||
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
|
||||
function _AddRef: Integer; stdcall;
|
||||
function _Release: Integer; stdcall;
|
||||
public
|
||||
constructor Create(ARecordSeries: TScalarRecordSeries; AElementIdx: Integer);
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
private
|
||||
FDef: TScalarRecordDefinition;
|
||||
FDef: IScalarRecordDefinition;
|
||||
FArray: TChunkArray<TScalar.TValue>;
|
||||
FFields: TArray<TMemberSeries>;
|
||||
FTotalCount: Int64;
|
||||
function GetCount: Int64; inline;
|
||||
function GetDef: TScalarRecordDefinition; inline;
|
||||
function GetItems(Idx: Integer): TScalarRecord; inline;
|
||||
function GetFields(const Key: IKeyword): ISeries;
|
||||
function GetDef: IScalarRecordDefinition; inline;
|
||||
function GetTotalCount: Int64; inline;
|
||||
function GetItemRef(Idx: Integer): TChunkArray<TScalar.TValue>.PT; inline;
|
||||
public
|
||||
constructor Create(const ADef: TScalarRecordDefinition);
|
||||
constructor Create(const ADef: IScalarRecordDefinition);
|
||||
destructor Destroy; override;
|
||||
procedure Add(const Item: TScalarRecord; Lookback: Int64 = -1);
|
||||
function CreateMemberSeries(const Key: IKeyword): ISeries;
|
||||
property Count: Int64 read GetCount;
|
||||
property Def: TScalarRecordDefinition read GetDef;
|
||||
property Items[Idx: Integer]: TScalarRecord read GetItems; default;
|
||||
property Fields[const Key: IKeyword]: ISeries read GetFields; default;
|
||||
property Def: IScalarRecordDefinition read GetDef;
|
||||
property TotalCount: Int64 read GetTotalCount;
|
||||
end;
|
||||
|
||||
@@ -519,14 +524,14 @@ end;
|
||||
|
||||
{ TScalarRecord }
|
||||
|
||||
constructor TScalarRecord.Create(const ADef: TScalarRecordDefinition; const AFields: TArray<TScalar.TValue>);
|
||||
constructor TScalarRecord.Create(const ADef: IScalarRecordDefinition; const AFields: TArray<TScalar.TValue>);
|
||||
begin
|
||||
Assert(Length(ADef.Fields) = Length(AFields), 'Field definition and value count must match.');
|
||||
FDef := ADef;
|
||||
FFields := AFields;
|
||||
end;
|
||||
|
||||
function TScalarRecord.GetDef: TScalarRecordDefinition;
|
||||
function TScalarRecord.GetDef: IScalarRecordDefinition;
|
||||
begin
|
||||
Result := FDef;
|
||||
end;
|
||||
@@ -549,11 +554,21 @@ end;
|
||||
|
||||
{ TScalarRecordSeries }
|
||||
|
||||
constructor TScalarRecordSeries.Create(const ADef: TScalarRecordDefinition);
|
||||
constructor TScalarRecordSeries.Create(const ADef: IScalarRecordDefinition);
|
||||
begin
|
||||
Assert(Length(ADef.Fields) > 0);
|
||||
FDef := ADef;
|
||||
FTotalCount := 0;
|
||||
SetLength(FFields, Length(FDef.Fields));
|
||||
for var i := 0 to High(FFields) do
|
||||
FFields[i] := TMemberSeries.Create(Self, i);
|
||||
end;
|
||||
|
||||
destructor TScalarRecordSeries.Destroy;
|
||||
begin
|
||||
for var i := High(FFields) downto 0 do
|
||||
FFields[i].Free;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TScalarRecordSeries.Add(const Item: TScalarRecord; Lookback: Int64 = -1);
|
||||
@@ -562,13 +577,13 @@ begin
|
||||
inc(FTotalCount);
|
||||
end;
|
||||
|
||||
function TScalarRecordSeries.CreateMemberSeries(const Key: IKeyword): ISeries;
|
||||
function TScalarRecordSeries.GetFields(const Key: IKeyword): ISeries;
|
||||
begin
|
||||
var elem := FDef.IndexOf(Key);
|
||||
if elem < 0 then
|
||||
raise EArgumentException.CreateFmt('Field ":%s" not found in record definition.', [Key.Name]);
|
||||
|
||||
Result := TMemberSeries.Create(Self, elem);
|
||||
Result := FFields[elem];
|
||||
end;
|
||||
|
||||
function TScalarRecordSeries.GetCount: Int64;
|
||||
@@ -576,7 +591,7 @@ begin
|
||||
Result := FArray.Count div Length(FDef.Fields);
|
||||
end;
|
||||
|
||||
function TScalarRecordSeries.GetDef: TScalarRecordDefinition;
|
||||
function TScalarRecordSeries.GetDef: IScalarRecordDefinition;
|
||||
begin
|
||||
Result := FDef;
|
||||
end;
|
||||
@@ -587,15 +602,6 @@ begin
|
||||
Result := FArray.ItemRef[(FArray.Count - len) - (Idx * len)];
|
||||
end;
|
||||
|
||||
function TScalarRecordSeries.GetItems(Idx: Integer): TScalarRecord;
|
||||
var
|
||||
values: TArray<TScalar.TValue>;
|
||||
begin
|
||||
SetLength(values, Length(FDef.Fields));
|
||||
Move(GetItemRef(Idx)^, values[0], sizeof(TScalar.TValue) * Length(values));
|
||||
Result.Create(FDef, values);
|
||||
end;
|
||||
|
||||
function TScalarRecordSeries.GetTotalCount: Int64;
|
||||
begin
|
||||
Result := FTotalCount;
|
||||
@@ -643,21 +649,16 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TScalarRecordSeries.TMemberSeries }
|
||||
|
||||
constructor TScalarRecordSeries.TMemberSeries.Create(ARecordSeries: TScalarRecordSeries; AElementIdx: Integer);
|
||||
begin
|
||||
inherited Create;
|
||||
FRecordSeries := ARecordSeries;
|
||||
FRecordSeries._AddRef;
|
||||
FKind := FRecordSeries.FDef.Fields[AElementIdx].Value;
|
||||
FOffset := sizeof(TScalar.TValue) * AElementIdx;
|
||||
end;
|
||||
|
||||
destructor TScalarRecordSeries.TMemberSeries.Destroy;
|
||||
begin
|
||||
FRecordSeries._Release;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
function TScalarRecordSeries.TMemberSeries.GetCount: Int64;
|
||||
begin
|
||||
Result := FRecordSeries.Count;
|
||||
@@ -677,6 +678,24 @@ begin
|
||||
Result := FRecordSeries.TotalCount;
|
||||
end;
|
||||
|
||||
function TScalarRecordSeries.TMemberSeries.QueryInterface(const IID: TGUID; out Obj): HResult;
|
||||
begin
|
||||
if GetInterface(IID, Obj) then
|
||||
Result := S_OK
|
||||
else
|
||||
Result := E_NOINTERFACE;
|
||||
end;
|
||||
|
||||
function TScalarRecordSeries.TMemberSeries._AddRef: Integer;
|
||||
begin
|
||||
Result := FRecordSeries._AddRef;
|
||||
end;
|
||||
|
||||
function TScalarRecordSeries.TMemberSeries._Release: Integer;
|
||||
begin
|
||||
Result := FRecordSeries._Release;
|
||||
end;
|
||||
|
||||
{ TScalarSeries }
|
||||
|
||||
constructor TScalarSeries.Create(AKind: TScalar.TKind);
|
||||
|
||||
Reference in New Issue
Block a user