holes

package
v0.3.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 18, 2026 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package holes is the shared model + threshold policy for "holes": runs of consecutive segments confirmed missing from Usenet providers. One table governs every moment the engine meets a hole:

  • at IMPORT, the fast-fail sweep classifies a file's sampled damage (fail the import / import as degraded / keep checking),
  • at HEALTH CHECK, sampled or full sweeps classify accumulated damage, and
  • at PLAYBACK, the hole hooks decide per miss whether to zero-fill and keep streaming or to kill the stream and fail the file.

Ported from AIOStreams' holes.ts. This package is imported by usenet, importer, health and nzbfilesystem layers; it must stay dependency-free.

Index

Constants

View Source
const (
	// MaxPadRunSegments is the longest run of consecutive missing segments
	// that may be zero-filled. A longer measured run fails the file.
	MaxPadRunSegments = 4
	// MaxPadTotalSegments is the cumulative padded-segment cap per file.
	MaxPadTotalSegments = 64
	// MaxPadFileBytesRatio is the cumulative padded-bytes share of the file
	// above which it is unwatchable. The segment-count caps are the primary
	// guards; this ratio only protects small files where the segment caps
	// would be a large share.
	MaxPadFileBytesRatio = 0.02
	// ProjectionMinHits is the minimum number of confirmed misses a PARTIAL
	// sample needs before a projection may fail a file; an observed run
	// beyond MaxPadRunSegments fails regardless (measured, not projected).
	ProjectionMinHits = 8
	// ProjectionMargin is how far a projection must exceed the cumulative cap
	// to fail early from partial evidence.
	ProjectionMargin = 2
)

Variables

This section is empty.

Functions

func EligibleFile

func EligibleFile(name string) bool

EligibleFile reports whether a file may have missing segments zero-filled, based on its extension.

Types

type Accumulator

type Accumulator struct {
	// contains filtered or unexported fields
}

Accumulator incrementally merges missing segments into maximal non-overlapping runs. Used by import/health sweeps (spread hits) and by playback sessions (pads as they happen, including out-of-order discovery via seeks). Not safe for concurrent use; callers hold their own lock.

func (*Accumulator) Add

func (a *Accumulator) Add(index int)

Add records one missing segment, merging into adjacent runs.

func (*Accumulator) AddRun

func (a *Accumulator) AddRun(run Run)

AddRun records a measured run, merging with any overlapping or adjacent existing runs.

func (*Accumulator) Has

func (a *Accumulator) Has(index int) bool

Has reports whether the segment index lies inside a known run.

func (*Accumulator) Load

func (a *Accumulator) Load(runs []Run)

Load seeds the accumulator from persisted runs.

func (*Accumulator) LongestRun

func (a *Accumulator) LongestRun() int

LongestRun is the length of the longest run ever merged. It never shrinks.

func (*Accumulator) Runs

func (a *Accumulator) Runs() []Run

Runs returns all runs ordered by Start. The slice is a copy.

func (*Accumulator) Total

func (a *Accumulator) Total() int

Total is the total number of missing segments across all runs.

type Decision

type Decision string

Decision is the playback hook's verdict for one confirmed missing segment.

const (
	// DecisionPad zero-fills the segment and keeps streaming.
	DecisionPad Decision = "pad"
	// DecisionFail kills the stream (caps exceeded / ineligible).
	DecisionFail Decision = "fail"
)

type Impact

type Impact struct {
	Verdict Verdict `json:"verdict"`
	// TotalMissing is the number of confirmed missing segments (capped
	// captures may undercount; Verdict already accounts for that).
	TotalMissing int `json:"total_missing"`
	// LongestRun is the longest observed run of consecutive missing segments.
	LongestRun int `json:"longest_run"`
	// Sampled is how many segments the sweep checked (0 = playback discovery).
	Sampled int `json:"sampled,omitempty"`
	// TotalSegments is the file's full segment count.
	TotalSegments int `json:"total_segments,omitempty"`
	// PaddedRatio is missing bytes / file bytes, when the file size is known.
	PaddedRatio float64 `json:"padded_ratio,omitempty"`
}

Impact is the serializable playback-impact summary persisted in health error details (playback_impact key) and rendered by the frontend.

type Run

type Run struct {
	// Start is the first missing segment index.
	Start int
	// Count is the number of consecutive missing segments.
	Count int
}

Run is a run of consecutive missing segments in one file's segment space.

type Verdict

type Verdict string

Verdict classifies a file's confirmed hole damage.

const (
	// VerdictClean means no confirmed damage (only a FULL check can prove it).
	VerdictClean Verdict = "clean"
	// VerdictDegraded means damage within the padding caps: playable with
	// glitches, zero-filled during streaming.
	VerdictDegraded Verdict = "degraded"
	// VerdictFailed means damage beyond the caps: unwatchable.
	VerdictFailed Verdict = "failed"
	// VerdictUnknown means a partial sample found nothing — absence of
	// evidence, not evidence of absence.
	VerdictUnknown Verdict = "unknown"
)

func Classify

func Classify(runs []Run, fileBytes int64, avgSegBytes int64) Verdict

Classify applies the threshold table to a file's confirmed damage. runs must cover the file's whole segment space (i.e. come from a full check or the persisted hole map). fileBytes is the file's decoded size when known (<= 0 skips the ratio guard); avgSegBytes an average decoded segment size (encoded sizes are fine; yEnc overhead is negligible for the ratio guard).

func ClassifyProjected

func ClassifyProjected(hits, sampled, totalSegments, longestObservedRun int) Verdict

ClassifyProjected classifies from a partial, uniform sample. It never returns VerdictClean: absence of evidence is VerdictUnknown until a full check completes.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL