use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::atomic::AtomicBool;
use ahash::AHashMap;
use crate::common::counter::hardware_counter::HardwareCounterCell;
use crate::common::generic_consts::AccessPattern;
use crate::common::types::{DeferredBehavior, PointOffsetType, ScoreType};
use serde_json::Value;
use super::field_index::numeric_index::NumericFieldIndexRead;
use super::field_index::{FacetIndex, FieldIndex};
use super::query_optimization::rescore_formula::FormulaScorer;
use super::query_optimization::rescore_formula::parsed_formula::ParsedFormula;
use crate::segment::common::Flusher;
use crate::segment::common::operation_error::OperationResult;
use crate::segment::index::field_index::{CardinalityEstimation, PayloadBlockCondition};
use crate::segment::index::query_optimization::optimized_filter::OptimizedFilter;
use crate::segment::json_path::JsonPath;
use crate::segment::telemetry::PayloadIndexTelemetry;
use crate::segment::types::{Filter, Payload, PayloadFieldSchema, PayloadKeyType, PayloadKeyTypeRef};
pub enum BuildIndexResult {
Built(Vec<FieldIndex>),
AlreadyBuilt,
IncompatibleSchema,
}
pub trait PayloadIndexRead {
fn indexed_fields(&self) -> HashMap<PayloadKeyType, PayloadFieldSchema>;
fn estimate_cardinality(
&self,
query: &Filter,
hw_counter: &HardwareCounterCell,
) -> OperationResult<CardinalityEstimation>;
fn estimate_nested_cardinality(
&self,
query: &Filter,
nested_path: &JsonPath,
hw_counter: &HardwareCounterCell,
) -> OperationResult<CardinalityEstimation>;
fn query_points(
&self,
filter: &Filter,
hw_counter: &HardwareCounterCell,
is_stopped: &AtomicBool,
) -> OperationResult<Vec<PointOffsetType>>;
fn indexed_points(&self, field: PayloadKeyTypeRef) -> OperationResult<usize>;
fn filter_context<'a>(
&'a self,
filter: &'a Filter,
hw_counter: &HardwareCounterCell,
) -> OperationResult<OptimizedFilter<'a>>;
fn numeric_index_for(&self, key: &PayloadKeyType) -> Option<impl NumericFieldIndexRead + '_>;
fn facet_index_for(&self, key: &JsonPath) -> Option<impl FacetIndex + '_>;
fn get_telemetry_data(&self) -> OperationResult<Vec<PayloadIndexTelemetry>>;
fn formula_scorer<'q>(
&'q self,
parsed_formula: &'q ParsedFormula,
prefetches_scores: &'q [AHashMap<PointOffsetType, ScoreType>],
hw_counter: &'q HardwareCounterCell,
) -> OperationResult<FormulaScorer<'q>>;
fn iter_filtered_points<'a>(
&'a self,
filter: &'a Filter,
query_cardinality: &'a CardinalityEstimation,
hw_counter: &'a HardwareCounterCell,
is_stopped: &'a AtomicBool,
deferred_behavior: DeferredBehavior,
) -> OperationResult<impl Iterator<Item = PointOffsetType> + 'a>;
fn for_each_payload_block(
&self,
field: PayloadKeyTypeRef,
threshold: usize,
f: &mut dyn FnMut(PayloadBlockCondition) -> OperationResult<()>,
) -> OperationResult<()>;
fn get_payload(
&self,
point_id: PointOffsetType,
hw_counter: &HardwareCounterCell,
) -> OperationResult<Payload>;
fn get_payload_sequential(
&self,
point_id: PointOffsetType,
hw_counter: &HardwareCounterCell,
) -> OperationResult<Payload>;
fn read_payloads<P: AccessPattern, U: crate::common::universal_io::UserData>(
&self,
point_ids: impl Iterator<Item = (U, PointOffsetType)>,
callback: impl FnMut(U, Payload) -> OperationResult<()>,
hw_counter: &HardwareCounterCell,
) -> OperationResult<()>;
}
pub trait PayloadIndex {
fn build_index(
&self,
field: PayloadKeyTypeRef,
payload_schema: &PayloadFieldSchema,
hw_counter: &HardwareCounterCell,
) -> OperationResult<BuildIndexResult>;
fn apply_index(
&mut self,
field: PayloadKeyType,
payload_schema: PayloadFieldSchema,
field_index: Vec<FieldIndex>,
) -> OperationResult<()>;
fn set_indexed(
&mut self,
field: PayloadKeyTypeRef,
payload_schema: impl Into<PayloadFieldSchema>,
hw_counter: &HardwareCounterCell,
) -> OperationResult<()>;
fn drop_index(&mut self, field: PayloadKeyTypeRef) -> OperationResult<bool>;
fn drop_index_if_incompatible(
&mut self,
field: PayloadKeyTypeRef,
new_payload_schema: &PayloadFieldSchema,
) -> OperationResult<bool>;
fn overwrite_payload(
&mut self,
point_id: PointOffsetType,
payload: &Payload,
hw_counter: &HardwareCounterCell,
) -> OperationResult<()>;
fn set_payload(
&mut self,
point_id: PointOffsetType,
payload: &Payload,
key: &Option<JsonPath>,
hw_counter: &HardwareCounterCell,
) -> OperationResult<()>;
fn delete_payload(
&mut self,
point_id: PointOffsetType,
key: PayloadKeyTypeRef,
hw_counter: &HardwareCounterCell,
) -> OperationResult<Vec<Value>>;
fn clear_payload(
&mut self,
point_id: PointOffsetType,
hw_counter: &HardwareCounterCell,
) -> OperationResult<Option<Payload>>;
fn flusher(&self) -> Flusher;
fn files(&self) -> Vec<PathBuf>;
fn immutable_files(&self) -> Vec<(PayloadKeyType, PathBuf)> {
Vec::new()
}
}