Skip to content

Commit ef5926d

Browse files
committed
Add module file in database crate
1 parent 8ed525c commit ef5926d

1 file changed

Lines changed: 111 additions & 0 deletions

File tree

database/src/file.rs

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
use std::fs::File;
2+
use std::path::PathBuf;
3+
use std::io::Read;
4+
use std::collections::HashMap;
5+
use futures::Complete;
6+
7+
use crate::error::*;
8+
use crate::objects::TrackKey;
9+
10+
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
11+
pub struct Packet {
12+
pub id: TrackKey,
13+
pub body: PacketBody
14+
}
15+
16+
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
17+
pub enum PacketBody {
18+
AskForFile,
19+
HasFile(bool),
20+
GetFile(Option<Vec<u8>>)
21+
}
22+
23+
pub struct State {
24+
data_path: PathBuf,
25+
awaiting: HashMap<TrackKey, (usize, Complete<Result<(TrackKey, Vec<u8>)>>)>
26+
}
27+
28+
impl State {
29+
pub fn new(data_path: PathBuf) -> State {
30+
State {
31+
data_path,
32+
awaiting: HashMap::new()
33+
}
34+
}
35+
36+
fn get_file(&self, id: TrackKey) -> Option<Vec<u8>> {
37+
let mut file = File::open(self.data_path.join(&id.to_string())).ok()?;
38+
let mut content = vec![];
39+
file.read_to_end(&mut content).unwrap();
40+
41+
Some(content)
42+
}
43+
44+
fn has_file(&self, id: TrackKey) -> bool {
45+
self.data_path.join(&id.to_string()).exists()
46+
}
47+
48+
pub fn process(&mut self, packet: Packet) -> Option<Packet> {
49+
let Packet { id, body } = packet;
50+
51+
let inner = match body {
52+
PacketBody::AskForFile => {
53+
Some(PacketBody::HasFile(self.has_file(id)))
54+
},
55+
PacketBody::HasFile(has_file) => {
56+
57+
if has_file {
58+
if !self.has_file(id) {
59+
Some(PacketBody::GetFile(None))
60+
} else {
61+
None
62+
}
63+
} else {
64+
let mut ct = 0;
65+
if let Some(ref mut elm) = self.awaiting.get_mut(&id) {
66+
elm.0 -= 1;
67+
ct = elm.0;
68+
}
69+
70+
if ct == 0 {
71+
if let Some((_, shot)) = self.awaiting.remove(&id) {
72+
if let Err(err) = shot.send(Err(Error::SyncFailed("No peer had file available".into()))) {
73+
eprintln!("Oneshot err = {:?}", err);
74+
}
75+
76+
}
77+
}
78+
79+
None
80+
}
81+
},
82+
PacketBody::GetFile(file) => {
83+
match file {
84+
None => {
85+
Some(PacketBody::GetFile(self.get_file(id)))
86+
},
87+
Some(data) => {
88+
if let Some((_, shot)) = self.awaiting.remove(&id) {
89+
if let Err(err) = shot.send(Ok((id, data))) {
90+
eprintln!("Oneshot err = {:?}", err);
91+
}
92+
93+
}
94+
95+
None
96+
}
97+
}
98+
}
99+
};
100+
101+
inner.map(|x| Packet { id: id, body: x })
102+
}
103+
104+
pub fn add(&mut self, track_key: TrackKey, num_peers: usize, c: Complete<Result<(TrackKey, Vec<u8>)>>) {
105+
self.awaiting.insert(track_key, (num_peers, c));
106+
}
107+
108+
pub fn remove(&mut self, track_key: TrackKey) {
109+
self.awaiting.remove(&track_key);
110+
}
111+
}

0 commit comments

Comments
 (0)