Implemented a pixbuf cache mechanism.

Since gdk_pixbuf::Pixbuf is refference counted and every episode,
use the cover of the Podcast Feed/Show, We can only create a Pixbuf
cover per show and pass around the Rc pointer.

GObjects do not implement Send trait, so SendCell is a way around that.
Also lazy_static requires Sync trait, so that's what the mutexes are.
This commit is contained in:
Jordan Petridis 2017-12-21 17:36:07 +02:00
parent 74a6e5814a
commit e416bca963
No known key found for this signature in database
GPG Key ID: CEABAD9F5683B9A6
5 changed files with 42 additions and 1 deletions

8
Cargo.lock generated
View File

@ -611,11 +611,13 @@ dependencies = [
"gtk 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hammond-data 0.1.0",
"hammond-downloader 0.1.0",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"loggerv 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"send-cell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1280,6 +1282,11 @@ dependencies = [
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "send-cell"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.24"
@ -1746,6 +1753,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f412dfa83308d893101dd59c10d6fda8283465976c28c287c5c855bf8d216bc"
"checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332"
"checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead"
"checksum send-cell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c620dd7e056b468b9d374a9f51cfa6bb4bf17a8ca4ee62e5efa0d99aaff2c41"
"checksum serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "1c57ab4ec5fa85d08aaf8ed9245899d9bbdd66768945b21113b84d5f595cb6a1"
"checksum serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7cf5b0b5b4bd22eeecb7e01ac2e1225c7ef5e4272b79ee28a8392a8c8489c839"
"checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480"

View File

@ -513,6 +513,11 @@ impl From<Podcast> for PodcastCoverQuery {
}
impl PodcastCoverQuery {
/// Get the Feed `id`.
pub fn id(&self) -> i32 {
self.id
}
/// Get the Feed `title`.
pub fn title(&self) -> &str {
&self.title

View File

@ -12,11 +12,13 @@ gdk = "0.7.0"
gdk-pixbuf = "0.3.0"
gio = "0.3.0"
glib = "0.4.0"
lazy_static = "1.0.0"
log = "0.3.8"
loggerv = "0.6.0"
open = "1.2.1"
rayon = "0.9.0"
regex = "0.2.3"
send-cell = "0.1.2"
[dependencies.diesel]
features = ["sqlite"]

View File

@ -12,10 +12,13 @@ extern crate dissolve;
extern crate hammond_data;
extern crate hammond_downloader;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate loggerv;
extern crate open;
extern crate regex;
extern crate send_cell;
// extern crate rayon;
// use rayon::prelude::*;

View File

@ -1,3 +1,4 @@
use send_cell::SendCell;
use glib;
use gdk_pixbuf::Pixbuf;
@ -8,7 +9,9 @@ use hammond_downloader::downloader;
use std::thread;
use std::cell::RefCell;
use std::sync::mpsc::{channel, Receiver};
use std::sync::Mutex;
use std::rc::Rc;
use std::collections::HashMap;
use content::Content;
@ -59,10 +62,30 @@ fn refresh_podcasts_view() -> glib::Continue {
glib::Continue(false)
}
lazy_static! {
static ref CACHED_PIXBUFS: Mutex<HashMap<(i32, u32), Mutex<SendCell<Pixbuf>>>> = {
Mutex::new(HashMap::new())
};
}
// FIXME: use something that would just scale?
pub fn get_pixbuf_from_path(pd: &PodcastCoverQuery, size: u32) -> Option<Pixbuf> {
let mut hashmap = CACHED_PIXBUFS.lock().unwrap();
{
let res = hashmap.get(&(pd.id(), size));
if let Some(px) = res {
let m = px.lock().unwrap();
return Some(m.clone().into_inner());
}
}
let img_path = downloader::cache_image(pd)?;
Pixbuf::new_from_file_at_scale(&img_path, size as i32, size as i32, true).ok()
let px = Pixbuf::new_from_file_at_scale(&img_path, size as i32, size as i32, true).ok();
if let Some(px) = px {
hashmap.insert((pd.id(), size), Mutex::new(SendCell::new(px.clone())));
return Some(px);
}
None
}
#[cfg(test)]