Skip to content

Commit 1822f4f

Browse files
committed
Improve metadb approve performance
1 parent 8ae8c59 commit 1822f4f

4 files changed

Lines changed: 574 additions & 128 deletions

File tree

src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/CompositeResultDocument.DbRow.cs

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,31 @@ internal readonly struct DbRow
1212
public const int Size = 20;
1313
public const int UnknownSize = -1;
1414

15-
// 27 bits for location + 2 bits OpRefType + 3 reserved bits
16-
private readonly int _locationAndOpRefType;
15+
// Byte offsets used by MetaDb's direct-read fast paths.
16+
internal const int TypeAndParentOffset = 0;
17+
internal const int SelectionAndFlagsOffset = 4;
18+
internal const int SizeOffset = 8;
19+
internal const int LocationOrRowsOffset = 12;
20+
internal const int SourceOffset = 16;
1721

18-
// A Sign bit for HasComplexChildren + 31 bits for size/length
19-
private readonly int _sizeOrLengthUnion;
22+
// 4 bits TokenType + 28 bits ParentRow
23+
private readonly int _typeAndParent;
24+
25+
// 15 bits OperationReferenceId + 2 bits OperationReferenceType + 6 bits Flags + 9 reserved
26+
private readonly int _selectionAndFlags;
2027

21-
// 4 bits TokenType + 27 bits NumberOfRows + 1 reserved bit
22-
private readonly int _numberOfRowsTypeAndReserved;
28+
// 1 bit HasComplexChildren (sign) + 31 bits SizeOrLength
29+
private readonly int _sizeOrLengthUnion;
2330

24-
// 15 bits SourceDocumentId + 17 bits (high 17 bits of ParentRow)
25-
private readonly int _sourceAndParentHigh;
31+
// 27 bits — either Location or NumberOfRows, depending on TokenType/Flags
32+
private readonly int _locationOrRows;
2633

27-
// 15 bits OperationReferenceId + 6 bits Flags + 11 bits (low bits of ParentRow)
28-
private readonly int _selectionSetFlagsAndParentLow;
34+
// 15 bits SourceDocumentId + 17 reserved
35+
private readonly int _source;
2936

3037
public DbRow(
3138
ElementTokenType tokenType,
32-
int location,
39+
int location = 0,
3340
int sizeOrLength = 0,
3441
int sourceDocumentId = 0,
3542
int parentRow = 0,
@@ -49,20 +56,24 @@ public DbRow(
4956
Debug.Assert((byte)operationReferenceType <= 3); // 2 bits
5057
Debug.Assert(Unsafe.SizeOf<DbRow>() == Size);
5158

52-
_locationAndOpRefType = location | ((int)operationReferenceType << 27);
59+
var locationOrRows = location != 0 ? location : numberOfRows;
60+
61+
_typeAndParent = ((int)tokenType & 0x0F) | (parentRow << 4);
62+
_selectionAndFlags = operationReferenceId
63+
| ((int)operationReferenceType << 15)
64+
| ((int)flags << 17);
5365
_sizeOrLengthUnion = sizeOrLength;
54-
_numberOfRowsTypeAndReserved = ((int)tokenType << 28) | (numberOfRows & 0x07FFFFFF);
55-
_sourceAndParentHigh = sourceDocumentId | ((parentRow >> 11) << 15);
56-
_selectionSetFlagsAndParentLow = operationReferenceId | ((int)flags << 15) | ((parentRow & 0x7FF) << 21);
66+
_locationOrRows = locationOrRows & 0x07FFFFFF;
67+
_source = sourceDocumentId & 0x7FFF;
5768
}
5869

5970
/// <summary>
6071
/// Element token type (includes Reference for composition).
6172
/// </summary>
6273
/// <remarks>
63-
/// 4 bits = possible values
74+
/// 4 bits = 16 possible values
6475
/// </remarks>
65-
public ElementTokenType TokenType => (ElementTokenType)(unchecked((uint)_numberOfRowsTypeAndReserved) >> 28);
76+
public ElementTokenType TokenType => (ElementTokenType)(_typeAndParent & 0x0F);
6677

6778
/// <summary>
6879
/// Operation reference type indicating the type of GraphQL operation element.
@@ -71,15 +82,15 @@ public DbRow(
7182
/// 2 bits = 4 possible values
7283
/// </remarks>
7384
public OperationReferenceType OperationReferenceType
74-
=> (OperationReferenceType)((_locationAndOpRefType >> 27) & 0x03);
85+
=> (OperationReferenceType)((_selectionAndFlags >> 15) & 0x03);
7586

7687
/// <summary>
77-
/// Byte offset in source data OR metaDb row index for references
88+
/// Byte offset in source data or metaDb row index for references.
7889
/// </summary>
7990
/// <remarks>
8091
/// 27 bits = 134M limit
8192
/// </remarks>
82-
public int Location => _locationAndOpRefType & 0x07FFFFFF;
93+
public int Location => _locationOrRows & 0x07FFFFFF;
8394

8495
/// <summary>
8596
/// Length of data in JSON payload, number of elements if array or number of properties in an object.
@@ -95,7 +106,7 @@ public OperationReferenceType OperationReferenceType
95106
public bool HasComplexChildren => _sizeOrLengthUnion < 0;
96107

97108
/// <summary>
98-
/// Specifies if a size for the item has ben set.
109+
/// Specifies if a size for the item has not been set.
99110
/// </summary>
100111
public bool IsUnknownSize => _sizeOrLengthUnion == UnknownSize;
101112

@@ -105,40 +116,39 @@ public OperationReferenceType OperationReferenceType
105116
/// <remarks>
106117
/// 27 bits = 134M rows
107118
/// </remarks>
108-
public int NumberOfRows => _numberOfRowsTypeAndReserved & 0x07FFFFFF;
119+
public int NumberOfRows => _locationOrRows & 0x07FFFFFF;
109120

110121
/// <summary>
111122
/// Which source JSON document contains the data.
112123
/// </summary>
113124
/// <remarks>
114125
/// 15 bits = 32K documents
115126
/// </remarks>
116-
public int SourceDocumentId => _sourceAndParentHigh & 0x7FFF;
127+
public int SourceDocumentId => _source & 0x7FFF;
117128

118129
/// <summary>
119130
/// Index of parent element in metadb for navigation and null propagation.
120131
/// </summary>
121132
/// <remarks>
122133
/// 28 bits = 268M rows
123134
/// </remarks>
124-
public int ParentRow
125-
=> ((int)((uint)_sourceAndParentHigh >> 15) << 11) | ((_selectionSetFlagsAndParentLow >> 21) & 0x7FF);
135+
public int ParentRow => (int)((uint)_typeAndParent >> 4);
126136

127137
/// <summary>
128138
/// Reference to GraphQL selection set or selection metadata.
129139
/// </summary>
130140
/// <remarks>
131141
/// 15 bits = 32K selections
132142
/// </remarks>
133-
public int OperationReferenceId => _selectionSetFlagsAndParentLow & 0x7FFF;
143+
public int OperationReferenceId => _selectionAndFlags & 0x7FFF;
134144

135145
/// <summary>
136146
/// Element metadata flags.
137147
/// </summary>
138148
/// <remarks>
139149
/// 6 bits = 64 combinations
140150
/// </remarks>
141-
public ElementFlags Flags => (ElementFlags)((_selectionSetFlagsAndParentLow >> 15) & 0x3F);
151+
public ElementFlags Flags => (ElementFlags)((_selectionAndFlags >> 17) & 0x3F);
142152

143153
/// <summary>
144154
/// True for primitive JSON values (strings, numbers, booleans, null).

0 commit comments

Comments
 (0)