You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Replaces the BTreeMap-based fragment storage with a new, specialized
"IntervalList" backed by a sorted Vec.
The previous implementation treated every received fragment as an
individual node in a B-Tree. This approach had several drawbacks for
high-throughput networking:
- With many fragments, there would be many short-lived allocations,
and while the allocator is fast, it's still costly.
- Tree traversal involved pointer chasing across non-contiguous memory,
causing CPU cache misses.
- Strictly in-order arrival (the 99% case) still required a tree search
and rebalancing operations (logarithmic time complexity).
The new IntervalList stores *ranges* of contiguous data (Intervals)
rather than individual points. When a fragment arrives, it is checked
against existing intervals and merged if contiguous.
For in-order delivery, the new fragment simply extends the last interval
in the vector. This is an O(1) operation with zero allocation.
Metadata is stored in a contiguous Vec, ensuring that checking for
gaps or overlaps utilizes CPU caches effectively.
A message split into 100 sequential fragments now consumes a single
Interval struct (approx. 24 bytes) rather than a large number of tree
nodes.
This structure unifies the storage logic for both SCTP standards by
abstracting the sort key (how the gaps are sorted in the vector):
- For traditional (RFC9260) streams, the (SSN, TSN) is the key.
Unordered messages have SSN=0, so for them, the TSN is the sorting
key. For ordered messages, every fragment is first grouped by SSN,
and then sorted by TSN. As a message is always sent in full before
sending another message, all fragments are contiguous in TSN number
space.
- For interleaved (RFC8260) streams, the (MID, FSN) is used as the key.
Note that while inserting into the middle of a vector is theoretically
costly, in this specific domain, the length of the vector represents the
number of *gaps* (packet loss events), not the total number of packets.
In real-world traffic, a stream rarely experiences more than a handful of
disjoint intervals at any given time. Therefore, the cost of shifting a
few vector elements is negligible compared to the overhead of maintaining
a tree structure.
0 commit comments