Table of Contents

Class OfflineBundlePageSource

Namespace
Typhon.Engine
Assembly
Typhon.Engine.dll

Reads a .typhon bundle directly as bytes: no DatabaseEngine, no page cache, no lock acquisition, no WAL replay. The page source the checker uses when it matters most — when the database will not open.

public sealed class OfflineBundlePageSource : IPageSource, IDisposable
Inheritance
OfflineBundlePageSource
Implements
Inherited Members

Remarks

Booting the engine to inspect a database is self-defeating three ways. It destroys the evidence (on the crash path the rebuild net clears and re-derives indexes, chains, entity maps and occupancy before a caller gets a handle, so a post-open check can only ever verify that rebuild worked). It cannot reach the cases that matter most (an open that fails loudly by design leaves no handle to ask questions through). And it mutates — acquiring the lock, clearing the clean-shutdown flag, replaying the log, checkpointing on close.

Opened FileAccess.Read with FileShare.ReadWrite so a live database can still be scanned; a scan of a live database yields Suspected cross-structure findings, never Confirmed ones.

Constructors

OfflineBundlePageSource(string)

Opens a bundle for reading.

public OfflineBundlePageSource(string bundlePath)

Parameters

bundlePath string

Path to the {name}.typhon bundle directory, or to the data file inside one. A path whose extension is missing gets .typhon appended when that directory exists.

Exceptions

ArgumentNullException

bundlePath is null.

DirectoryNotFoundException

No bundle directory could be resolved from bundlePath.

FileNotFoundException

The bundle has no data file.

Properties

BundlePath

Absolute path to the bundle directory.

public string BundlePath { get; }

Property Value

string

LockFilePresent

Whether a db.lock file exists in the bundle.

public bool LockFilePresent { get; }

Property Value

bool

LockHeld

Whether db.lock is held by another process — i.e. a live engine has this database open.

public bool LockHeld { get; }

Property Value

bool

PageCount

Number of pages addressable in this source. Indices [0, PageCount) are in range.

public int PageCount { get; }

Property Value

int

PagesRead

Pages actually read from disk since this source was opened.

public long PagesRead { get; }

Property Value

long

Remarks

Exists so a test can assert what a scan costs rather than what it claims to cost. The open-time Spine tier is only affordable as a default because it is bounded by the number of segments rather than the size of the database; that is a property of the I/O it performs, so it has to be measured at the I/O boundary. Asserting it any further up measures the wrong thing.

SizeBytes

Size of the data file in bytes.

public long SizeBytes { get; }

Property Value

long

TrailingBytes

Bytes past the last whole page. Non-zero means the data file is truncated mid-page — itself a finding, because every write the engine performs is whole-page.

public int TrailingBytes { get; }

Property Value

int

WalSegments

WAL segment files found in the bundle's wal/ directory, unparsed, ordered by name.

public IReadOnlyList<WalSegmentRef> WalSegments { get; }

Property Value

IReadOnlyList<WalSegmentRef>

Methods

Describe()

Human-readable identity of the source, used to anchor findings: a bundle path, a backup id, or "live".

public string Describe()

Returns

string

Dispose()

public void Dispose()

ResolveBundleDirectory(string)

Resolves a user-supplied path to a bundle directory. Accepts the directory itself, the data file inside it, or a stem with no extension.

public static string ResolveBundleDirectory(string path)

Parameters

path string

The user-supplied path.

Returns

string

Exceptions

DirectoryNotFoundException

Nothing resolvable was found.

TryReadPage(int, Span<byte>)

Reads page index into destination.

public bool TryReadPage(int index, Span<byte> destination)

Parameters

index int

Zero-based file-page index.

destination Span<byte>

Buffer of at least PageSize bytes.

Returns

bool

true when the page was read in full; false when it does not exist in this source (out of range, or a hole in a sparse source such as an incremental backup). A false return is not an error — the caller decides whether an absent page is a finding.