Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ private OperationPlan(
Operation operation,
ImmutableArray<ExecutionNode> rootNodes,
ImmutableArray<ExecutionNode> allNodes,
uint searchSpace,
int searchSpace,
int expandedNodes)
{
Id = id;
Expand Down Expand Up @@ -67,7 +67,7 @@ public IReadOnlyList<VariableDefinitionNode> VariableDefinitions
/// <summary>
/// Gets a number specifying how many possible plans were considered during planning.
/// </summary>
public uint SearchSpace { get; }
public int SearchSpace { get; }

/// <summary>
/// Gets the number of nodes expanded (dequeued) during the A* search.
Expand Down Expand Up @@ -101,8 +101,8 @@ public static OperationPlan Create(
Operation operation,
ImmutableArray<ExecutionNode> rootNodes,
ImmutableArray<ExecutionNode> allNodes,
uint searchSpace,
int expandedNodes = 0)
int searchSpace,
int expandedNodes)
{
ArgumentException.ThrowIfNullOrEmpty(id);
ArgumentNullException.ThrowIfNull(operation);
Expand All @@ -128,8 +128,8 @@ public static OperationPlan Create(
Operation operation,
ImmutableArray<ExecutionNode> rootNodes,
ImmutableArray<ExecutionNode> allNodes,
uint searchSpace,
int expandedNodes = 0)
int searchSpace,
int expandedNodes)
{
ArgumentNullException.ThrowIfNull(operation);
ArgumentOutOfRangeException.ThrowIfLessThan(rootNodes.Length, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ public override OperationPlan Parse(ReadOnlyMemory<byte> planSourceText)
{
using var document = JsonDocument.Parse(planSourceText);
var rootElement = document.RootElement;
uint searchSpace = 0;
int expandedNodes = 0;
var searchSpace = 0;
var expandedNodes = 0;

var id = rootElement.GetProperty("id").GetString()!;
var operation = ParseOperation(rootElement.GetProperty("operation"));

if (rootElement.TryGetProperty("searchSpace", out var searchSpaceElement))
{
searchSpace = searchSpaceElement.GetUInt32();
searchSpace = searchSpaceElement.GetInt32();
}

if (rootElement.TryGetProperty("expandedNodes", out var expandedNodesElement))
Expand Down
110 changes: 110 additions & 0 deletions src/HotChocolate/Fusion-vnext/src/Fusion.Execution/Planning/Backlog.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using System.Collections.Immutable;

namespace HotChocolate.Fusion.Planning;

/// <summary>
/// An immutable backlog of work items paired with cost tracking.
/// Every push and pop keeps the cost in sync with the stack,
/// so branch scoring stays O(1) per transition.
/// </summary>
internal readonly struct Backlog(ImmutableStack<WorkItem> items, BacklogCost cost)
{
private readonly ImmutableStack<WorkItem> _items = items;

public static Backlog Empty { get; } = new([], BacklogCost.Empty);

/// <summary>
/// The cost tracking state for all items in this backlog.
/// </summary>
public BacklogCost Cost { get; } = cost;

/// <summary>
/// Whether this backlog has no work items left.
/// </summary>
public bool IsEmpty => _items.IsEmpty;

/// <summary>
/// Returns the next work item without removing it.
/// </summary>
public WorkItem Peek() => _items.Peek();

/// <summary>
/// Pushes a work item and updates cost tracking.
/// </summary>
public Backlog Push(WorkItem workItem)
{
var cost = PlannerCostEstimator.AddWorkItemCost(Cost, workItem);
return new Backlog(_items.Push(workItem), cost);
}

/// <summary>
/// Pops the next work item and updates cost tracking.
/// </summary>
public Backlog Pop(out WorkItem workItem)
{
var items = _items.Pop(out workItem);
var cost = PlannerCostEstimator.RemoveWorkItemCost(Cost, workItem);
return new Backlog(items, cost);
}

/// <summary>
/// Pushes work items for unresolvable selection sets that need
/// their own operation steps on other schemas.
/// </summary>
public Backlog PushUnresolvable(
ImmutableStack<SelectionSet> unresolvable,
string fromSchema,
int parentDepth)
{
if (unresolvable.IsEmpty)
{
return this;
}

var backlog = this;

foreach (var selectionSet in unresolvable.Reverse())
{
var workItem = new OperationWorkItem(
selectionSet.Path.IsRoot
? OperationWorkItemKind.Root
: OperationWorkItemKind.Lookup,
selectionSet,
FromSchema: fromSchema)
{
ParentDepth = parentDepth
};
backlog = backlog.Push(workItem);
}

return backlog;
}

/// <summary>
/// Pushes work items for fields that have requirements
/// which may need lookup steps to satisfy.
/// </summary>
public Backlog PushRequirements(
ImmutableStack<FieldSelection> fieldsWithRequirements,
int stepId,
int parentDepth)
{
if (fieldsWithRequirements.IsEmpty)
{
return this;
}

var backlog = this;

foreach (var selection in fieldsWithRequirements.Reverse())
{
var workItem = new FieldRequirementWorkItem(selection, stepId)
{
ParentDepth = parentDepth
};
backlog = backlog.Push(workItem);
}

return backlog;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,25 @@
namespace HotChocolate.Fusion.Planning;

/// <summary>
/// Incremental backlog lower-bound state used to project remaining work shape.
/// Tracks the minimum guaranteed cost of all work items still in the backlog.
/// </summary>
/// <param name="OperationLowerBound">
/// Guaranteed remaining operation floor from all backlog items.
/// <param name="MinimumCost">
/// Sum of the cheapest possible cost for each backlog item.
/// </param>
/// <param name="MaxProjectedDepth">
/// Deepest projected operation depth across remaining guaranteed operations.
/// The deepest level at which backlog items are expected to produce operations.
/// </param>
/// <param name="ProjectedOpsPerLevel">
/// Projected guaranteed operation count per depth level.
/// How many operations each depth level is expected to add.
/// </param>
internal readonly record struct BacklogCostState(
double OperationLowerBound,
internal readonly record struct BacklogCost(
double MinimumCost,
int MaxProjectedDepth,
ImmutableDictionary<int, int> ProjectedOpsPerLevel)
{
/// <summary>
/// Gets an empty backlog cost state with no projected operations.
/// </summary>
public static BacklogCostState Empty { get; } =
public static BacklogCost Empty { get; } =
new(0.0, 0, ImmutableDictionary<int, int>.Empty);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ public interface ISelectionSetIndex
/// <returns></returns>
uint GetId(SelectionSetNode selectionSet);

bool TryGetId(SelectionSetNode selectionSet, out uint id);

bool TryGetOriginalIdFromCloned(uint clonedId, out uint originalId);

bool IsRegistered(SelectionSetNode selectionSet);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ internal sealed class OperationDefinitionBuilder
{
private OperationType _type = OperationType.Query;
private string? _name;
private string? _description;
private Lookup? _lookup;
private List<ArgumentNode>? _lookupArguments;
private ITypeDefinition? _typeToLookup;
Expand All @@ -38,12 +37,6 @@ public OperationDefinitionBuilder SetName(string? name)
return this;
}

public OperationDefinitionBuilder SetDescription(string? description)
{
_description = description;
return this;
}

public OperationDefinitionBuilder SetLookup(
Lookup lookup,
List<ArgumentNode> arguments,
Expand Down Expand Up @@ -139,7 +132,7 @@ public OperationDefinitionBuilder SetSelectionSet(SelectionSetNode selectionSet)
var definition = new OperationDefinitionNode(
null,
string.IsNullOrEmpty(_name) ? null : new NameNode(_name),
string.IsNullOrEmpty(_description) ? null : new StringValueNode(_description),
null,
_type,
[],
[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ private OperationPlan BuildExecutionPlan(
Operation operation,
OperationDefinitionNode operationDefinition,
ImmutableList<PlanStep> planSteps,
uint searchSpace,
int searchSpace,
int expandedNodes)
{
if (operation.IsIntrospectionOnly())
Expand Down

This file was deleted.

Loading
Loading