use std::collections::HashMap;
use std::hash::{DefaultHasher, Hash, Hasher};
use serde::{Deserialize, Serialize};
pub type SeriesId = u64;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct SeriesKey {
pub metric: String,
pub tags: Vec<(String, String)>,
}
impl SeriesKey {
pub fn new(metric: impl Into<String>, mut tags: Vec<(String, String)>) -> Self {
tags.sort();
Self {
metric: metric.into(),
tags,
}
}
pub fn to_series_id(&self, salt: u64) -> SeriesId {
let mut hasher = DefaultHasher::new();
salt.hash(&mut hasher);
self.metric.hash(&mut hasher);
for (k, v) in &self.tags {
k.hash(&mut hasher);
v.hash(&mut hasher);
}
hasher.finish()
}
}
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct SeriesCatalog {
entries: HashMap<SeriesId, (SeriesKey, u64)>,
}
impl SeriesCatalog {
pub fn new() -> Self {
Self::default()
}
pub fn resolve(&mut self, key: &SeriesKey) -> SeriesId {
let mut salt = 0u64;
loop {
let id = key.to_series_id(salt);
match self.entries.get(&id) {
None => {
self.entries.insert(id, (key.clone(), salt));
return id;
}
Some((existing_key, _)) if existing_key == key => {
return id;
}
Some(_) => {
salt += 1;
}
}
}
}
pub fn get(&self, id: SeriesId) -> Option<&SeriesKey> {
self.entries.get(&id).map(|(k, _)| k)
}
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
}
pub type LiteId = String;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum BatteryState {
Normal,
Low,
Charging,
#[default]
Unknown,
}
impl BatteryState {
pub fn should_defer_flush(&self) -> bool {
matches!(self, Self::Low)
}
}