Repository: meilisearch/meilisearch
File: crates/milli/src/database_stats.rs (Rust)

Code before:
        while let Some((key, value)) = iter.next().transpose()? {
            let key_size = key.len() as u64;
            let value_size = value.len() as u64;
            database_stats.number_of_entries += 1;
            database_stats.total_key_size += key_size;
            database_stats.total_value_size += value_size;
            database_stats.max_key_size = database_stats.max_key_size.max(key_size);
            database_stats.max_value_size = database_stats.max_value_size.max(value_size);
            database_stats.min_key_size = database_stats.min_key_size.min(key_size);
            database_stats.min_value_size = database_stats.min_value_size.min(value_size);
        }

        if database_stats.number_of_entries == 0 {
            database_stats.min_key_size = 0;
            database_stats.min_value_size = 0;
        }

        Ok(database_stats)
    }

    pub fn average_key_size(&self) -> u64 {
        if self.total_key_size == 0 {
            0
        } else {
            self.total_key_size / self.number_of_entries
        }
    }

    pub fn average_value_size(&self) -> u64 {
        if self.total_value_size == 0 {
            0
        } else {
            self.total_value_size / self.number_of_entries
        }
    }

    pub fn number_of_entries(&self) -> u64 {
        self.number_of_entries
    }

    pub fn total_key_size(&self) -> u64 {
        self.total_key_size
    }

    pub fn total_value_size(&self) -> u64 {
        self.total_value_size
    }

    pub fn max_key_size(&self) -> u64 {
        self.max_key_size
    }

Review comment (suggestion):
```suggestion
        if self.number_of_entries== 0 {
            0
        } else {
            self.total_key_size / self.number_of_entries
        }
```

In theory, it doesn’t change anything, but I feel like in practice and over time it may save us to actually do the check against the divider instead of the dividend

Code after:
        mut stats: Self,
        database: Database<Bytes, Bytes>,
        before_rtxn: &RoTxn<'_>,
        after_rtxn: &RoTxn<'_>,
        modified_keys: I,
    ) -> heed::Result<Self>
    where
        I: IntoIterator<Item = K>,
        K: AsRef<[u8]>,
    {
        for key in modified_keys {
            let key = key.as_ref();
            if let Some(value) = database.get(after_rtxn, key)? {
                let key_size = key.len() as u64;
                let value_size = value.len() as u64;
                stats.total_key_size = stats.total_key_size.saturating_add(key_size);
                stats.total_value_size = stats.total_value_size.saturating_add(value_size);
            }

            if let Some(value) = database.get(before_rtxn, key)? {
                let key_size = key.len() as u64;
                let value_size = value.len() as u64;
                stats.total_key_size = stats.total_key_size.saturating_sub(key_size);
                stats.total_value_size = stats.total_value_size.saturating_sub(value_size);
            }
        }

        stats.number_of_entries = database.len(after_rtxn)?;

        Ok(stats)
    }

    pub fn average_key_size(&self) -> u64 {
        self.total_key_size.checked_div(self.number_of_entries).unwrap_or(0)
    }

    pub fn average_value_size(&self) -> u64 {
        self.total_value_size.checked_div(self.number_of_entries).unwrap_or(0)
    }

    pub fn number_of_entries(&self) -> u64 {
        self.number_of_entries
    }

    pub fn total_key_size(&self) -> u64 {
        self.total_key_size
    }

    pub fn total_value_size(&self) -> u64 {
        self.total_value_size
    }