Refacoring data pipeline
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -416,7 +416,7 @@ begin
|
||||
|
||||
// Converter: Transforms raw IRecordSeries (Columns) into TArray<TDataPoint>
|
||||
|
||||
var unpacker: TConverter<TScalarBatch, IScalarRecord> := TScalarBatchUnpacker.Create(def);
|
||||
var unpacker := TScalarBatchLoader.CreateTicker(def);
|
||||
|
||||
var ticker :=
|
||||
unpacker.Producer.Chain<TDataPoint<Double>>(
|
||||
|
||||
+2
-111
@@ -7,8 +7,7 @@ interface
|
||||
uses
|
||||
Myc.Signals,
|
||||
Myc.Mutable,
|
||||
Myc.Data.Series,
|
||||
Myc.Data.Records;
|
||||
Myc.Data.Series;
|
||||
|
||||
type
|
||||
TTag = Pointer;
|
||||
@@ -105,12 +104,7 @@ type
|
||||
class property Null: IConverter<S, T> read GetNull;
|
||||
end;
|
||||
|
||||
TDataRecordLayoutHelper = record helper for TDataRecord.TLayout
|
||||
function FieldAsRecord<T>(const Name: String): TConverter<T, TDataRecord>;
|
||||
function FieldOfRecord<T>(const Name: String): TConverter<TDataRecord, T>;
|
||||
end;
|
||||
|
||||
// Factory for creating specific converter instances.
|
||||
// Tools for creating specific converter instances.
|
||||
TConverter = record
|
||||
class function CreateCounter<T>: TConverter<T, Int64>; static;
|
||||
class function CreateTicker<T>: TConverter<TArray<T>, T>; static;
|
||||
@@ -122,32 +116,6 @@ type
|
||||
TJoinMode = (jmAll, jmAny);
|
||||
|
||||
class function Join<T>(Mode: TJoinMode; const Producers: TArray<TProducer<T>>): TProducer<TArray<T>>; static;
|
||||
|
||||
type
|
||||
TRecordMapping = record
|
||||
Layout: TDataRecord.TLayout;
|
||||
Fields: array of record
|
||||
FromField, ToField: String
|
||||
end;
|
||||
end;
|
||||
|
||||
class function DataMapping(
|
||||
const Inputs: TArray<TRecordMapping>;
|
||||
const Output: TDataRecord.TLayout
|
||||
): TConverter<TArray<TDataRecord>, TDataRecord>; static;
|
||||
|
||||
class function JoinRecords(
|
||||
const TargetLayout: TDataRecord.TLayout;
|
||||
const Mapping: TArray<TRecordMapping>;
|
||||
const Producers: TArray<TProducer<TDataRecord>>
|
||||
): TConverter<TArray<TDataRecord>, TDataRecord>; static;
|
||||
end;
|
||||
|
||||
TDataRecordHelper = record helper for TArray<TProducer<TDataRecord>>
|
||||
function JoinRecords(
|
||||
const TargetLayout: TDataRecord.TLayout;
|
||||
const Mapping: TArray<TConverter.TRecordMapping>
|
||||
): TProducer<TDataRecord>; experimental;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@@ -315,38 +283,6 @@ begin
|
||||
Result := TMycTicker<T>.Create;
|
||||
end;
|
||||
|
||||
class function TConverter.DataMapping(
|
||||
const Inputs: TArray<TRecordMapping>;
|
||||
const Output: TDataRecord.TLayout
|
||||
): TConverter<TArray<TDataRecord>, TDataRecord>;
|
||||
var
|
||||
Idxs: array of array of record
|
||||
FromIdx, ToIdx: Integer
|
||||
end;
|
||||
begin
|
||||
SetLength(Idxs, Length(Inputs));
|
||||
for var i := 0 to High(Idxs) do
|
||||
begin
|
||||
SetLength(Idxs[i], Length(Inputs[i].Fields));
|
||||
for var j := 0 to High(Idxs[i]) do
|
||||
begin
|
||||
Idxs[i][j].FromIdx := Inputs[i].Layout.IndexOf(Inputs[i].Fields[j].FromField);
|
||||
Idxs[i][j].ToIdx := Output.IndexOf(Inputs[i].Fields[j].ToField);
|
||||
end;
|
||||
end;
|
||||
|
||||
Result :=
|
||||
TConverter<TArray<TDataRecord>, TDataRecord>.CreateConverter(
|
||||
function(const Inputs: TArray<TDataRecord>): TDataRecord
|
||||
begin
|
||||
Result := TDataRecord.Create(Output);
|
||||
for var i := 0 to High(Idxs) do
|
||||
for var j := 0 to High(Idxs[i]) do
|
||||
Result.CopyValue(Inputs[i], Idxs[i][j].FromIdx, Idxs[i][j].ToIdx);
|
||||
end
|
||||
);
|
||||
end;
|
||||
|
||||
class function TConverter.Join<T>(Mode: TJoinMode; const Producers: TArray<TProducer<T>>): TProducer<TArray<T>>;
|
||||
var
|
||||
joiner: IDataJoin<T>;
|
||||
@@ -363,49 +299,4 @@ begin
|
||||
Producers[i].Chain(joiner.Consumers[i]);
|
||||
end;
|
||||
|
||||
class function TConverter.JoinRecords(
|
||||
const TargetLayout: TDataRecord.TLayout;
|
||||
const Mapping: TArray<TRecordMapping>;
|
||||
const Producers: TArray<TProducer<TDataRecord>>
|
||||
): TConverter<TArray<TDataRecord>, TDataRecord>;
|
||||
begin
|
||||
var RecProvider := Join<TDataRecord>(jmAll, Producers);
|
||||
|
||||
Result := DataMapping(Mapping, TargetLayout);
|
||||
|
||||
RecProvider.Chain(Result.Consumer);
|
||||
end;
|
||||
|
||||
function TDataRecordLayoutHelper.FieldAsRecord<T>(const Name: String): TConverter<T, TDataRecord>;
|
||||
begin
|
||||
var layout := Self;
|
||||
var idx := IndexOf(Name);
|
||||
Result :=
|
||||
TConverter<T, TDataRecord>.CreateConverter(
|
||||
function(const Value: T): TDataRecord
|
||||
begin
|
||||
Result := TDataRecord.Create(layout);
|
||||
Result.SetValue(idx, Value);
|
||||
end
|
||||
);
|
||||
end;
|
||||
|
||||
function TDataRecordLayoutHelper.FieldOfRecord<T>(const Name: String): TConverter<TDataRecord, T>;
|
||||
begin
|
||||
var idx := IndexOf(Name);
|
||||
Result := TConverter<TDataRecord, T>.CreateConverter(function(const Value: TDataRecord): T begin Value.GetValue(idx, Result); end);
|
||||
end;
|
||||
|
||||
function TDataRecordHelper.JoinRecords(
|
||||
const TargetLayout: TDataRecord.TLayout;
|
||||
const Mapping: TArray<TConverter.TRecordMapping>
|
||||
): TProducer<TDataRecord>;
|
||||
begin
|
||||
var map := TConverter.DataMapping(Mapping, TargetLayout);
|
||||
|
||||
TConverter.Join<TDataRecord>(jmAll, Self).Chain(map.Consumer);
|
||||
|
||||
Result := map.Producer;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
+113
-1
@@ -4,7 +4,8 @@ interface
|
||||
|
||||
uses
|
||||
System.SysUtils,
|
||||
System.TypInfo;
|
||||
System.TypInfo,
|
||||
Myc.Data.Pipeline;
|
||||
|
||||
type
|
||||
TDataRecord = record
|
||||
@@ -110,6 +111,40 @@ type
|
||||
property Layout: TLayout read FLayout;
|
||||
end;
|
||||
|
||||
TDataRecordLayoutHelper = record helper for TDataRecord.TLayout
|
||||
function FieldAsRecord<T>(const Name: String): TConverter<T, TDataRecord>;
|
||||
function FieldOfRecord<T>(const Name: String): TConverter<TDataRecord, T>;
|
||||
end;
|
||||
|
||||
type
|
||||
TRecordMapping = record
|
||||
Layout: TDataRecord.TLayout;
|
||||
Fields: array of record
|
||||
FromField, ToField: String
|
||||
end;
|
||||
end;
|
||||
|
||||
// Factory for creating specific converter instances.
|
||||
TRecordConverter = record
|
||||
class function DataMapping(
|
||||
const Inputs: TArray<TRecordMapping>;
|
||||
const Output: TDataRecord.TLayout
|
||||
): TConverter<TArray<TDataRecord>, TDataRecord>; static;
|
||||
|
||||
class function JoinRecords(
|
||||
const TargetLayout: TDataRecord.TLayout;
|
||||
const Mapping: TArray<TRecordMapping>;
|
||||
const Producers: TArray<TProducer<TDataRecord>>
|
||||
): TConverter<TArray<TDataRecord>, TDataRecord>; static;
|
||||
end;
|
||||
|
||||
TDataRecordHelper = record helper for TArray<TProducer<TDataRecord>>
|
||||
function JoinRecords(
|
||||
const TargetLayout: TDataRecord.TLayout;
|
||||
const Mapping: TArray<TRecordMapping>
|
||||
): TProducer<TDataRecord>; experimental;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@@ -569,4 +604,81 @@ begin
|
||||
Result := not (A = B);
|
||||
end;
|
||||
|
||||
function TDataRecordLayoutHelper.FieldAsRecord<T>(const Name: String): TConverter<T, TDataRecord>;
|
||||
begin
|
||||
var layout := Self;
|
||||
var idx := IndexOf(Name);
|
||||
Result :=
|
||||
TConverter<T, TDataRecord>.CreateConverter(
|
||||
function(const Value: T): TDataRecord
|
||||
begin
|
||||
Result := TDataRecord.Create(layout);
|
||||
Result.SetValue(idx, Value);
|
||||
end
|
||||
);
|
||||
end;
|
||||
|
||||
function TDataRecordLayoutHelper.FieldOfRecord<T>(const Name: String): TConverter<TDataRecord, T>;
|
||||
begin
|
||||
var idx := IndexOf(Name);
|
||||
Result := TConverter<TDataRecord, T>.CreateConverter(function(const Value: TDataRecord): T begin Value.GetValue(idx, Result); end);
|
||||
end;
|
||||
|
||||
class function TRecordConverter.DataMapping(
|
||||
const Inputs: TArray<TRecordMapping>;
|
||||
const Output: TDataRecord.TLayout
|
||||
): TConverter<TArray<TDataRecord>, TDataRecord>;
|
||||
var
|
||||
Idxs: array of array of record
|
||||
FromIdx, ToIdx: Integer
|
||||
end;
|
||||
begin
|
||||
SetLength(Idxs, Length(Inputs));
|
||||
for var i := 0 to High(Idxs) do
|
||||
begin
|
||||
SetLength(Idxs[i], Length(Inputs[i].Fields));
|
||||
for var j := 0 to High(Idxs[i]) do
|
||||
begin
|
||||
Idxs[i][j].FromIdx := Inputs[i].Layout.IndexOf(Inputs[i].Fields[j].FromField);
|
||||
Idxs[i][j].ToIdx := Output.IndexOf(Inputs[i].Fields[j].ToField);
|
||||
end;
|
||||
end;
|
||||
|
||||
Result :=
|
||||
TConverter<TArray<TDataRecord>, TDataRecord>.CreateConverter(
|
||||
function(const Inputs: TArray<TDataRecord>): TDataRecord
|
||||
begin
|
||||
Result := TDataRecord.Create(Output);
|
||||
for var i := 0 to High(Idxs) do
|
||||
for var j := 0 to High(Idxs[i]) do
|
||||
Result.CopyValue(Inputs[i], Idxs[i][j].FromIdx, Idxs[i][j].ToIdx);
|
||||
end
|
||||
);
|
||||
end;
|
||||
|
||||
class function TRecordConverter.JoinRecords(
|
||||
const TargetLayout: TDataRecord.TLayout;
|
||||
const Mapping: TArray<TRecordMapping>;
|
||||
const Producers: TArray<TProducer<TDataRecord>>
|
||||
): TConverter<TArray<TDataRecord>, TDataRecord>;
|
||||
begin
|
||||
var RecProvider := TConverter.Join<TDataRecord>(jmAll, Producers);
|
||||
|
||||
Result := TRecordConverter.DataMapping(Mapping, TargetLayout);
|
||||
|
||||
RecProvider.Chain(Result.Consumer);
|
||||
end;
|
||||
|
||||
function TDataRecordHelper.JoinRecords(
|
||||
const TargetLayout: TDataRecord.TLayout;
|
||||
const Mapping: TArray<TRecordMapping>
|
||||
): TProducer<TDataRecord>;
|
||||
begin
|
||||
var map := TRecordConverter.DataMapping(Mapping, TargetLayout);
|
||||
|
||||
TConverter.Join<TDataRecord>(jmAll, Self).Chain(map.Consumer);
|
||||
|
||||
Result := map.Producer;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
@@ -135,7 +135,7 @@ type
|
||||
// Streaming processing: Reads data from disk and broadcasts it via BatchTicker
|
||||
function ProcessData(const Symbol: String; const Terminated: TState): TState;
|
||||
|
||||
function CreateTicker(const Def: IScalarRecordDefinition): TConverter<TScalarBatch, IScalarRecord>;
|
||||
class function CreateTicker(const Def: IScalarRecordDefinition): TConverter<TScalarBatch, IScalarRecord>; static;
|
||||
|
||||
property Path: String read GetPath;
|
||||
property FileExtension: String read FFileExtension;
|
||||
@@ -279,7 +279,7 @@ begin
|
||||
UpdateSymbols;
|
||||
end;
|
||||
|
||||
function TScalarBatchLoader.CreateTicker(const Def: IScalarRecordDefinition): TConverter<TScalarBatch, IScalarRecord>;
|
||||
class function TScalarBatchLoader.CreateTicker(const Def: IScalarRecordDefinition): TConverter<TScalarBatch, IScalarRecord>;
|
||||
var
|
||||
viewObj: TScalarRecordView;
|
||||
view: IScalarRecord;
|
||||
|
||||
Reference in New Issue
Block a user