Skip to main content

qdrant_edge/edge/
count.rs

1use std::sync::atomic::AtomicBool;
2
3use crate::common::counter::hardware_counter::HardwareCounterCell;
4use crate::common::types::DeferredBehavior;
5use itertools::Itertools as _;
6use crate::segment::common::operation_error::OperationResult;
7use crate::segment::index::field_index::EstimationMerge;
8use crate::shard::count::CountRequestInternal;
9
10use super::EdgeShard;
11
12impl EdgeShard {
13    pub fn count(&self, request: CountRequestInternal) -> OperationResult<usize> {
14        let CountRequestInternal { filter, exact } = request;
15
16        let (non_appendable, appendable) = self.segments.read().split_segments();
17        let segments = non_appendable.into_iter().chain(appendable);
18
19        let points_count = if exact {
20            segments
21                .map(|segment| {
22                    segment.get().read().read_filtered(
23                        None,
24                        None,
25                        filter.as_ref(),
26                        &AtomicBool::new(false),
27                        &HardwareCounterCell::disposable(),
28                        DeferredBehavior::Exclude,
29                    )
30                })
31                .process_results(|iter| iter.flatten().count())?
32        } else {
33            let cardinality = segments
34                .map(|segment| {
35                    segment
36                        .get()
37                        .read() // blocking sync lock
38                        .estimate_point_count(filter.as_ref(), &HardwareCounterCell::disposable())
39                })
40                .process_results(|iter| iter.merge_independent())?;
41
42            cardinality.exp
43        };
44
45        Ok(points_count)
46    }
47}