use std::time::{SystemTime, UNIX_EPOCH};
use thiserror::Error;
use crate::registry::CollectionId;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum CompressionProfile {
None,
Dictionary,
#[default]
Balanced,
Compact,
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct CollectionConfig {
pub compression: CompressionProfile,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Collection {
name: String,
id: CollectionId,
created_at: u64,
compression: CompressionProfile,
doc_count: u64,
}
impl Collection {
#[must_use]
pub fn new(name: String, id: CollectionId, config: CollectionConfig) -> Self {
Self {
name,
id,
created_at: current_unix_seconds(),
compression: config.compression,
doc_count: 0,
}
}
#[must_use]
pub fn name(&self) -> &str {
&self.name
}
#[must_use]
pub fn id(&self) -> CollectionId {
self.id
}
#[must_use]
pub fn created_at(&self) -> u64 {
self.created_at
}
#[must_use]
pub fn compression(&self) -> CompressionProfile {
self.compression
}
#[must_use]
pub fn doc_count(&self) -> u64 {
self.doc_count
}
pub fn increment_doc_count(&mut self) {
self.doc_count = self.doc_count.saturating_add(1);
}
pub fn decrement_doc_count(&mut self) {
self.doc_count = self.doc_count.saturating_sub(1);
}
}
#[derive(Debug, Error, PartialEq, Eq)]
pub enum CollectionError {
#[error("collection '{0}' already exists")]
AlreadyExists(String),
}
fn current_unix_seconds() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map_or(0, |duration| duration.as_secs())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn collection_doc_count_tracks_mutations() {
let mut collection = Collection::new(
"users".to_string(),
7,
CollectionConfig {
compression: CompressionProfile::Dictionary,
},
);
assert_eq!(collection.doc_count(), 0);
collection.increment_doc_count();
collection.increment_doc_count();
assert_eq!(collection.doc_count(), 2);
collection.decrement_doc_count();
assert_eq!(collection.doc_count(), 1);
collection.decrement_doc_count();
collection.decrement_doc_count();
assert_eq!(collection.doc_count(), 0);
assert_eq!(collection.name(), "users");
assert_eq!(collection.id(), 7);
assert_eq!(collection.compression(), CompressionProfile::Dictionary);
}
}