Refactoring DataFlow, 1st Generic Data records working
This commit is contained in:
+27
-196
@@ -11,238 +11,69 @@ uses
|
||||
Myc.DataRecord;
|
||||
|
||||
type
|
||||
// The builder implementation class, now in the global scope.
|
||||
TDataRecordBuilder = class(TInterfacedObject, TDataRecord.TBuilder.IBuilder)
|
||||
private
|
||||
FStagedValues: TList<TPair<string, TValue>>;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
// IBuilder implementation
|
||||
procedure AddField(const Name: String; const Value: TValue); overload;
|
||||
procedure SetupRecord(out Layout: TArray<TDataRecord.TFieldLayout>; out Buffer: TBytes);
|
||||
end;
|
||||
|
||||
type
|
||||
TField = class(TInterfacedObject, TDataRecord.IField)
|
||||
private
|
||||
FBuffer: TBytes;
|
||||
FFieldLayout: TDataRecord.TFieldLayout;
|
||||
protected
|
||||
function GetRawRef: Pointer; inline;
|
||||
public
|
||||
constructor Create(ABuffer: TBytes; const AField: TDataRecord.TFieldLayout);
|
||||
procedure GetRaw(Dst: Pointer); virtual;
|
||||
procedure SetRaw(Src: Pointer); virtual;
|
||||
property FieldLayout: TDataRecord.TFieldLayout read FFieldLayout;
|
||||
end;
|
||||
|
||||
type
|
||||
TGenericField<T> = class(TField, TDataRecord.IField<T>)
|
||||
public
|
||||
function GetValue: T;
|
||||
procedure SetValue(const Value: T);
|
||||
end;
|
||||
|
||||
type
|
||||
TIntegerField = class(TGenericField<Integer>)
|
||||
public
|
||||
procedure GetRaw(Dst: Pointer); override;
|
||||
procedure SetRaw(Src: Pointer); override;
|
||||
end;
|
||||
|
||||
type
|
||||
TSingleField = class(TGenericField<Single>)
|
||||
public
|
||||
procedure GetRaw(Dst: Pointer); override;
|
||||
procedure SetRaw(Src: Pointer); override;
|
||||
end;
|
||||
|
||||
type
|
||||
TDoubleField = class(TGenericField<Double>)
|
||||
public
|
||||
procedure GetRaw(Dst: Pointer); override;
|
||||
procedure SetRaw(Src: Pointer); override;
|
||||
end;
|
||||
|
||||
type
|
||||
TInt64Field = class(TGenericField<Int64>)
|
||||
public
|
||||
procedure GetRaw(Dst: Pointer); override;
|
||||
procedure SetRaw(Src: Pointer); override;
|
||||
end;
|
||||
|
||||
type
|
||||
TStringField = class(TGenericField<String>)
|
||||
public
|
||||
procedure GetRaw(Dst: Pointer); override;
|
||||
procedure SetRaw(Src: Pointer); override;
|
||||
end;
|
||||
|
||||
type
|
||||
TFieldLayoutComparer = class(TComparer<TDataRecord.TFieldLayout>)
|
||||
TFieldLayoutComparer = class(TComparer<TDataRecord.TField>)
|
||||
strict private
|
||||
class var
|
||||
FDefaultComparer: IComparer<TDataRecord.TFieldLayout>;
|
||||
FDefaultComparer: IComparer<TDataRecord.TField>;
|
||||
class constructor CreateClass;
|
||||
public
|
||||
function Compare(const Left, Right: TDataRecord.TFieldLayout): Integer; override;
|
||||
class property DefaultComparer: IComparer<TDataRecord.TFieldLayout> read FDefaultComparer;
|
||||
function Compare(const Left, Right: TDataRecord.TField): Integer; override;
|
||||
class property DefaultComparer: IComparer<TDataRecord.TField> read FDefaultComparer;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TDataRecordBuilder }
|
||||
|
||||
constructor TDataRecordBuilder.Create;
|
||||
(*
|
||||
procedure TIntegerField.GetRaw(const [ref] Buffer: TBytes; Dst: Pointer);
|
||||
begin
|
||||
inherited;
|
||||
FStagedValues := TList<TPair<string, TValue>>.Create;
|
||||
PInteger(Dst)^ := PInteger(GetRawRef(Buffer))^;
|
||||
end;
|
||||
|
||||
destructor TDataRecordBuilder.Destroy;
|
||||
procedure TIntegerField.SetRaw(const [ref] Buffer: TBytes; Src: Pointer);
|
||||
begin
|
||||
FStagedValues.Free;
|
||||
inherited;
|
||||
PInteger(GetRawRef(Buffer))^ := PInteger(Src)^;
|
||||
end;
|
||||
|
||||
procedure TDataRecordBuilder.AddField(const Name: String; const Value: TValue);
|
||||
procedure TSingleField.GetRaw(const [ref] Buffer: TBytes; Dst: Pointer);
|
||||
begin
|
||||
FStagedValues.Add(TPair<string, TValue>.Create(Name, Value));
|
||||
PSingle(Dst)^ := PSingle(GetRawRef(Buffer))^;
|
||||
end;
|
||||
|
||||
procedure TDataRecordBuilder.SetupRecord(out Layout: TArray<TDataRecord.TFieldLayout>; out Buffer: TBytes);
|
||||
var
|
||||
layoutList: TList<TDataRecord.TFieldLayout>;
|
||||
pair: TPair<string, TValue>;
|
||||
field: TDataRecord.TFieldLayout;
|
||||
procedure TSingleField.SetRaw(const [ref] Buffer: TBytes; Src: Pointer);
|
||||
begin
|
||||
layoutList := TList<TDataRecord.TFieldLayout>.Create;
|
||||
try
|
||||
layoutList.Capacity := FStagedValues.Count;
|
||||
var ofs: NativeUInt := 0;
|
||||
for pair in FStagedValues do
|
||||
begin
|
||||
field.Name := pair.Key;
|
||||
field.Size := pair.Value.DataSize;
|
||||
ofs := (ofs + 15) and not 15;
|
||||
field.Offset := ofs;
|
||||
inc(ofs, field.Size);
|
||||
field.TypeInfo := pair.Value.TypeInfo;
|
||||
layoutList.Add(field);
|
||||
end;
|
||||
|
||||
SetLength(Buffer, ofs);
|
||||
|
||||
for var i := 0 to layoutList.Count - 1 do
|
||||
begin
|
||||
var P: PByte := @Buffer[layoutList[i].Offset];
|
||||
FStagedValues[i].Value.ExtractRawData(P);
|
||||
end;
|
||||
|
||||
layoutList.Sort(TFieldLayoutComparer.DefaultComparer);
|
||||
Layout := layoutList.ToArray;
|
||||
finally
|
||||
layoutList.Free;
|
||||
end;
|
||||
FStagedValues.Clear;
|
||||
PSingle(GetRawRef(Buffer))^ := PSingle(Src)^;
|
||||
end;
|
||||
|
||||
{ TField and descendants... }
|
||||
constructor TField.Create(ABuffer: TBytes; const AField: TDataRecord.TFieldLayout);
|
||||
procedure TDoubleField.GetRaw(const [ref] Buffer: TBytes; Dst: Pointer);
|
||||
begin
|
||||
inherited Create;
|
||||
FBuffer := ABuffer;
|
||||
FFieldLayout := AField;
|
||||
PDouble(Dst)^ := PDouble(GetRawRef(Buffer))^;
|
||||
end;
|
||||
|
||||
procedure TField.GetRaw(Dst: Pointer);
|
||||
var
|
||||
Val: TValue;
|
||||
procedure TDoubleField.SetRaw(const [ref] Buffer: TBytes; Src: Pointer);
|
||||
begin
|
||||
TValue.MakeWithoutCopy(GetRawRef, FFieldLayout.TypeInfo, val, true);
|
||||
val.ExtractRawData(Dst);
|
||||
PDouble(GetRawRef(Buffer))^ := PDouble(Src)^;
|
||||
end;
|
||||
|
||||
function TField.GetRawRef: Pointer;
|
||||
procedure TInt64Field.GetRaw(const [ref] Buffer: TBytes; Dst: Pointer);
|
||||
begin
|
||||
Result := @FBuffer[FFieldLayout.Offset];
|
||||
PInt64(Dst)^ := PInt64(GetRawRef(Buffer))^;
|
||||
end;
|
||||
|
||||
procedure TField.SetRaw(Src: Pointer);
|
||||
var
|
||||
Val: TValue;
|
||||
procedure TInt64Field.SetRaw(const [ref] Buffer: TBytes; Src: Pointer);
|
||||
begin
|
||||
TValue.MakeWithoutCopy(Src, FFieldLayout.TypeInfo, val, true);
|
||||
val.ExtractRawData(GetRawRef);
|
||||
PInt64(GetRawRef(Buffer))^ := PInt64(Src)^;
|
||||
end;
|
||||
|
||||
{ TGenericField<T> }
|
||||
|
||||
function TGenericField<T>.GetValue: T;
|
||||
type
|
||||
PT = ^T;
|
||||
procedure TStringField.GetRaw(const [ref] Buffer: TBytes; Dst: Pointer);
|
||||
begin
|
||||
Result := PT(@FBuffer[FFieldLayout.Offset])^;
|
||||
PString(Dst)^ := PString(GetRawRef(Buffer))^;
|
||||
end;
|
||||
|
||||
procedure TGenericField<T>.SetValue(const Value: T);
|
||||
type
|
||||
PT = ^T;
|
||||
procedure TStringField.SetRaw(const [ref] Buffer: TBytes; Src: Pointer);
|
||||
begin
|
||||
PT(@FBuffer[FFieldLayout.Offset])^ := Value;
|
||||
PString(GetRawRef(Buffer))^ := PString(Src)^;
|
||||
end;
|
||||
|
||||
procedure TIntegerField.GetRaw(Dst: Pointer);
|
||||
begin
|
||||
PInteger(Dst)^ := PInteger(GetRawRef)^;
|
||||
end;
|
||||
|
||||
procedure TIntegerField.SetRaw(Src: Pointer);
|
||||
begin
|
||||
PInteger(GetRawRef)^ := PInteger(Src)^;
|
||||
end;
|
||||
|
||||
procedure TSingleField.GetRaw(Dst: Pointer);
|
||||
begin
|
||||
PSingle(Dst)^ := PSingle(GetRawRef)^;
|
||||
end;
|
||||
|
||||
procedure TSingleField.SetRaw(Src: Pointer);
|
||||
begin
|
||||
PSingle(GetRawRef)^ := PSingle(Src)^;
|
||||
end;
|
||||
|
||||
procedure TDoubleField.GetRaw(Dst: Pointer);
|
||||
begin
|
||||
PDouble(Dst)^ := PDouble(GetRawRef)^;
|
||||
end;
|
||||
|
||||
procedure TDoubleField.SetRaw(Src: Pointer);
|
||||
begin
|
||||
PDouble(GetRawRef)^ := PDouble(Src)^;
|
||||
end;
|
||||
|
||||
procedure TInt64Field.GetRaw(Dst: Pointer);
|
||||
begin
|
||||
PInt64(Dst)^ := PInt64(GetRawRef)^;
|
||||
end;
|
||||
|
||||
procedure TInt64Field.SetRaw(Src: Pointer);
|
||||
begin
|
||||
PInt64(GetRawRef)^ := PInt64(Src)^;
|
||||
end;
|
||||
|
||||
procedure TStringField.GetRaw(Dst: Pointer);
|
||||
begin
|
||||
PString(Dst)^ := PString(GetRawRef)^;
|
||||
end;
|
||||
|
||||
procedure TStringField.SetRaw(Src: Pointer);
|
||||
begin
|
||||
PString(GetRawRef)^ := PString(Src)^;
|
||||
end;
|
||||
|
||||
*)
|
||||
{ TFieldLayoutComparer }
|
||||
|
||||
class constructor TFieldLayoutComparer.CreateClass;
|
||||
@@ -250,7 +81,7 @@ begin
|
||||
FDefaultComparer := TFieldLayoutComparer.Create;
|
||||
end;
|
||||
|
||||
function TFieldLayoutComparer.Compare(const Left, Right: TDataRecord.TFieldLayout): Integer;
|
||||
function TFieldLayoutComparer.Compare(const Left, Right: TDataRecord.TField): Integer;
|
||||
begin
|
||||
Result := TComparer<string>.Default.Compare(Left.Name, Right.Name);
|
||||
end;
|
||||
|
||||
Reference in New Issue
Block a user