///|
/// Operational counters for observing a search workload without exposing data.
pub(all) struct SearchTelemetry {
queries : Int
returned : Int
filtered : Int
empty_queries : Int
average_results : Double
}
///|
pub impl Show for SearchTelemetry with fn output(self, logger) {
logger.write_string(
"SearchTelemetry{queries: " +
self.queries.to_string() +
", returned: " +
self.returned.to_string() +
", filtered: " +
self.filtered.to_string() +
", empty_queries: " +
self.empty_queries.to_string() +
", average_results: " +
self.average_results.to_string() +
"}",
)
}
///|
/// Aggregate result lists into a privacy-preserving workload summary.
pub fn summarize_workload(
batches : Array[Array[SearchResult]],
requested_top_k : Int,
) -> SearchTelemetry {
let mut returned = 0
let mut empty_queries = 0
for batch in batches {
returned = returned + batch.length()
if batch.length() == 0 {
empty_queries = empty_queries + 1
}
}
let queries = batches.length()
let average_results = if queries == 0 {
0.0
} else {
returned.to_double() / queries.to_double()
}
let filtered = if requested_top_k * queries > returned {
requested_top_k * queries - returned
} else {
0
}
{ queries, returned, filtered, empty_queries, average_results }
}
///|
/// Compare two workloads by average result count.
pub fn workload_delta(a : SearchTelemetry, b : SearchTelemetry) -> Double {
b.average_results - a.average_results
}
///|
/// Return whether a workload has enough successful queries for a stable sample.
pub fn workload_is_stable(
report : SearchTelemetry,
minimum_queries : Int,
) -> Bool {
report.queries >= minimum_queries &&
report.queries > 0 &&
report.empty_queries * 2 <= report.queries
}
///|
/// A deterministic report for evaluating filter selectivity.
pub(all) struct FilterReport {
total : Int
matched : Int
selectivity : Double
}
///|
pub impl Show for FilterReport with fn output(self, logger) {
logger.write_string(
"FilterReport{total: " +
self.total.to_string() +
", matched: " +
self.matched.to_string() +
", selectivity: " +
self.selectivity.to_string() +
"}",
)
}
///|
/// Measure how many documents survive a metadata filter.
pub fn measure_filter(
docs : Array[Document],
filters : Array[(String, String)],
) -> FilterReport {
let matched = filter_documents(docs, filters).length()
let selectivity = if docs.length() == 0 {
0.0
} else {
matched.to_double() / docs.length().to_double()
}
{ total: docs.length(), matched, selectivity }
}
///|
/// Return the fraction of approximate results that also satisfy an exact filter.
pub fn filtered_recall(
approximate : Array[SearchResult],
exact : Array[SearchResult],
k : Int,
) -> Double {
recall_at_k(approximate, exact, k)
}
///|
/// Determine whether an index appears useful for a requested recall target.
pub fn meets_recall_target(
approximate : Array[Array[SearchResult]],
exact : Array[Array[SearchResult]],
k : Int,
target : Double,
) -> Bool {
mean_recall(approximate, exact, k) >= target
}