SchemaCatalog

class SchemaCatalog(val directory: Path, val options: CatalogOptions = CatalogOptions.DEFAULT) : SegmentObserver

The model of what is in a store, derived from its documents as they are written.

val catalog = SchemaCatalog(directory)
DocumentStore.open(directory, StoreOptions(segmentObserver = catalog)).use { store ->
store.put(Key.of("user:1"), Variant.fromJson("""{"name":"ada","team":"analytics"}"""))
store.flush()
catalog.attach(store)

println(catalog.inferSchema().render())
catalog.indexCandidates().forEach(::println)
}

Nothing here scans the store. Statistics are collected on the flush and compaction passes that were going to walk every document anyway, kept in a .cat sidecar next to each segment, and folded on demand. A compaction that merges two segments into one replaces two sketches with one as a consequence of the merge, so the model is never stale and there is no invalidation step to forget. attach covers whatever was written before the catalog existed, by reading the segments that are already there — which is the whole "model later" claim, and it is why an index recommendation can be asked for on a store nobody planned to model.

Two objects, and the order matters. The observer has to be installed in app.oreshkov.rabosh.core.StoreOptions before the store opens, because a flush can begin the moment it does; attach is what loads the sidecars and backfills the rest, and until it is called this catalog answers nothing. That is deliberate — a model that quietly reported on half a store would be worse than one that refuses. A caller who would rather not remember any of it opens a Rabosh from rabosh-api, which owns the ordering and reaches this catalog through one backfill pass shared with the index catalog.

Thread safety. Safe to call from any thread. The store's maintenance thread drives beginSegment, SegmentObservation.complete and retain while a reader may be inside inferSchema; the accumulation of one segment happens on one thread and is not shared.

Constructors

Link copied to clipboard
constructor(directory: Path, options: CatalogOptions = CatalogOptions.DEFAULT)

Properties

Link copied to clipboard

The store directory sidecars live in. The same directory the store was opened on.

Link copied to clipboard

Whether attach has been called. Nothing is answered before it has.

Link copied to clipboard
Link copied to clipboard

Failures raised inside this catalog's own callbacks, in order.

Functions

Link copied to clipboard
fun attach(store: DocumentStore, backfill: Boolean = true)

Loads what is on disk, scans whatever is not, and starts maintaining the model.

Link copied to clipboard
open override fun beginSegment(segmentNumber: Long): SegmentObservation?
Link copied to clipboard
fun indexCandidates(options: IndexCandidateOptions = IndexCandidateOptions.DEFAULT): List<IndexCandidate>

The paths worth an index, best first.

Link copied to clipboard

Folds the live segments' sketches into one model.

Link copied to clipboard
open override fun observerFailed(cause: Throwable)
Link copied to clipboard

Discards everything and rebuilds it from the segments.

Link copied to clipboard
open override fun retain(liveSegments: Set<Long>)
Link copied to clipboard
fun sketchOf(segmentNumber: Long): SegmentSketch?

The sketch of one segment, or null if it is not covered. For tests and for diagnostics.

Link copied to clipboard
open override fun toString(): String