Skip to main content

velesdb_core/database/
stats.rs

1//! Collection statistics: analyze and cache collection stats.
2
3use crate::{Error, Result};
4
5use super::Database;
6
7impl Database {
8    /// Analyzes a collection, caches stats, and persists them to disk.
9    ///
10    /// # Errors
11    ///
12    /// Returns an error if the name is invalid, the collection does not exist,
13    /// analysis fails, or stats cannot be serialized and written to disk.
14    #[allow(deprecated)]
15    pub fn analyze_collection(
16        &self,
17        name: &str,
18    ) -> Result<crate::collection::stats::CollectionStats> {
19        crate::validation::validate_collection_name(name)?;
20
21        let collection = self
22            .get_collection(name)
23            .ok_or_else(|| Error::CollectionNotFound(name.to_string()))?;
24        let stats = collection.analyze()?;
25
26        self.collection_stats
27            .write()
28            .insert(name.to_string(), stats.clone());
29
30        let stats_path = self.data_dir.join(name).join("collection.stats.json");
31        let serialized = serde_json::to_vec_pretty(&stats)
32            .map_err(|e| Error::Serialization(format!("failed to serialize stats: {e}")))?;
33        std::fs::write(&stats_path, serialized)?;
34
35        Ok(stats)
36    }
37
38    /// Returns cached statistics when available, loading from disk if present.
39    ///
40    /// # Errors
41    ///
42    /// Returns an error if the name is invalid, or the on-disk stats file
43    /// exists but cannot be read or deserialized.
44    pub fn get_collection_stats(
45        &self,
46        name: &str,
47    ) -> Result<Option<crate::collection::stats::CollectionStats>> {
48        crate::validation::validate_collection_name(name)?;
49
50        if let Some(stats) = self.collection_stats.read().get(name).cloned() {
51            return Ok(Some(stats));
52        }
53
54        let stats_path = self.data_dir.join(name).join("collection.stats.json");
55        if !stats_path.exists() {
56            return Ok(None);
57        }
58
59        let bytes = std::fs::read(stats_path)?;
60        let stats: crate::collection::stats::CollectionStats = serde_json::from_slice(&bytes)
61            .map_err(|e| Error::Serialization(format!("failed to parse stats: {e}")))?;
62        self.collection_stats
63            .write()
64            .insert(name.to_string(), stats.clone());
65        Ok(Some(stats))
66    }
67}