Class InputConflictSet
A snapshot of every non-composite binding in a project, in the order the conflict rules must see them.
Inherited Members
Namespace: Scylla.Input
Assembly: ScyllaInput.dll
Syntax
public sealed class InputConflictSet
Remarks
Order is a contract, not an implementation detail. Records appear in action map declaration order, then action order within a map, then binding order within an action. Conflict results are deduplicated first-hit-wins, so the order decides which map is named as the rival. Change the order and user-visible text changes with it.
A set is only valid for the caller that built it, because IsInRegisteredSchemes is baked in from that caller's declared columns. Never cache one on a shared service and never hand one between managers.
Access is through Records or the ref readonly indexer. The
element is a large struct and there is deliberately no IEnumerable surface.
Properties
Count
Gets how many records the set holds.
Declaration
public int Count { get; }
Property Value
| Type | Description |
|---|---|
| int |
DistinctPathCount
Gets how many distinct non-empty normalized paths the set holds. Builds the index.
Declaration
public int DistinctPathCount { get; }
Property Value
| Type | Description |
|---|---|
| int |
this[int]
Gets a record by position, without copying it.
Declaration
public ref readonly InputConflictRecord this[int index] { get; }
Parameters
| Type | Name | Description |
|---|---|---|
| int | index | Zero-based position in scan order. |
Property Value
| Type | Description |
|---|---|
| InputConflictRecord | A read-only reference to the record. |
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown when the index is out of range. |
Records
Gets the records, in scan order.
Declaration
public ReadOnlySpan<InputConflictRecord> Records { get; }
Property Value
| Type | Description |
|---|---|
| ReadOnlySpan<InputConflictRecord> |
Methods
Create(InputConflictRecord[], int)
Wraps a populated array as a set.
Declaration
public static InputConflictSet Create(InputConflictRecord[] records, int count)
Parameters
| Type | Name | Description |
|---|---|---|
| InputConflictRecord[] | records | Backing array, already in scan order. |
| int | count | How many leading entries are populated. |
Returns
| Type | Description |
|---|---|
| InputConflictSet | The set. |
Remarks
The array is taken by reference rather than copied, so the caller must not write to it afterwards. The builder relies on this to reuse one scratch array across rebuilds without allocating.
Exceptions
| Type | Condition |
|---|---|
| ArgumentNullException | Thrown when the array is |
| ArgumentOutOfRangeException | Thrown when the count does not fit the array. |
Empty()
Gets a shared empty set.
Declaration
public static InputConflictSet Empty()
Returns
| Type | Description |
|---|---|
| InputConflictSet | A set with no records. |
GetBucketAt(int)
Returns one bucket by ordinal, so a caller can walk every group of records that share a path without knowing the paths.
Declaration
public ReadOnlySpan<int> GetBucketAt(int ordinal)
Parameters
| Type | Name | Description |
|---|---|---|
| int | ordinal | Bucket ordinal, below DistinctPathCount. |
Returns
| Type | Description |
|---|---|
| ReadOnlySpan<int> | Ascending record positions. |
Remarks
Ordinals run from zero to DistinctPathCount and are assigned in first appearance order, which makes a whole-set sweep visit groups in the order their first member appears. That is what keeps such a sweep's output stable across runs.
Exceptions
| Type | Condition |
|---|---|
| ArgumentOutOfRangeException | Thrown when the ordinal is out of range. |
GetPathBucket(string)
Returns the positions of every record sharing a normalized path, in ascending order.
Declaration
public ReadOnlySpan<int> GetPathBucket(string normalizedPath)
Parameters
| Type | Name | Description |
|---|---|---|
| string | normalizedPath | The path to look up. |
Returns
| Type | Description |
|---|---|
| ReadOnlySpan<int> | Ascending record positions, or an empty span. |
Remarks
A conflict requires the two paths to be equal, and every rule the engine tests before that one can only reject. So no record outside the bucket can produce a result, and scanning the bucket instead of the whole set is a pure filter.
The index is keyed case-insensitively while one policy compares paths ordinally. That asymmetry is deliberate and must not be tightened: a case-insensitive bucket is a superset of the ordinal one, so the looser key can only hand the engine extra candidates, which it then rejects on the path test as it would have anyway. Keying ordinally instead would silently drop case-variant candidates for any policy that compares case-insensitively, and silently dropping a real conflict is the failure mode this whole subsystem exists to avoid. The bucket filters candidates; it never decides.
Records with an empty normalized path are not indexed, because the engine rejects them outright. A path absent from the set returns an empty span.