Files
pmomusic/pmoplaylist/src/playlist/core.rs

112 lines
2.9 KiB
Rust
Raw Normal View History

2025-10-27 12:32:31 +01:00
//! PlaylistCore : structure FIFO avec éviction automatique
use super::record::Record;
use std::collections::VecDeque;
use std::sync::Arc;
use std::time::Duration;
/// Configuration d'une playlist
#[derive(Debug, Clone)]
pub struct PlaylistConfig {
pub max_size: Option<usize>,
pub default_ttl: Option<Duration>,
}
impl Default for PlaylistConfig {
fn default() -> Self {
Self {
max_size: None,
default_ttl: None,
}
}
}
/// Noyau de la playlist (structure interne protégée par RwLock)
pub struct PlaylistCore {
pub tracks: VecDeque<Arc<Record>>,
pub config: PlaylistConfig,
}
impl PlaylistCore {
/// Crée un nouveau core
pub fn new(config: PlaylistConfig) -> Self {
Self {
tracks: VecDeque::new(),
config,
}
}
/// Ajoute un record et applique l'éviction
pub fn push(&mut self, record: Record) {
self.tracks.push_back(Arc::new(record));
self.evict();
}
/// Ajoute plusieurs records de manière atomique
pub fn push_all(&mut self, records: Vec<Record>) {
for record in records {
self.tracks.push_back(Arc::new(record));
}
self.evict();
}
/// Nettoie les morceaux expirés et applique la limite de taille
pub fn evict(&mut self) {
// 1. Supprimer les morceaux périmés par TTL
self.tracks.retain(|record| {
!record.is_expired(self.config.default_ttl)
});
// 2. Appliquer la limite de taille (FIFO)
if let Some(max) = self.config.max_size {
while self.tracks.len() > max {
self.tracks.pop_front();
}
}
}
/// Vide complètement la playlist
pub fn clear(&mut self) {
self.tracks.clear();
}
/// Nombre de morceaux
pub fn len(&self) -> usize {
self.tracks.len()
}
/// Vérifie si la playlist est vide
pub fn is_empty(&self) -> bool {
self.tracks.is_empty()
}
/// Récupère un record par index
pub fn get(&self, index: usize) -> Option<Arc<Record>> {
self.tracks.get(index).cloned()
}
/// Snapshot de tous les records
pub fn snapshot(&self) -> Vec<Arc<Record>> {
self.tracks.iter().cloned().collect()
}
/// Supprime un record par cache_pk (retourne true si supprimé)
pub fn remove_by_cache_pk(&mut self, cache_pk: &str) -> bool {
let initial_len = self.tracks.len();
self.tracks.retain(|r| r.cache_pk != cache_pk);
self.tracks.len() != initial_len
}
/// Met à jour la capacité maximale
pub fn set_capacity(&mut self, max_size: Option<usize>) {
self.config.max_size = max_size;
self.evict();
}
/// Met à jour le TTL par défaut
pub fn set_default_ttl(&mut self, ttl: Option<Duration>) {
self.config.default_ttl = ttl;
self.evict();
}
}