@@ -29,38 +29,14 @@ public static byte[] SerializeRow(
2929
3030 for ( int i = 0 ; i < columns . Count ; i ++ )
3131 {
32- var slot = span . Slice ( layout . Offsets [ i ] , layout . SlotSizes [ i ] ) ;
3332 var value = row . TryGetValue ( columns [ i ] , out var v ) ? v : DBNull . Value ;
34-
35- if ( layout . IsVariable [ i ] )
36- {
37- if ( value == null || value == DBNull . Value )
38- {
39- slot [ 0 ] = 0 ;
40- BinaryPrimitives . WriteInt32LittleEndian ( slot [ 1 .. ] , 0 ) ;
41- }
42- else
43- {
44- var payload = Table . EncodeVariablePayload ( types [ i ] , value ) ;
45- var offset = arena . Write ( payload ) ;
46- slot [ 0 ] = 1 ;
47- BinaryPrimitives . WriteInt32LittleEndian ( slot [ 1 .. ] , ( int ) offset ) ;
48- }
49- }
50- else
51- {
52- _ = Table . WriteTypedValueToSpan ( slot , value , types [ i ] ) ;
53- }
33+ WriteSlot ( span . Slice ( layout . Offsets [ i ] , layout . SlotSizes [ i ] ) , layout . IsVariable [ i ] , types [ i ] , value , arena ) ;
5434 }
5535
5636 return buffer ;
5737 }
5838
59- /// <summary>
60- /// Serializes a column-ordered <c>object[]</c> row (values already aligned to the table's full
61- /// column order) into a fixed-width record. Dedicated overload for the SQL batch-INSERT fast
62- /// path so it never falls back to the variable-length encoding on a fixed-width table.
63- /// </summary>
39+ /// <summary>Serializes a column-ordered object[] row (full table column order) with the fixed-width codec.</summary>
6440 public static byte [ ] SerializeRow (
6541 object [ ] row ,
6642 IReadOnlyList < DataType > types ,
@@ -72,31 +48,35 @@ public static byte[] SerializeRow(
7248
7349 for ( int i = 0 ; i < row . Length && i < types . Count ; i ++ )
7450 {
75- var slot = span . Slice ( layout . Offsets [ i ] , layout . SlotSizes [ i ] ) ;
76- var value = row [ i ] ;
51+ WriteSlot ( span . Slice ( layout . Offsets [ i ] , layout . SlotSizes [ i ] ) , layout . IsVariable [ i ] , types [ i ] , row [ i ] , arena ) ;
52+ }
7753
78- if ( layout . IsVariable [ i ] )
79- {
80- if ( value == null || value == DBNull . Value )
81- {
82- slot [ 0 ] = 0 ;
83- BinaryPrimitives . WriteInt32LittleEndian ( slot [ 1 .. ] , 0 ) ;
84- }
85- else
86- {
87- var payload = Table . EncodeVariablePayload ( types [ i ] , value ) ;
88- var offset = arena . Write ( payload ) ;
89- slot [ 0 ] = 1 ;
90- BinaryPrimitives . WriteInt32LittleEndian ( slot [ 1 .. ] , ( int ) offset ) ;
91- }
92- }
93- else
54+ return buffer ;
55+ }
56+
57+ /// <summary>
58+ /// Writes one column value into its fixed-width slot: variable-length types store an out-of-line
59+ /// arena block reference, fixed-size types store their payload inline.
60+ /// </summary>
61+ private static void WriteSlot ( Span < byte > slot , bool isVariable , DataType type , object ? value , IOverflowArena arena )
62+ {
63+ if ( isVariable )
64+ {
65+ if ( value == null || value == DBNull . Value )
9466 {
95- _ = Table . WriteTypedValueToSpan ( slot , value , types [ i ] ) ;
67+ slot [ 0 ] = 0 ;
68+ BinaryPrimitives . WriteInt32LittleEndian ( slot [ 1 .. ] , 0 ) ;
69+ return ;
9670 }
71+
72+ var payload = Table . EncodeVariablePayload ( type , value ) ;
73+ var offset = arena . Write ( payload ) ;
74+ slot [ 0 ] = 1 ;
75+ BinaryPrimitives . WriteInt32LittleEndian ( slot [ 1 .. ] , ( int ) offset ) ;
76+ return ;
9777 }
9878
99- return buffer ;
79+ _ = Table . WriteTypedValueToSpan ( slot , value , type ) ;
10080 }
10181
10282 /// <summary>Deserializes a fixed-width record into a row dictionary (variable values ← arena).</summary>
0 commit comments