pub enum SectionPolicy {
Cost,
Split,
Widen,
PrefixOnly,
Room,
Runt,
Adaptive,
}Expand description
How a section decides between widening its encoding and closing where it stands.
Every variant produces a valid bigWig; they differ only in how big it is.
SectionPolicy::Adaptive is the default and the only one a caller should
normally set — the rest exist so that “is this rule any good?” is a
question with a measured answer rather than an opinion. See
examples/section_policy.rs, which writes the same data through each and
reports the bytes; the answer, over six shapes of input, is that Adaptive
writes files 17% smaller than Cost and is the smallest or within half
a percent of it on every one.
Variants§
Cost
Weigh the bytes a widening costs against the bytes a split costs, counting the widening over what is buffered plus what the current call still has to give.
The rule this library shipped with, and measurably not a good one: a caller adding values one at a time has nothing left in the call, so the second term vanishes and the widening is costed over the prefix alone — while the section goes on filling in the wider encoding and paying for every value of it. Kept as the baseline the others are measured against.
Split
Never widen: close the section and start a new one in the narrower encoding. Most sections, smallest items.
Widen
Never split for encoding: widen and keep going until items_per_slot.
Fewest sections, widest items.
PrefixOnly
Weigh only what is already buffered, ignoring what the call still has to hand over. The obvious rule, and what the cost model would be without its second term.
Room
Weigh the widening against the room left in the section, rather than against what the current call happens to have left.
SectionPolicy::Cost costs the tail at min(batch_remaining, room),
and a caller adding values one at a time has batch_remaining == 0 —
so the tail term vanishes and the widening is costed over the prefix
alone. But the section does not stop there: it goes on filling to
items_per_slot in the wider encoding, paying the extra width for
every one of them. This costs what will actually be paid.
Runt
SectionPolicy::Room, and never split a section too short to be
worth writing.
The failure Room has on its own is that data which is irregular
throughout breaks the section immediately, every time: split, reopen,
break at item two, split again — sections of one item, and a file
several times larger than it should be. Widening a section that has
barely started costs almost nothing, so below the floor it always
widens.
Adaptive
SectionPolicy::Room, and split unless the data has just shown that
splitting does not work.
The two failure modes pull opposite ways and no arithmetic at the break can tell them apart, because both look identical at that instant:
- Data that is regular with rare breaks wants a split. Widening makes the whole rest of the section wider to absorb one odd value.
- Data that is irregular throughout wants a widening. Splitting emits one section per value, an R-tree leaf and a zlib stream each.
What does tell them apart is what happened last time. A split that was right is followed by a section that goes on to hold many values; a split that was wrong is followed by one that breaks again immediately. So this splits by default and stops as soon as two sections in a row have come out too short to be worth writing — and starts again the moment one does not.
The cost is bounded: at most runt_patience short sections are written
before it adapts, once per stretch of irregular data.
Two things beyond the streak make this the default rather than
SectionPolicy::Runt:
- The streak only overrules the arithmetic for a section that is itself short. A section holding a thousand uniform values is always worth closing, whatever the burst before it did.
- A long run that cannot extend the open section flushes it first — see
WigSection::should_flush_for_run. Without that, one odd value makes the next thousand cost three times as much, and nothing else in the writer is in a position to notice.
Trait Implementations§
Source§impl Clone for SectionPolicy
impl Clone for SectionPolicy
Source§fn clone(&self) -> SectionPolicy
fn clone(&self) -> SectionPolicy
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for SectionPolicy
Source§impl Debug for SectionPolicy
impl Debug for SectionPolicy
Source§impl Default for SectionPolicy
impl Default for SectionPolicy
Source§fn default() -> SectionPolicy
fn default() -> SectionPolicy
impl Eq for SectionPolicy
Source§impl PartialEq for SectionPolicy
impl PartialEq for SectionPolicy
impl StructuralPartialEq for SectionPolicy
Auto Trait Implementations§
impl Freeze for SectionPolicy
impl RefUnwindSafe for SectionPolicy
impl Send for SectionPolicy
impl Sync for SectionPolicy
impl Unpin for SectionPolicy
impl UnsafeUnpin for SectionPolicy
impl UnwindSafe for SectionPolicy
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more