Refactoring de pmoflac -factorisation de code ogg et opus
This commit is contained in:
@@ -35,13 +35,13 @@ impl PlaylistCore {
|
||||
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 {
|
||||
@@ -49,14 +49,13 @@ impl PlaylistCore {
|
||||
}
|
||||
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)
|
||||
});
|
||||
|
||||
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 {
|
||||
@@ -64,45 +63,45 @@ impl PlaylistCore {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// 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;
|
||||
|
||||
@@ -51,49 +51,50 @@ impl Playlist {
|
||||
writer_lock: RwLock::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Vérifie si la playlist est active
|
||||
pub fn is_alive(&self) -> bool {
|
||||
PlaylistState::from(self.state.load(Ordering::SeqCst)) == PlaylistState::Active
|
||||
}
|
||||
|
||||
|
||||
/// Marque la playlist comme supprimée
|
||||
pub fn mark_deleted(&self) {
|
||||
self.state.store(PlaylistState::Deleted as u8, Ordering::SeqCst);
|
||||
self.state
|
||||
.store(PlaylistState::Deleted as u8, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
|
||||
/// Met à jour le timestamp de dernière modification
|
||||
pub async fn touch(&self) {
|
||||
*self.last_change.write().await = SystemTime::now();
|
||||
}
|
||||
|
||||
|
||||
/// Récupère le titre
|
||||
pub async fn title(&self) -> String {
|
||||
self.title.read().await.clone()
|
||||
}
|
||||
|
||||
|
||||
/// Change le titre
|
||||
pub async fn set_title(&self, title: String) {
|
||||
*self.title.write().await = title;
|
||||
self.touch().await;
|
||||
}
|
||||
|
||||
|
||||
/// Timestamp du dernier changement
|
||||
pub async fn last_change(&self) -> SystemTime {
|
||||
*self.last_change.read().await
|
||||
}
|
||||
|
||||
|
||||
/// Tente d'acquérir le write lock
|
||||
pub async fn acquire_write_lock(&self) -> Result<Arc<()>, ()> {
|
||||
let mut guard = self.writer_lock.write().await;
|
||||
|
||||
|
||||
// Vérifier si un writer existe déjà
|
||||
if let Some(weak) = guard.as_ref() {
|
||||
if weak.strong_count() > 0 {
|
||||
return Err(()); // Lock déjà pris
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Créer un nouveau token
|
||||
let token = Arc::new(());
|
||||
*guard = Some(Arc::downgrade(&token));
|
||||
|
||||
@@ -10,10 +10,10 @@ use std::time::{Duration, SystemTime};
|
||||
pub struct Record {
|
||||
/// Clé primaire dans pmoaudiocache
|
||||
pub cache_pk: String,
|
||||
|
||||
|
||||
/// Timestamp d'ajout à la playlist (en nanosecondes depuis epoch)
|
||||
pub added_at: SystemTime,
|
||||
|
||||
|
||||
/// Durée de vie optionnelle (surcharge le TTL par défaut)
|
||||
pub ttl: Option<Duration>,
|
||||
}
|
||||
@@ -27,7 +27,7 @@ impl Record {
|
||||
ttl: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Crée un record avec un TTL personnalisé
|
||||
pub fn with_ttl(cache_pk: String, ttl: Duration) -> Self {
|
||||
Self {
|
||||
@@ -36,12 +36,12 @@ impl Record {
|
||||
ttl: Some(ttl),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Vérifie si le record est expiré
|
||||
pub fn is_expired(&self, default_ttl: Option<Duration>) -> bool {
|
||||
let now = SystemTime::now();
|
||||
let age = now.duration_since(self.added_at).unwrap_or_default();
|
||||
|
||||
|
||||
if let Some(ttl) = self.ttl {
|
||||
age >= ttl
|
||||
} else if let Some(default_ttl) = default_ttl {
|
||||
@@ -50,7 +50,7 @@ impl Record {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Retourne le timestamp en nanosecondes depuis epoch
|
||||
pub fn added_at_nanos(&self) -> i64 {
|
||||
self.added_at
|
||||
|
||||
Reference in New Issue
Block a user