perf: make daemon more memory efficient
Use Box<str> instead of String in daemon. Because we don't need to change names of timers in the daemon this is way more memory efficient.
This commit is contained in:
parent
853e735fcd
commit
b3885f80dd
3 changed files with 20 additions and 30 deletions
|
@ -11,8 +11,8 @@ use std::{
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
Add(String, Duration),
|
Add(Box<str>, Duration),
|
||||||
Remove(String),
|
Remove(Box<str>),
|
||||||
List,
|
List,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,12 +42,11 @@ impl Display for Answer {
|
||||||
#[derive(Debug, thiserror::Error, Serialize, Deserialize)]
|
#[derive(Debug, thiserror::Error, Serialize, Deserialize)]
|
||||||
pub enum AnswerErr {
|
pub enum AnswerErr {
|
||||||
#[error("Timer with name '{}' already exists", .0)]
|
#[error("Timer with name '{}' already exists", .0)]
|
||||||
TimerAlreadyExist(String),
|
TimerAlreadyExist(Box<str>),
|
||||||
#[error("No timer with the name '{}' exists", .0)]
|
#[error("No timer with the name '{}' exists", .0)]
|
||||||
NoSuchTimer(String),
|
NoSuchTimer(Box<str>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub struct Daemon {
|
pub struct Daemon {
|
||||||
listener: UnixListener,
|
listener: UnixListener,
|
||||||
timers: Vec<Timer>,
|
timers: Vec<Timer>,
|
||||||
|
@ -68,14 +67,14 @@ impl Daemon {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_timer(&mut self, name: &String) -> bool {
|
fn has_timer(&mut self, name: &str) -> bool {
|
||||||
self.timers.iter().any(|other| &other.name == name)
|
self.timers.iter().any(|other| other.name.as_ref() == name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_command(&mut self, command: Command) -> Result<Answer, AnswerErr> {
|
fn handle_command(&mut self, command: Command) -> Result<Answer, AnswerErr> {
|
||||||
println!("Received command {:?}", command);
|
println!("Received command {:?}", command);
|
||||||
match command {
|
match command {
|
||||||
Command::List => Ok(Answer::Timers(self.timers.to_vec())),
|
Command::List => Ok(Answer::Timers(self.timers.clone())),
|
||||||
Command::Add(name, duration) => {
|
Command::Add(name, duration) => {
|
||||||
if self.has_timer(&name) {
|
if self.has_timer(&name) {
|
||||||
return Err(AnswerErr::TimerAlreadyExist(name));
|
return Err(AnswerErr::TimerAlreadyExist(name));
|
||||||
|
@ -88,12 +87,8 @@ impl Daemon {
|
||||||
if !self.has_timer(&name) {
|
if !self.has_timer(&name) {
|
||||||
return Err(AnswerErr::NoSuchTimer(name));
|
return Err(AnswerErr::NoSuchTimer(name));
|
||||||
}
|
}
|
||||||
self.timers = self
|
self.timers
|
||||||
.timers
|
.retain(|other| other.name.as_ref() != name.as_ref());
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.filter(|other| other.name != name)
|
|
||||||
.collect();
|
|
||||||
Ok(Answer::Ok)
|
Ok(Answer::Ok)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,18 +103,13 @@ impl Daemon {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_timers(&mut self) {
|
fn check_timers(&mut self) {
|
||||||
self.timers = self
|
self.timers.retain(|timer| {
|
||||||
.timers
|
let expired = timer.is_expired();
|
||||||
.iter()
|
if expired {
|
||||||
.cloned()
|
println!("Timer {} is expired!", timer.name);
|
||||||
.filter(|timer| {
|
}
|
||||||
let expired = timer.is_expired();
|
!expired
|
||||||
if expired {
|
});
|
||||||
println!("Timer {} is expired!", timer.name);
|
|
||||||
}
|
|
||||||
!expired
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&mut self) -> anyhow::Result<()> {
|
pub fn run(&mut self) -> anyhow::Result<()> {
|
||||||
|
|
|
@ -16,9 +16,9 @@ fn main() -> Result<()> {
|
||||||
CliCommand::Add {
|
CliCommand::Add {
|
||||||
name,
|
name,
|
||||||
duration_seconds,
|
duration_seconds,
|
||||||
} => DaemonCommand::Add(name, Duration::from_secs(duration_seconds)),
|
} => DaemonCommand::Add(name.into_boxed_str(), Duration::from_secs(duration_seconds)),
|
||||||
CliCommand::List => DaemonCommand::List,
|
CliCommand::List => DaemonCommand::List,
|
||||||
CliCommand::Remove { name } => DaemonCommand::Remove(name),
|
CliCommand::Remove { name } => DaemonCommand::Remove(name.into_boxed_str()),
|
||||||
};
|
};
|
||||||
send_command(&args.socket, daemon_command)
|
send_command(&args.socket, daemon_command)
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ mod approx_instant {
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
|
||||||
pub struct Timer {
|
pub struct Timer {
|
||||||
pub name: String,
|
pub name: Box<str>,
|
||||||
#[serde(with = "approx_instant")]
|
#[serde(with = "approx_instant")]
|
||||||
start: Instant,
|
start: Instant,
|
||||||
duration: Duration,
|
duration: Duration,
|
||||||
|
@ -51,7 +51,7 @@ impl Display for Timer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Timer {
|
impl Timer {
|
||||||
pub fn new(name: String, duration: Duration) -> Timer {
|
pub fn new(name: Box<str>, duration: Duration) -> Timer {
|
||||||
Timer {
|
Timer {
|
||||||
name,
|
name,
|
||||||
start: Instant::now(),
|
start: Instant::now(),
|
||||||
|
|
Loading…
Reference in a new issue