Skip to content

Fix memory layout#9797

Merged
michaelstaib merged 23 commits into
mainfrom
mst/memory
Jun 17, 2026
Merged

Fix memory layout#9797
michaelstaib merged 23 commits into
mainfrom
mst/memory

Conversation

@michaelstaib

Copy link
Copy Markdown
Member

No description provided.

Copilot AI review requested due to automatic review settings May 29, 2026 12:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR reworks the internal memory layout of ResultDocument (Core) and CompositeResultDocument (Fusion). Cursors are repacked to include a 3-bit chunk-size bucket (12-bit chunk + 14-bit row + 3-bit size), parent/reference fields in DbRow are widened from 27/28 bits to 29 bits and now store packed cursor values rather than linear row indices, and Fusion's DbRow relocates the 4-bit token type to share the int that already holds sourceDocumentId. New ChunkSize enums and cursor unit tests are added for both Core and Fusion.

Changes:

  • Introduce ChunkSize enum and stamp chunk-size bits into packed cursor values; replace Cursor.Zero/FromIndex with CreateZero(ChunkSize) and new Cursor(value) and drive RowsPerChunk per-cursor.
  • Switch stored parent/reference fields to 29-bit packed cursor values across both DbRow types, relocating Fusion's token type to share storage with sourceDocumentId, and update all writers/readers and root checks to use cursor.Value / IsZero.
  • Add ResultDocumentCursorTests and CompositeResultDocumentCursorTests, and update CompositeResultDocumentMetaDbTests to the new Create(Cursor zero) API and renamed DbRow.Parent accessor.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/HotChocolate/Core/src/Types/Text/Json/ChunkSize.cs New chunk-size enum (1K–128K) sized for the cursor's 3 size bits.
src/HotChocolate/Core/src/Types/Text/Json/ResultDocument.Cursor.cs Repacks cursor as int with size/chunk/row, adds Value/Index/IsZero/ChunkSize/RowsPerChunk, removes Zero/FromIndex/ToIndex/ToTotalBytes.
src/HotChocolate/Core/src/Types/Text/Json/ResultDocument.DbRow.cs Splits _locationAndOpRefType into a dedicated 29-bit _location; moves opRefType into _opRefIdAndFlags; renames ParentRowParent (29 bits).
src/HotChocolate/Core/src/Types/Text/Json/ResultDocument.MetaDb.cs Threads ChunkSize through CreateForEstimatedRows/Append; renames parentRowparent; reads parents/locations as packed cursor values.
src/HotChocolate/Core/src/Types/Text/Json/ResultDocument.WriteTo.cs Root cursor obtained via CreateZero(_chunkSize).
src/HotChocolate/Core/src/Types/Text/Json/ResultDocument.cs Stores _chunkSize = Size128K; passes cursor Value as parent; drops the old IsRoot heuristic and ToIndex helper.
src/HotChocolate/Core/src/Types/Text/Json/ResultElement.cs Replaces _cursor == Cursor.Zero with _cursor.IsZero.
src/HotChocolate/Core/test/Types.Tests/Text/Json/ResultDocumentCursorTests.cs New cursor unit tests (chunk/row/size round-trip, AddRows, Index, IsZero, DbRow packing).
src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/ChunkSize.cs Fusion mirror of ChunkSize enum.
src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/CompositeResultDocument.Cursor.cs Fusion cursor mirror of the new packed layout.
src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/CompositeResultDocument.DbRow.cs Relocates token type into _sourceAndType alongside sourceDocumentId; renames ParentRowParent and widens to 29 bits.
src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/CompositeResultDocument.MetaDb.cs New Create(Cursor zero) factory; specialized append paths write packed parents and write the token type at the new offset; reads use 29-bit masks and rebuild cursors via new Cursor(value).
src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/CompositeResultDocument.WriteTo.cs Root and reference resolution use new cursor APIs.
src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/CompositeResultDocument.cs Stores _chunkSize, switches parent/path traversal to packed cursor values and IsZero, drops the IsRoot heuristic in WriteStartObject/Array.
src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/CompositeResultElement.cs Replaces Cursor.Zero comparisons with IsZero.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Text/Json/CompositeResultDocumentCursorTests.cs New Fusion cursor tests, including parent/reference round-trip and token+sourceDocumentId packing.
src/HotChocolate/Fusion/test/Fusion.Execution.Tests/Text/Json/CompositeResultDocumentMetaDbTests.cs Updates tests to MetaDb.Create(Cursor.CreateZero(...)), CreateCursor helper, TotalBytes, and renamed DbRow.Parent.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 439 to +449
var c0 = _metaDb.AppendNull(0);
var c1 = _metaDb.AppendNull(c0.Index);
var c2 = _metaDb.AppendNull(c1.Index);

// Assert
Assert.Equal(0, c0.Index);
Assert.Equal(1, c1.Index);
Assert.Equal(2, c2.Index);
Assert.Equal(0, _metaDb.Get(c0).ParentRow);
Assert.Equal(c0.Index, _metaDb.Get(c1).ParentRow);
Assert.Equal(c1.Index, _metaDb.Get(c2).ParentRow);
Assert.Equal(0, _metaDb.Get(c0).Parent);
Assert.Equal(c0.Index, _metaDb.Get(c1).Parent);
Assert.Equal(c1.Index, _metaDb.Get(c2).Parent);
Comment thread src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/CompositeResultDocument.cs Outdated
@github-code-quality

github-code-quality Bot commented Jun 16, 2026

Copy link
Copy Markdown

Code Coverage Overview

Languages: C#

C# / code-coverage/dotnet

The overall coverage in the branch remains at 49%, unchanged from the branch.

Show a code coverage summary of the most impacted files.
File eeb6a28 f08b428 +/-
/home/runner/wo...sultDocument.cs 83% 91% +8%
/home/runner/wo...SchemaClient.cs 34% 44% +10%
/home/runner/wo...ltEnumerable.cs 74% 87% +13%
/home/runner/wo...se/SseReader.cs 75% 90% +15%
/home/runner/wo...ument.Cursor.cs 49% 70% +21%
/home/runner/wo...ument.Cursor.cs 56% 81% +25%
/home/runner/wo...BufferWriter.cs 0% 73% +73%
/home/runner/wo.../MemoryArena.cs 0% 82% +82%
/home/runner/wo...entTablePool.cs 0% 88% +88%
/home/runner/wo...eTrackerPool.cs 0% 100% +100%

Updated June 17, 2026 13:03 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

Comment thread src/HotChocolate/AspNetCore/test/Transport.Http.Tests/GraphQLHttpClientTests.cs Dismissed
// arrange
// Keep-alive comment blocks appear before, between, and after the events and are ignored.
var ms = new MemoryStream();
var sw = new StreamWriter(ms);
// An event name that is neither "next" nor "complete" is not part of the GraphQL over SSE
// protocol and is ignored, even when it carries data.
var ms = new MemoryStream();
var sw = new StreamWriter(ms);
await using var fixture = await RoutingTestFixture.CreateAsync();
var context = fixture.CreateContext();
await using var client = new HttpSourceSchemaClient(
GraphQLHttpClient.Create(new HttpClient()),
{
// arrange
// The event payload is split across several data lines that are joined with a single line feed.
var ms = new MemoryStream();
// arrange
// The event payload is split across several data lines that are joined with a single line feed.
var ms = new MemoryStream();
var sw = new StreamWriter(ms);
ms.Position = 0;

var handler = new MockHttpMessageHandler(ms, "text/event-stream");
using var client = new DefaultGraphQLHttpClient(new HttpClient(handler));
// arrange
await using var fixture = await BatchBufferTestFixture.CreateAsync();
using var graphQLClient = new DefaultGraphQLHttpClient(
new HttpClient(new BatchHandler()),
Comment on lines +214 to +235
var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK)
{
Content = new StringContent(
"""
[
{
"data": {
"field": "a"
},
"requestIndex": 0
},
{
"data": {
"field": "b"
},
"requestIndex": 1
}
]
""",
Encoding.UTF8,
"application/json")
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants