IScalarRecord
This commit is contained in:
@@ -146,20 +146,18 @@ type
|
||||
IScalarRecord = IKeywordMapping<TScalar>;
|
||||
TScalarRecordRegistry = TKeywordMappingRegistry<TScalar.TKind>;
|
||||
|
||||
// A record of scalar values, based on a definition.
|
||||
TScalarRecord = record
|
||||
public
|
||||
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: IScalarRecordDefinition read GetDef;
|
||||
property Fields: TArray<TScalar.TValue> read GetFields;
|
||||
property Keys[const Key: IKeyword]: TScalar read GetKeys; default;
|
||||
strict private
|
||||
TScalarRecord = class(TInterfacedObject, IScalarRecord)
|
||||
private
|
||||
FDef: IScalarRecordDefinition;
|
||||
FFields: TArray<TScalar.TValue>;
|
||||
end deprecated;
|
||||
FData: TArray<TScalar.TValue>;
|
||||
|
||||
function IndexOf(const Key: IKeyword): Integer;
|
||||
function GetCount: Integer;
|
||||
function GetItems(Idx: Integer): TPair<IKeyword, TScalar>;
|
||||
function GetFields(const Key: IKeyword): TScalar;
|
||||
public
|
||||
constructor Create(const ADef: IScalarRecordDefinition; const AData: TArray<TScalar.TValue>);
|
||||
end;
|
||||
|
||||
ISeries = interface
|
||||
{$region 'private'}
|
||||
@@ -197,7 +195,7 @@ type
|
||||
function GetTotalCount: Int64;
|
||||
function GetFields(const Key: IKeyword): ISeries;
|
||||
{$endregion}
|
||||
procedure Add(const Item: TScalarRecord; Lookback: Int64 = -1);
|
||||
procedure Add(const Item: IScalarRecord; Lookback: Int64 = -1);
|
||||
procedure AddRaw(const Data; Lookback: Int64 = -1);
|
||||
property Count: Int64 read GetCount;
|
||||
property Def: IScalarRecordDefinition read GetDef;
|
||||
@@ -233,7 +231,7 @@ type
|
||||
public
|
||||
constructor Create(const ADef: IScalarRecordDefinition);
|
||||
destructor Destroy; override;
|
||||
procedure Add(const Item: TScalarRecord; Lookback: Int64 = -1);
|
||||
procedure Add(const Item: IScalarRecord; Lookback: Int64 = -1);
|
||||
|
||||
// Copies data directly from the Data reference (zero-copy wrapper)
|
||||
procedure AddRaw(const Data; Lookback: Int64 = -1);
|
||||
@@ -801,36 +799,6 @@ begin
|
||||
Items := AItems;
|
||||
end;
|
||||
|
||||
{ TScalarRecord }
|
||||
|
||||
constructor TScalarRecord.Create(const ADef: IScalarRecordDefinition; const AFields: TArray<TScalar.TValue>);
|
||||
begin
|
||||
Assert(ADef.Count = Length(AFields), 'Field definition and value count must match.');
|
||||
FDef := ADef;
|
||||
FFields := AFields;
|
||||
end;
|
||||
|
||||
function TScalarRecord.GetDef: IScalarRecordDefinition;
|
||||
begin
|
||||
Result := FDef;
|
||||
end;
|
||||
|
||||
function TScalarRecord.GetFields: TArray<TScalar.TValue>;
|
||||
begin
|
||||
Result := FFields;
|
||||
end;
|
||||
|
||||
function TScalarRecord.GetKeys(const Key: IKeyword): TScalar;
|
||||
var
|
||||
idx: Integer;
|
||||
begin
|
||||
idx := FDef.IndexOf(Key);
|
||||
if idx < 0 then
|
||||
raise EArgumentException.CreateFmt('Field ":%s" not found in record definition.', [Key.Name]);
|
||||
|
||||
Result.Create(FDef[idx].Value, FFields[idx]);
|
||||
end;
|
||||
|
||||
{ TScalarRecordSeries }
|
||||
|
||||
constructor TScalarRecordSeries.Create(const ADef: IScalarRecordDefinition);
|
||||
@@ -850,22 +818,23 @@ begin
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TScalarRecordSeries.Add(const Item: TScalarRecord; Lookback: Int64 = -1);
|
||||
procedure TScalarRecordSeries.Add(const Item: IScalarRecord; Lookback: Int64 = -1);
|
||||
begin
|
||||
FArray.Add(Item.Fields, FDef.Count * Integer(Lookback));
|
||||
var lb := FDef.Count * Integer(Lookback);
|
||||
for var i := 0 to FDef.Count - 1 do
|
||||
FArray.Add(Item[i].Value.Value, lb);
|
||||
inc(FTotalCount);
|
||||
end;
|
||||
|
||||
procedure TScalarRecordSeries.AddRaw(const Data; Lookback: Int64 = -1);
|
||||
type
|
||||
TValueArr = array[0..MaxInt div SizeOf(TScalar.TValue) - 1] of TScalar.TValue;
|
||||
PValueArr = ^TValueArr;
|
||||
var
|
||||
len: Integer;
|
||||
begin
|
||||
len := FDef.Count;
|
||||
// Use Slice to pass the raw data as an open array without copying.
|
||||
FArray.Add(Slice(PValueArr(@Data)^, len), len * Integer(Lookback));
|
||||
var lb := FDef.Count * Integer(Lookback);
|
||||
var P: TScalar.PValue := @Data;
|
||||
for var i := 0 to FDef.Count - 1 do
|
||||
begin
|
||||
FArray.Add(P^, lb);
|
||||
inc(P);
|
||||
end;
|
||||
inc(FTotalCount);
|
||||
end;
|
||||
|
||||
@@ -1042,6 +1011,45 @@ begin
|
||||
Result := TScalar.FromInt64(sourceIndex);
|
||||
end;
|
||||
|
||||
{ TScalarRecord }
|
||||
|
||||
constructor TScalarRecord.Create(const ADef: IScalarRecordDefinition; const AData: TArray<TScalar.TValue>);
|
||||
begin
|
||||
inherited Create;
|
||||
FDef := ADef;
|
||||
FData := AData;
|
||||
end;
|
||||
|
||||
function TScalarRecord.GetCount: Integer;
|
||||
begin
|
||||
Result := FDef.Count;
|
||||
end;
|
||||
|
||||
function TScalarRecord.GetFields(const Key: IKeyword): TScalar;
|
||||
var
|
||||
idx: Integer;
|
||||
begin
|
||||
idx := FDef.IndexOf(Key);
|
||||
if idx < 0 then
|
||||
exit(Default(TScalar));
|
||||
|
||||
// Return the raw TValue at the offset
|
||||
Result.Kind := FDef[idx].Value;
|
||||
Result.Value := FData[idx];
|
||||
end;
|
||||
|
||||
function TScalarRecord.GetItems(Idx: Integer): TPair<IKeyword, TScalar>;
|
||||
begin
|
||||
Result.Key := FDef[Idx].Key;
|
||||
Result.Value.Kind := FDef[idx].Value;
|
||||
Result.Value.Value := FData[idx];
|
||||
end;
|
||||
|
||||
function TScalarRecord.IndexOf(const Key: IKeyword): Integer;
|
||||
begin
|
||||
Result := FDef.IndexOf(Key);
|
||||
end;
|
||||
|
||||
initialization
|
||||
Assert(sizeof(TScalar.TValue) = 8);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user