Core Foundations - Concepts
This page covers the vocabulary that spans the Core Foundations topic - the conventions shared by Bodu.Core's buffers and guards, the Bodu.Collections catalogue and its Bodu.Collections.Concurrent thread-safe companion, and the Bodu.Text character-encoding helpers that ship inside Bodu.Core. Read the topic overview first for the package map; come back here whenever a term feels imprecise.
The guard convention
Every Bodu library validates its public parameters through ThrowHelper rather than hand-rolled checks. The convention is validate-then-work: guards form a contiguous block at the top of a member, before any real logic runs, so a method either throws immediately with a precise ArgumentException-family error or proceeds knowing its inputs are sound.
public static double Average(IReadOnlyList<int> values)
{
ThrowHelper.ThrowIfNull(values);
ThrowHelper.ThrowIfZero(values.Count);
return values.Average();
}
Each helper accepts a [CallerArgumentExpression]-driven paramName, so the call site never repeats the argument name - the compiler captures the expression text (values, values.Count) and it surfaces as ParamName on the thrown exception. The helpers are partitioned by concern (null, numeric, comparison, array, collection, span, type, string), and [StackTraceHidden] keeps the helper frame out of stack traces. Centralizing the guards is what keeps exception messages and parameter-name capture identical across every Bodu package.
Bounded vs. growable
A fixed capacity is a contract, not a tuning knob. A bounded collection sizes its backing storage once; when Count reaches Capacity, it must either reject the next add or evict an existing element. Bodu's ring-backed types expose that choice as a single toggle:
- CircularBuffer<T> -
AllowOverwrite = truesilently evicts the oldest element (sliding-window semantics);falsethrows InvalidOperationException on overflow. - Deque<T> -
AllowGrow = truedoubles the backing array like aList<T>;falsefixes the capacity and throws on overflow. The toggle can be flipped at runtime.
The Try… variants (TryEnqueue, TryAddFirst, TryAddLast) substitute a false return for the throw, so hot paths can stay exception-free without changing the configured behavior. Choose overwrite when the newest data matters most (telemetry windows, recent-items lists); choose throw or Try… when dropping data silently would be a bug.
Eviction policies
EvictingDictionary<TKey, TValue> is the one collection that evicts a non-end element: when a new key overflows the capacity, the configured EvictingDictionaryPolicy selects the victim - FirstInFirstOut, LeastRecentlyUsed, LeastFrequentlyUsed, MostRecentlyUsed, RandomReplacement, or SecondChance. All six policies share the same IDictionary<TKey,TValue> surface and the same overflow trigger; only the selection differs. That makes the policy a deployment decision you can change without touching call sites - start with LRU, switch to Second-Chance if access-tracking overhead shows up in profiles.
Pooled buffers vs. allocation
A pooled buffer trades garbage-collector pressure for an explicit ownership protocol. PooledBufferBuilder<T> rents its array from ArrayPool<T> instead of new T[], grows by re-renting, and returns the array to the pool on Dispose. The rules that follow:
- The builder owns the rented array - always
usingit, or the array leaks from the pool. WrittenSpan/WrittenMemoryare zero-copy views valid only while the builder is alive; copy out before disposal if the data must outlive it.Resetreuses the current rented array without a pool round-trip, which makes the builder cheap to recycle inside loops.
Because it implements IBufferWriter<T>, the builder drops into any span-based pipeline that the BCL's writer-style APIs accept. Prefer it over MemoryStream or List<byte> when buffers are short-lived, sized unpredictably, and built on hot paths.
Character-encoding vocabulary
The Bodu.Text namespace works in terms the BCL defines but does not always make ergonomic:
- Preamble / BOM - the byte-order mark some encoders emit at the start of a stream (the five canonical Unicode preambles: UTF-8, UTF-16 LE/BE, UTF-32 LE/BE). EncodingDetection identifies an encoding from its preamble with a non-allocating
TryDetectByPreamble, and the extension surface can decode while skipping a leading preamble or emit one when writing. - Transcoding - converting bytes from one character encoding to another without materializing an intermediate
string. EncodingExtensions provides span-based transcode overloads. - Validation - confirming that a byte span is well-formed for a given encoding before trusting it, rather than discovering malformed sequences mid-decode.
- Span-first, UTF-8-first surfaces - every operation has overloads over
ReadOnlySpan<char>/ReadOnlySpan<byte>and UTF-8-specific fast paths (ToUtf8Bytes, pooled conversions on StringEncodingExtensions), so the common cases avoid intermediate allocations entirely.
The distinction worth internalizing: Bodu.Text handles character encodings (bytes ↔ text through System.Text.Encoding); the separate Bodu.Text.Encoding package handles binary-to-text codecs (Base16/32/58/64/85). Similar names, different jobs.
Member concept pages
| Member | Concepts coverage |
|---|---|
| Bodu.Core | Bodu.Core - Core concepts - WeekPattern, pooled buffers, railway-oriented outcomes, natural ordering, async coordination, ThrowHelper, the random-generator abstraction, and the calendar-shape extensions. |
| Bodu.Collections | Bodu.Collections - Core concepts - fixed-capacity and ring-backed collections, overflow policies, eviction policies and time-based expiry, navigation and rank/select, overlap-storing intervals, approximate sketches, multi-value / multiset semantics, range-keyed lookups, and index-aware collections. |
| Bodu.Collections.Concurrent | Bodu.Collections.Concurrent - Core concepts - lock-free MPMC rings, split-ordered hashing, snapshot enumeration, counting under concurrency, and eviction events under contention. |
| Bodu.Text | No separate concepts page - the Bodu.Text introduction covers the encoding-detection and transcoding vocabulary alongside its type map. |
For the topic-level package map and decision table, return to the Core Foundations overview; for hands-on walk-throughs, see the Core Foundations guides.