vike
Desktop appData Manager

Coverage

The span bar and its shared scale, the stale tint, gap cut-outs from the file index, the cross-kind Partial column, and the two smart views that filter on them.

One cell answers three questions — how much of the store's timeline a series spans, whether it has stopped, and whether it has holes — and a fourth, whether an instrument has days where one kind is present and another is not, cannot be answered per series and gets its own column. The authorities are crates/vike-data-manager/src/view.rs for the rendering and crates/vike-data-manager/src/model.rs for the rollups the scale is built from.

The span bar

paint_coverage_bar paints a background track and a filled segment spanning the series' [first_ts, last_ts], mapped over the tree-wide window [global_first, global_last]. That window is global_span: the earliest first and latest last across every venue with at least one series, folded from the RollUp each node carries. The header gives the reason for a shared scale: bars are painted over the tree-wide window "so bars are comparable across every row". A zero-row series paints an empty track, and when nothing has data the window is inert and every bar is empty.

Stale

A series reads as stale when its last_ts lags more than 35 % of the tree-wide span behind the global maximum, and its bar takes the warning colour. is_stale's doc calls the fraction arbitrary but conservative: recent data is typically within a few percent of the newest, and anything more than a third of the whole window behind is very likely an abandoned or broken feed rather than yesterday's close. It is a fraction of the span you hold, not a number of days.

Gap cut-outs

The rich grid takes a GapMap: per-series missing-day ranges keyed by the same SeriesKey the selection uses. paint_coverage_bar overpaints each range as a dark cut-out inside the filled segment, so a hole reads as missing against the span. Fetching the map is the caller's job — the header is explicit that this crate never calls series_gaps itself — and has_gaps's doc states the conservative default: a series absent from the map, never fetched or failed, is treated as gap-free, so the bar never flags a series it has no data for.

What a gap is comes from crates/vike-data/src/datafusion_hist.rs's series_gaps: the ranges missing within a series' recorded span, derived purely from the manifest's date= file index with no Parquet scan, as cheap as a coverage read. Contiguous coverage, fewer than two distinct days, or no data at all return an empty list; it never errors on "no data". The finder underneath is crates/vike-data/src/coverage.rs's find_gaps, whose doc example is the whole rule: present days [1, 2, 5, 6] give one gap, (3, 4).

A gap is a missing day, not a missing row

The index knows which days exist and nothing finer. coverage.rs's header draws the line: a day that is present but was recorded through a feed outage is a row-level trust question, answered by the quality module over scanned rows, not by this fold. A day the recorder half-covered shows as present here.

The app fetches the map alongside the tree: crates/vike-app-core/src/stored_load.rs's load_stored_tree probes series_gaps once per listed series — manifest-only locally, one small RPC per series on a remote store — and a failed probe skips that one entry rather than failing the refresh, which runs on the tab's first render and on Refresh, never per frame.

Partial days

PartialDayMap is keyed one level above the gap map, by vike_data::InstrumentKey — venue, label and the grouped flag. Its doc explains why it is a second map rather than more gap entries: the two answer different questions and neither derives from the other. A gap says this series is missing days 3–4, a hole in one kind's own timeline. A partial day says on day 11 the instrument has trades but no book — invisible per series, because each series is perfectly contiguous on its own. The doc's example is the case that motivated the column: a Polymarket venue backfill restores the trade tape and nothing else, since no venue-direct source serves book, so the trade series closes its gap, the book series never had one, and only the join shows that a market-making backtest over that window would run on no book at all.

The join is coverage.rs's InstrumentCoverage::partial_days, and two of its rules shape the column:

  • Only tick kinds are lined up. TICK_KINDS is trade, quote, book, depth. Bars are excluded on purpose: they derive from trades, so a missing bar day beside a present trade day is a resample not yet run, not a hole in the tape. depth is included because that is where some feeds' L2 lands — omitting it once made the report claim an instrument had no L2 while 34 rows of it sat on disk.
  • Days are held against the instrument's own recorded kinds. An instrument with no book series at all is not partial on every day it will ever have — the doc calls that "a permanent ⚠ carrying no day-to-day information, which is precisely how an operator learns to ignore a warning column"; the absence is already visible as a missing book row. With fewer than two recorded kinds nothing is partial.

The report is a manifest fold in the same cost class as the inventory — one manifest read per series, no Parquet scan — so the Data Manager runs it on open. The column shows a ⚠ glyph and puts the detail in the tooltip, in partial_days_label's shape: 3 partial days (book, quote). It is an instrument-level flag, so every row of one instrument carries the same value.

Over the wire, the column has three states

crates/vike-app-core/src/stored_mode.rs decides them. Local: rendered from the local fold. Remote, verb served: rendered from the wire answer. Remote, verb not served: a note in its place — "Partial column unavailable: the connected datahub did not answer the cross-kind coverage verb (an older server, or a read failure — see the log)". The verb is capability-negotiated rather than version-gated, so a refusal means the peer predates it, and an empty column is never substituted, because empty would claim "nothing is partial" — a different and possibly false fact.

The smart views

filter_tree applies the sidebar's choice. Has gaps keeps only series with a non-empty gap list; Stale keeps only series whose coverage lags the tree-wide span, reusing is_stale; a venue entry keeps only that venue. Both smart views drop symbols left with nothing and venues that empty out, and — the detail filter_stale_venue's doc insists on — rebuild the rollups over the surviving rows, so the filtered tree's header summaries and span bars stay internally consistent rather than describing rows you can no longer see.

On this page