net: De-GC the image cache stuff.

This is a step on the way toward parallel layout.
This commit is contained in:
Patrick Walton 2013-11-26 12:10:40 -08:00
parent 7eb4097dc9
commit c85953deeb
3 changed files with 61 additions and 57 deletions

View file

@ -48,22 +48,13 @@ pub enum Msg {
Exit(Chan<()>),
}
#[deriving(Clone)]
pub enum ImageResponseMsg {
ImageReady(Arc<~Image>),
ImageNotReady,
ImageFailed
}
impl ImageResponseMsg {
fn clone(&self) -> ImageResponseMsg {
match *self {
ImageReady(ref img) => ImageReady(img.clone()),
ImageNotReady => ImageNotReady,
ImageFailed => ImageFailed,
}
}
}
impl Eq for ImageResponseMsg {
fn eq(&self, other: &ImageResponseMsg) -> bool {
// FIXME: Bad copies
@ -243,11 +234,11 @@ impl ImageCache {
}
}
fn set_state(&self, url: Url, state: ImageState) {
fn set_state(&mut self, url: Url, state: ImageState) {
self.state_map.insert(url, state);
}
fn prefetch(&self, url: Url) {
fn prefetch(&mut self, url: Url) {
match self.get_state(url.clone()) {
Init => {
let to_cache = self.chan.clone();
@ -278,7 +269,7 @@ impl ImageCache {
}
}
fn store_prefetched_image_data(&self, url: Url, data: Result<Cell<~[u8]>, ()>) {
fn store_prefetched_image_data(&mut self, url: Url, data: Result<Cell<~[u8]>, ()>) {
match self.get_state(url.clone()) {
Prefetching(next_step) => {
match data {
@ -307,7 +298,7 @@ impl ImageCache {
}
}
fn decode(&self, url: Url) {
fn decode(&mut self, url: Url) {
match self.get_state(url.clone()) {
Init => fail!(~"decoding image before prefetch"),
@ -350,7 +341,7 @@ impl ImageCache {
}
}
fn store_image(&self, url: Url, image: Option<Arc<~Image>>) {
fn store_image(&mut self, url: Url, image: Option<Arc<~Image>>) {
match self.get_state(url.clone()) {
Decoding => {
@ -377,7 +368,7 @@ impl ImageCache {
}
fn purge_waiters(&self, url: Url, f: &fn() -> ImageResponseMsg) {
fn purge_waiters(&mut self, url: Url, f: &fn() -> ImageResponseMsg) {
match self.wait_map.pop(&url) {
Some(waiters) => {
for response in waiters.iter() {
@ -399,7 +390,7 @@ impl ImageCache {
}
}
fn wait_for_image(&self, url: Url, response: Chan<ImageResponseMsg>) {
fn wait_for_image(&mut self, url: Url, response: Chan<ImageResponseMsg>) {
match self.get_state(url.clone()) {
Init => fail!(~"request for image before prefetch"),

View file

@ -34,9 +34,10 @@ pub struct LocalImageCache {
priv image_cache_task: ImageCacheTask,
priv round_number: uint,
priv on_image_available: Option<~ImageResponder:Send>,
priv state_map: UrlMap<@mut ImageState>
priv state_map: UrlMap<ImageState>
}
#[deriving(Clone)]
struct ImageState {
prefetched: bool,
decoded: bool,
@ -52,24 +53,34 @@ impl LocalImageCache {
self.on_image_available = Some(on_image_available);
}
pub fn prefetch(&self, url: &Url) {
pub fn prefetch(&mut self, url: &Url) {
{
let state = self.get_state(url);
if !state.prefetched {
self.image_cache_task.send(Prefetch((*url).clone()));
state.prefetched = true;
}
if state.prefetched {
return
}
pub fn decode(&self, url: &Url) {
state.prefetched = true;
}
self.image_cache_task.send(Prefetch((*url).clone()));
}
pub fn decode(&mut self, url: &Url) {
{
let state = self.get_state(url);
if !state.decoded {
self.image_cache_task.send(Decode((*url).clone()));
if state.decoded {
return
}
state.decoded = true;
}
self.image_cache_task.send(Decode((*url).clone()));
}
// FIXME: Should return a Future
pub fn get_image(&self, url: &Url) -> Port<ImageResponseMsg> {
pub fn get_image(&mut self, url: &Url) -> Port<ImageResponseMsg> {
{
let state = self.get_state(url);
// Save the previous round number for comparison
@ -99,6 +110,7 @@ impl LocalImageCache {
return port;
}
}
}
let (response_port, response_chan) = comm::stream();
self.image_cache_task.send(GetImage((*url).clone(), response_chan));
@ -130,24 +142,24 @@ impl LocalImageCache {
ImageNotReady => ImageNotReady,
ImageFailed => ImageFailed
};
state.last_response = response_copy;
self.get_state(url).last_response = response_copy;
let (port, chan) = comm::stream();
chan.send(response);
return port;
}
fn get_state(&self, url: &Url) -> @mut ImageState {
let state = do self.state_map.find_or_insert_with(url.clone()) |_| {
let new_state = @mut ImageState {
fn get_state<'a>(&'a mut self, url: &Url) -> &'a mut ImageState {
let state = self.state_map.find_or_insert_with(url.clone(), |_| {
let new_state = ImageState {
prefetched: false,
decoded: false,
last_request_round: 0,
last_response: ImageNotReady
};
new_state
};
*state // Unborrowing the state
});
state
}
}

View file

@ -147,8 +147,9 @@ mod make_url_tests {
}
pub type UrlMap<T> = @mut HashMap<Url, T>;
pub type UrlMap<T> = HashMap<Url, T>;
pub fn url_map<T: Clone + 'static>() -> UrlMap<T> {
@mut HashMap::new()
HashMap::new()
}