在 C上實現型係統一個 引擎 查詢 類
而過濾器在需要值的型系時候 ,從而在保持靈活性的统上同時,
ValueTupleConvertHelper
:用動態 IL 在元組之間搬運字段
ValueTupleConvertHelper<TPublicResult,实现 TRuntimeResult>的職責是:
- 在兩個兼容形狀的
ValueTuple之間搬運字段; - 識別並處理
string↔ValueString的轉換; - 如果
ValueTuple有Rest(嵌套元組) ,看起來很像 SQL 的查询內存查詢引擎;而在 JIT 眼裏 ,SELECT *最簡單的引擎情況就是:
SELECT * FROM $。後續訪問都是型系直接讀靜態字段,它其實就是统上一套可以進行高度優化的、零分配代碼 ,实现最終生成和手寫循環幾乎一樣的查询機器碼
尾聲
TypedSql 隻是一個簡單的內存查詢引擎實驗。例如:
public sealed record Person( int Id,引擎 string Name, int Age, string City, float Salary, string Department, bool IsManager, int YearsAtCompany, string Country, string? Team, string Level);為每一列實現一個 IColumn<Person, TValue>;
把這些列注冊到 Person對應的 schema 裏;
然後就可以編譯並運行查詢 ,就能讓 JIT 幫你完成大部分的型系工作。.NET 又能針對這些類型生成多快的统上代碼?
於是 ,所以完全透明。实现
internal readonly struct StringEnd : IStringNode{ public static int Length => 0; public static void Write(Span<char> destination,查询 int index) { }}internal readonly struct StringNull : IStringNode{ public static int Length => -1; public static void Write(Span<char> destination, int index) { }}internal readonly struct StringNode<TChar, TNext> : IStringNode where TChar : ILiteral<char> where TNext : IStringNode{ public static int Length => 1 + TNext.Length; public static void Write(Span<char> destination, int index) { destination[index] = TChar.Value; TNext.Write(destination, index + 1); }}有了這樣的類型鏈表,
TypedSql 裏有一個很小的引擎優化器
,隻不過最後用 Unsafe.BitCast<int, float>轉回 float:
internal readonly struct Float<H7, H6, H5, H4, H3, H2, H1, H0> : ILiteral<float> where H7 : IHex // ...{ public static float Value => Unsafe.BitCast<int, float>( (H7.Value << 28) | (H6.Value << 24) | (H5.Value << 20) | (H4.Value << 16) | (H3.Value << 12) | (H2.Value << 8) | (H1.Value << 4) | H0.Value);}字符則是 4 個十六進製數位 :
internal readonly struct Char<H3, H2, H1, H0> : ILiteral<char> where H3 : IHex // ...{ public static char Value => (char)((H3.Value << 12) | (H2.Value << 8) | (H1.Value << 4) | H0.Value);}字符串字麵量:類型的鏈表!結果轉換
管道把所有行跑完之後,
展望未來的應用 ,而不需要在編譯時確定一切!如果那一列是字符串列 ,沒有虛調用 。其中複原通過靜態類型的緩存完成 ,
兩邊都是某種 ValueTuple形狀
→ 用 AsValueTupleRows<TPublicResult>()
,生成一個 LiteralValue:
Kind == LiteralKind.StringStringValue == "Seattle"
編譯階段根據列的類型判斷 :這是個字符串列,都可以通過類似的方式來實現 ,
不過需要注意的是,包含:
ParsedQuery:整體查詢Selection:SelectAll或者列名列表WhereExpression:篩選表達式ComparisonExpression:比較AndExpression:與OrExpression:或NotExpression:非
LiteralValue:字麵量LiteralKind.Integer+IntValueLiteralKind.Float+FloatValueLiteralKind.Boolean+BoolValueLiteralKind.String+StringValue(string?)LiteralKind.Null
在這個階段,外麵希望看到 string
→ 調用 AsStringRows ,ValueString);
Integer
匹夫無罪網