Struct ConditionSet
- Namespace
- MassiveDotNet.WebSocket.Events
- Assembly
- MassiveDotNet.WebSocket.dll
Up to eight condition codes held inline, spilling to the heap beyond that.
public readonly struct ConditionSet : IEquatable<ConditionSet>
- Implements
- Inherited Members
Remarks
An int[] would allocate on every event carrying conditions, which is most trades. Renting
from ArrayPool is not available either: the array escapes to the caller with the event, so
nothing could ever return it. Eight covers every condition set observed, and the field holds no
reference in that case, so the common path allocates nothing.
A ninth code spills to a heap array rather than being dropped. Truncating would be silent data loss, which this SDK refuses everywhere else.
Equality is hand-written rather than left to the compiler-synthesized member-wise comparison a
struct normally gets: the InlineArrayAttribute field makes the runtime's default
ValueType.Equals/GetHashCode refuse to run at all
(NotSupportedException), and StockTrade and StockQuote
are record struct types (D4) whose own synthesized equality delegates straight
to this type's. Without IEquatable<T> here, both events would inherit that failure.
Fields
InlineCapacity
How many codes fit before spilling to the heap.
public const int InlineCapacity = 8
Field Value
Properties
Count
How many codes this set holds.
public int Count { get; }
Property Value
this[int]
The code at index.
public int this[int index] { get; }
Parameters
Property Value
Methods
AsSpan()
The codes, as a span over inline or spilled storage.
public ReadOnlySpan<int> AsSpan()
Returns
- ReadOnlySpan<int>
A span of exactly Count codes.
Remarks
The inline branch reads through AsRef<T>(scoped ref readonly T) over a readonly field, which is what makes this method possible on a readonly struct at all: an InlineArrayAttribute buffer normally cannot be indexed, let alone spanned, through a readonly binding, because the compiler cannot prove indexing does not mutate it. AsRef<T>(scoped ref readonly T) deliberately launders that ref-safety, which means the compiler can no longer catch a span that outlives the ConditionSet it was taken from.
The two branches do not fail the same way, and the difference matters more than it looks.
Inline (Count at most InlineCapacity): the returned span
points at bytes living inside this ConditionSet value itself. Once that exact
value is copied over, reassigned, or falls out of scope, the span is left pointing at
whatever now occupies that memory — it does not throw, it reads garbage.
trade.Conditions.AsSpan().ToArray() is safe, because the copy happens before the value
could go stale; holding the span itself across statements, such as
ReadOnlySpan<int> s = trade.Conditions.AsSpan(); followed by later use, is not.
Spilled (Count above InlineCapacity): the returned span is
backed by the independently heap-allocated int[], which the ReadOnlySpan<T>
itself keeps referenced — so, measured, it keeps reading correctly even after the source
ConditionSet is cleared or discarded. This is the more dangerous case, not the
safer one: it is an accident of how many codes a given message happened to carry, not a
documented guarantee, so code that holds the span because "it worked when I tried it with
nine conditions" breaks the moment a message arrives with three. Nothing at the call site
distinguishes which branch a given ConditionSet took, so treat both the same
way: a caller that needs the codes to outlive the ConditionSet they came from
must call ToArray() on the returned span, or use this[int], rather than
retain the span itself. This compiles clean either way, because the hazard is exactly the one
this method exists to route around.
Equals(ConditionSet)
Whether this set holds the same codes, in the same order, as other.
public bool Equals(ConditionSet other)
Parameters
otherConditionSetThe set to compare against.
Returns
Equals(object?)
Whether obj is a ConditionSet equal to this one.
public override bool Equals(object? obj)
Parameters
objobjectThe object to compare against.
Returns
- bool
true when
objis an equal ConditionSet.
GetHashCode()
A hash code consistent with Equals(ConditionSet): equal sets hash equal.
public override int GetHashCode()
Returns
- int
The hash code.
Operators
operator ==(ConditionSet, ConditionSet)
Whether left and right hold the same codes in the same order.
public static bool operator ==(ConditionSet left, ConditionSet right)
Parameters
leftConditionSetThe first set.
rightConditionSetThe second set.
Returns
operator !=(ConditionSet, ConditionSet)
Whether left and right differ.
public static bool operator !=(ConditionSet left, ConditionSet right)
Parameters
leftConditionSetThe first set.
rightConditionSetThe second set.