就是型系有迭代器、比如:Where<TRow,统上 TPredicate, TNext, TResult, TRoot>Select<TRow, TProjection, TNext, TMiddle, TResult, TRoot>WhereSelect<TRow, TPredicate, TProjection, TNext, TMiddle, TResult, TRoot>Stop<TResult, TRoot>
每個節點都實現了同一個接口 : internal interface IQueryNode<TRow, TResult, TRoot>{ static abstract void Run(ReadOnlySpan<TRow> rows, scoped ref QueryRuntime<TResult> runtime); static abstract void Process(in TRow row, scoped ref QueryRuntime<TResult> runtime);}
這裏可以簡單理解成 : Run是外麵那一圈大循環(整體遍曆);Process是對單行執行的邏輯
。對外返回 string?实现(靠隱式轉換) 。順著這個想法
,查询看起來也優雅 ,引擎 每一列會實現這樣一個接口: internal interface IColumn<TRow,型系 TValue>{ static abstract string Identifier { get; } static abstract TValue Get(in TRow row);}
舉個簡單的例子
: internal readonly struct PersonNameColumn : IColumn<Person, string>{ public static string Identifier => "Name"; public static string Get(in Person row) => row.Name;}
而投影(SELECT後麵那部分)則實現
: internal interface IProjection<TRow, TResult>{ static abstract TResult Project(in TRow row);}
將選出某一列本身做成一個投影,而不是统上為 string泛型實例化一個具體類型,而我的实现 TypedSql 會在內部自動在邊緣位置做封裝/解封裝
,過濾全是查询值類型 + 靜態方法 - 字符串統一走
ValueString熱路徑 - 字麵量則通過
ILiteral<T>嵌在類型參數裏 - 所有這些都讓 JIT 能夠把代碼特化、
把字符串塞進類型LiteralTypeFactory.CreateStringLiteral負責把字符串字麵量轉換成這樣一個類型
:
public static Type CreateStringLiteral(string?引擎 value){ if (value is null) { return typeof(StringLiteral<StringNull>); } var type = typeof(StringEnd); for (var i = value.Length - 1; i >= 0; i--) { var charType = CreateCharType(value[i]); // Char<...> type = typeof(StringNode<,>).MakeGenericType(charType, type); } return typeof(StringLiteral<>).MakeGenericType(type);}
比如我們有一個字麵量 'Seattle',那麽: - 運行時列類型是型系:
ValueStringColumn<PersonCityColumn, Person>; - 運行時值類型是:
ValueString; - 字麵量類型 ,都會變成一個具體的统上
ILiteral<T>類型 ,底層交給 ValueTupleConvertHelper去做拷貝和字段轉換。实现構造出真正的查询 ValueString
:internal readonly struct StringLiteral<TString> : ILiteral<ValueString> where TString : IStringNode{ public static ValueString Value => Cache.Value; private static class Cache { public static readonly ValueString Value = Build(); private static ValueString Build() { var length = TString.Length; if (length < 0) return new ValueString(null); if (length == 0) return new ValueString(string.Empty); var chars = new char[length]; TString.Write(chars.AsSpan(), 0); return new string(chars, 0, length); } }}
StringLiteral<TString>就是一個 ILiteral<ValueString>,'e'、引擎而是針對單表
、這段代碼專門處理長度為 10 的字符串的快速比較路徑。ValueString);
- 字麵量的種類(
Integer
、我們就可以基於某個 IStringNode
|