1use crate::error::Result;
2use bytes::Bytes;
3use async_trait::async_trait;
4use std::collections::HashMap;
5use std::sync::Arc;
6use tokio::sync::RwLock;
7
8#[async_trait]
10pub trait ChunkStore: Send + Sync {
11 async fn get(&self, index: usize, offset: usize, length: usize) -> Result<Bytes>;
13
14 async fn put(&self, index: usize, data: Bytes) -> Result<()>;
16
17 async fn close(&self) -> Result<()>;
19
20 async fn destroy(&self) -> Result<()>;
22}
23
24pub struct MemoryChunkStore {
26 pieces: Arc<RwLock<HashMap<usize, Bytes>>>,
27}
28
29impl MemoryChunkStore {
30 pub fn new() -> Self {
31 Self {
32 pieces: Arc::new(RwLock::new(HashMap::new())),
33 }
34 }
35}
36
37#[async_trait]
38impl ChunkStore for MemoryChunkStore {
39 async fn get(&self, index: usize, offset: usize, length: usize) -> Result<Bytes> {
40 let pieces = self.pieces.read().await;
41 if let Some(piece) = pieces.get(&index) {
42 let end = (offset + length).min(piece.len());
43 Ok(piece.slice(offset..end))
44 } else {
45 Err(crate::error::WebTorrentError::Store(
46 format!("Piece {} not found", index),
47 ))
48 }
49 }
50
51 async fn put(&self, index: usize, data: Bytes) -> Result<()> {
52 let mut pieces = self.pieces.write().await;
53 pieces.insert(index, data);
54 Ok(())
55 }
56
57 async fn close(&self) -> Result<()> {
58 Ok(())
59 }
60
61 async fn destroy(&self) -> Result<()> {
62 let mut pieces = self.pieces.write().await;
63 pieces.clear();
64 Ok(())
65 }
66}
67