Skip to main content

sonic/executor/
count.rs

1// Sonic
2//
3// Fast, lightweight and schema-less search backend
4// Copyright: 2019, Valerian Saliou <valerian@valeriansaliou.name>
5// Copyright: 2026, Rémi Bardon <remi@remibardon.name>
6// License: Mozilla Public License v2.0 (MPL v2.0)
7
8use crate::store::StoreItem;
9use crate::store::fst::{StoreFSTActionBuilder, StoreFSTMisc};
10use crate::store::kv::StoreKVAcquireMode;
11use crate::store::kv::StoreKVActionBuilder;
12
13impl super::Executor {
14    pub fn count(&self, item: StoreItem) -> Result<u32, ()> {
15        match item {
16            // Count terms in (collection, bucket, object) from KV
17            StoreItem(collection, Some(bucket), Some(object)) => {
18                // Important: acquire database access read lock, and reference it in context. This \
19                //   prevents the database from being erased while using it in this block.
20                let _kv_read_guard = self.kv_pool.lock_read_access();
21
22                if let Ok(kv_store) = self
23                    .kv_pool
24                    .acquire(StoreKVAcquireMode::OpenOnly, collection)
25                {
26                    // Important: acquire bucket store read lock
27                    executor_kv_lock_read!(kv_store);
28
29                    let kv_action = StoreKVActionBuilder::access(bucket, kv_store);
30
31                    // Try to resolve existing OID to IID
32                    let oid = object.as_str();
33
34                    kv_action
35                        .get_oid_to_iid(oid)
36                        .unwrap_or(None)
37                        .map(|iid| {
38                            // List terms for IID
39                            if let Some(terms) = kv_action.get_iid_to_terms(iid).unwrap_or(None) {
40                                terms.len() as u32
41                            } else {
42                                0
43                            }
44                        })
45                        .ok_or(())
46                        .or(Ok(0))
47                } else {
48                    Err(())
49                }
50            }
51            // Count terms in (collection, bucket) from FST
52            StoreItem(collection, Some(bucket), None) => {
53                // Important: acquire graph access read lock, and reference it in context. This \
54                //   prevents the graph from being erased while using it in this block.
55                let _fst_read_guard = self.fst_pool.lock_read_access();
56
57                if let Ok(fst_store) = self.fst_pool.acquire(collection, bucket) {
58                    let fst_action = StoreFSTActionBuilder::access(fst_store);
59
60                    Ok(fst_action.count_words() as u32)
61                } else {
62                    Err(())
63                }
64            }
65            // Count buckets in (collection) from FS
66            StoreItem(collection, None, None) => {
67                StoreFSTMisc::count_collection_buckets(collection, &self.app_conf.store.fst)
68                    .map(|count| count as u32)
69            }
70            _ => Err(()),
71        }
72    }
73}