Table of Contents

Class PackedTileStore

Packed on-disk cache for downloaded tiles: one data file and one append-only index instead of a file per tile. The pipeline uses this; most apps never call it.

public sealed class PackedTileStore : ITilePersistentStore, IDisposable
Inheritance
object
PackedTileStore
Implements

Remarks

Frame-path members (TryRead(ulong, out byte[], out int), Write(ulong, byte[], int), FlushDue(double, double)) treat a file error as a miss or a dropped write and do not throw. The constructor, Flush(), and Dispose() still throw, so a failed open cannot leave a locked handle behind a discarded instance. Prefer OpenOrDegraded(string, TileCacheSettings, out Exception) when losing the cache is better than losing the map.

Constructors

PackedTileStore(string)

Opens the store under directory with Default.

public PackedTileStore(string directory)

Parameters

directory string

Folder for tiles.dat and tiles.idx; created if missing.

PackedTileStore(string, TileCacheSettings)

Opens the store under directory with settings. Throws on a file error.

public PackedTileStore(string directory, TileCacheSettings settings)

Parameters

directory string

Folder for tiles.dat and tiles.idx; created if missing.

settings TileCacheSettings

Validated cache configuration.

PackedTileStore(string, long)

Opens the store under directory with a live-data cap of maxDataBytes bytes.

public PackedTileStore(string directory, long maxDataBytes)

Parameters

directory string

Folder for tiles.dat and tiles.idx; created if missing.

maxDataBytes long

Live-data cap in bytes; must be positive.

Fields

DefaultEvictionsPerCall

Eviction steps one DrainPendingEviction(int) call performs when the caller does not name a number.

public const int DefaultEvictionsPerCall = 256

Field Value

int

Properties

CompactionDeferred

True when open found reclaimable waste but skipped the rewrite because the live set was past InlineCompactMaxBytes.

public bool CompactionDeferred { get; }

Property Value

bool

CompactionsRun

Compactions that actually shrank the data file.

public int CompactionsRun { get; }

Property Value

int

Disabled

True when the store holds no files; every member then misses or drops.

public bool Disabled { get; }

Property Value

bool

DroppedWrites

Writes refused because the payload was malformed, the file is at its bound, or the store is Disabled.

public int DroppedWrites { get; }

Property Value

int

InvalidIndexRecordsDropped

Damaged index records dropped since this instance opened. Does not reset across compaction; a new process starts at 0.

public int InvalidIndexRecordsDropped { get; }

Property Value

int

IoFailures

Swallowed file errors since this instance opened.

public int IoFailures { get; }

Property Value

int

LiveBytes

Bytes reachable through the index, excluding orphans.

public long LiveBytes { get; }

Property Value

long

PinnedKeyCount

Number of keys currently pinned against eviction.

public int PinnedKeyCount { get; }

Property Value

int

ProtectedBytes

Subset of LiveBytes in the protected zoom tier, in bytes.

public long ProtectedBytes { get; }

Property Value

long

ProtectedEvictionsUnderPressure

Coarse tiles evicted while the protected reservation was already at its floor. Structurally 0; counted rather than thrown because Write runs on the frame path.

public long ProtectedEvictionsUnderPressure { get; }

Property Value

long

Settings

Configuration this store is enforcing.

public TileCacheSettings Settings { get; }

Property Value

TileCacheSettings

Stats

Occupancy and hit counters for this store instance.

public TileCacheStats Stats { get; }

Property Value

TileCacheStats

SwapStepCount

Number of atomic steps in a compaction file swap. Crash-recovery tests use this; apps should not.

public static int SwapStepCount { get; }

Property Value

int

WritesRefusedAtFileBound

Dropped writes caused by the file sitting at MaxFileBytes.

public int WritesRefusedAtFileBound { get; }

Property Value

int

Methods

Clear()

Wipes both files and every in-memory entry; the store stays open.

public void Clear()

CompactNow()

Rewrites the packed file now, for a caller that can afford the stall (pause, scene load, quit).

public bool CompactNow()

Returns

bool

True when the data file shrank.

Contains(ulong)

True when key is in the in-memory index.

public bool Contains(ulong key)

Parameters

key ulong

Disk cache key.

Returns

bool

True when a later TryRead(ulong, out byte[], out int) may succeed for this key.

Degraded(string, TileCacheSettings)

A store that holds no files: every member misses or drops instead of throwing. What a failed open degrades to.

public static PackedTileStore Degraded(string directory, TileCacheSettings settings)

Parameters

directory string

Folder the store would have used; reported, never opened.

settings TileCacheSettings

Validated cache configuration.

Returns

PackedTileStore

Dispose()

Closes the data and index files.

public void Dispose()

DrainPendingEviction(int)

Continues eviction after a live cap shrink, up to maxEvictions entries.

public bool DrainPendingEviction(int maxEvictions = 256)

Parameters

maxEvictions int

Maximum dictionary removals this call.

Returns

bool

True while live bytes still exceed the cap.

Flush()

Pushes buffered writes to the OS now. Call this before inspecting the files on disk.

public void Flush()

Remarks

Not fsync: FileStream.Flush reaches the OS, not the platter.

FlushDue(double, double)

Flushes at most once per intervalSeconds; call from the frame tick.

public void FlushDue(double now, double intervalSeconds = 1)

Parameters

now double

Monotonic time in seconds, the same clock the caller uses for intervals.

intervalSeconds double

Minimum seconds between flushes; default 1.

Remarks

May rewrite the packed file on this tick when the file is past its bound and the live set is small enough for an inline compact.

IsKeyPinned(ulong)

True when key is in the pinned set.

public bool IsKeyPinned(ulong key)

Parameters

key ulong

Disk cache key.

Returns

bool

True when eviction will skip this key.

OpenOrDegraded(string, TileCacheSettings, out Exception)

Opens the store, or returns a disabled store when the files cannot be opened.

public static PackedTileStore OpenOrDegraded(string directory, TileCacheSettings settings, out Exception failure)

Parameters

directory string

Folder for tiles.dat and tiles.idx.

settings TileCacheSettings

Validated cache configuration.

failure Exception

The file error when degraded; null on success.

Returns

PackedTileStore

An open store, or a store whose every member misses or drops instead of throwing.

Remarks

Only IOException and UnauthorizedAccessException degrade. A bad directory or an out-of-memory failure still throws.

PinKey(ulong)

Prevents key from being evicted, independent of zoom tier.

public void PinKey(ulong key)

Parameters

key ulong

Disk cache key. Pinning before the first write is legal.

PinKeys(IReadOnlyList<ulong>)

Pins every key in keys.

public void PinKeys(IReadOnlyList<ulong> keys)

Parameters

keys IReadOnlyList<ulong>

Disk cache keys. Pinning a key not yet written is legal.

SetMaxDataBytes(long)

Changes the live-data cap. A shrink evicts a bounded number of entries here and leaves the rest to DrainPendingEviction(int).

public void SetMaxDataBytes(long maxDataBytes)

Parameters

maxDataBytes long

New live-data cap in bytes; must be positive.

SwapStep(string, int)

Runs one compaction-swap step against directory. Destructive: it renames the live cache files.

public static void SwapStep(string directory, int step)

Parameters

directory string

Folder holding tiles.dat and tiles.idx.

step int

Step index in 0..SwapStepCount minus one.

Remarks

Tests use this to stop a swap mid-way. Apps should not call it.

TryRead(ulong, out byte[], out int)

Reads the blob for key into a reused buffer.

public bool TryRead(ulong key, out byte[] bytes, out int length)

Parameters

key ulong

Disk cache key for the tile.

bytes byte[]

Internal buffer holding the blob; valid until the next TryRead(ulong, out byte[], out int). Copy it if you need to keep it.

length int

Valid length of bytes in bytes.

Returns

bool

True when the key is present and the read succeeded.

UnpinKey(ulong)

Drops eviction protection for key.

public void UnpinKey(ulong key)

Parameters

key ulong

Disk cache key.

UnpinKeys(IReadOnlyList<ulong>)

Drops eviction protection for every key in keys.

public void UnpinKeys(IReadOnlyList<ulong> keys)

Parameters

keys IReadOnlyList<ulong>

Disk cache keys.

Write(ulong, byte[], int)

Appends a blob that never joins the protected zoom tier.

public void Write(ulong key, byte[] bytes, int length)

Parameters

key ulong

Disk cache key for the tile.

bytes byte[]

Source buffer; only the first length bytes are stored.

length int

Payload length in bytes.

Write(ulong, byte[], int, int)

Appends a blob, placing it in the protected tier when the reservation is enabled and zoom is in 0..ProtectedMaxZoom.

public void Write(ulong key, byte[] bytes, int length, int zoom)

Parameters

key ulong

Disk cache key for the tile.

bytes byte[]

Source buffer; only the first length bytes are stored.

length int

Payload length in bytes.

zoom int

Integer tile zoom used only to choose the eviction tier.

Remarks

Zoom is passed in because the disk key does not preserve it. File errors drop the write rather than throw.