diff --git a/src/core/src/app.rs b/src/core/src/app.rs index 84153472..1988ac70 100644 --- a/src/core/src/app.rs +++ b/src/core/src/app.rs @@ -542,7 +542,7 @@ where self.request_redraw = true; } } else { - //al_core::log("discard tex sub"); + self.downloader.cache_rsc(Resource::Tile(tile)); } num_tile_received += 1; } diff --git a/src/core/src/downloader/mod.rs b/src/core/src/downloader/mod.rs index 855245c3..d1343c13 100644 --- a/src/core/src/downloader/mod.rs +++ b/src/core/src/downloader/mod.rs @@ -443,26 +443,34 @@ impl TileDownloader { }*/ }*/ -use crate::{survey::Url}; - +use crate::survey::Url; use std::collections::HashSet; pub struct Downloader { // Current requests requests: Vec, queried_urls: HashSet, + + cache: Cache, + queried_cached_urls: HashSet, } +use crate::fifo_cache::Cache; + use query::Query; use request::{RequestType, Resource}; + impl Downloader { pub fn new() -> Downloader { let requests = Vec::with_capacity(32); let queried_urls = HashSet::with_capacity(64); - + let cache = Cache::new(); + let queried_cached_urls = HashSet::with_capacity(64); Self { requests, queried_urls, + cache, + queried_cached_urls } } @@ -476,66 +484,28 @@ impl Downloader { //self.tiles_to_req.clear(); let url = query.url(); - let not_already_requested = !self.queried_urls.contains(url); + if self.cache.contains(url) { + self.queried_cached_urls.insert(url.to_string()); + false + } else { + let not_already_requested = !self.queried_urls.contains(url); - // The cell is not already requested - if not_already_requested || force_request { - /*if tile.is_root() { - self.base_tiles_to_req.push(tile); - } else { - self.tiles_to_req.push(tile); - }*/ - self.queried_urls.insert(url.to_string()); - - let request = T::Request::from(query); - self.requests.push(request.into()); - } - - not_already_requested - } - - /*pub fn try_sending_tile_requests(&mut self, surveys: &ImageSurveys) -> Result<(), JsValue> { - // Try sending the fits tile requests - let mut is_remaining_req = - !self.tiles_to_req.is_empty() || !self.base_tiles_to_req.is_empty(); - - let mut downloader_overloaded = false; - - while is_remaining_req && !downloader_overloaded { - let mut base_tile_requested = false; - let tile = if let Some(base_tile) = self.base_tiles_to_req.last() { - base_tile_requested = true; - base_tile - } else { - self.tiles_to_req.last().unwrap() - }; - //let tile = self.tiles_to_req.last(); - - if let Some(available_req) = self.requests.check_send(tile.format.clone()) { - let tile = if base_tile_requested { - // Send in priority requests to get the base tiles - self.base_tiles_to_req.pop().unwrap() + // The cell is not already requested + if not_already_requested || force_request { + /*if tile.is_root() { + self.base_tiles_to_req.push(tile); } else { - // Otherwise requests the other tiles - self.tiles_to_req.pop().unwrap() - }; - //let tile = self.tiles_to_req.pop().unwrap(); - - is_remaining_req = - !self.tiles_to_req.is_empty() || !self.base_tiles_to_req.is_empty(); - //is_remaining_req = !self.tiles_to_req.is_empty(); - self.requested_tiles.insert(tile.clone()); - - available_req.fetch(&tile, surveys)?; - } else { - // We have to wait for more requests - // to be available - downloader_overloaded = true; + self.tiles_to_req.push(tile); + }*/ + self.queried_urls.insert(url.to_string()); + + let request = T::Request::from(query); + self.requests.push(request.into()); } + + not_already_requested } - - Ok(()) - }*/ + } pub fn get_received_resources(&mut self) -> Vec { let mut rscs = vec![]; @@ -562,6 +532,17 @@ impl Downloader { self.queried_urls.remove(&url); } + for url in self.queried_cached_urls.iter() { + let rsc = self.cache.extract(url).unwrap(); + rscs.push(rsc); + } + + self.queried_cached_urls.clear(); + rscs } + + pub fn cache_rsc(&mut self, rsc: Resource) { + self.cache.insert(rsc.url().clone(), rsc); + } } diff --git a/src/core/src/downloader/request/blank.rs b/src/core/src/downloader/request/blank.rs index f2ac179f..6dd360de 100644 --- a/src/core/src/downloader/request/blank.rs +++ b/src/core/src/downloader/request/blank.rs @@ -149,6 +149,7 @@ impl From for PixelMetadataRequest { pub struct PixelMetadata { pub value: Metadata, pub hips_url: String, + pub url: String, } impl<'a> From<&'a PixelMetadataRequest> for Option { @@ -156,7 +157,7 @@ impl<'a> From<&'a PixelMetadataRequest> for Option { let PixelMetadataRequest { request, hips_url, - .. + url, } = request; if request.is_resolved() { let Request:: { @@ -166,7 +167,8 @@ impl<'a> From<&'a PixelMetadataRequest> for Option { // It will always be resolved and found as we will request a well know tile (Norder0/Tile0) Some(PixelMetadata { hips_url: hips_url.clone(), - value: data.lock().unwrap().unwrap().clone() + url: url.to_string(), + value: data.lock().unwrap().unwrap().clone(), }) } else { None diff --git a/src/core/src/downloader/request/mod.rs b/src/core/src/downloader/request/mod.rs index 1c3acde1..84f3e73d 100644 --- a/src/core/src/downloader/request/mod.rs +++ b/src/core/src/downloader/request/mod.rs @@ -122,3 +122,13 @@ pub enum Resource { Allsky(Allsky), PixelMetadata(PixelMetadata) } + +impl Resource { + pub fn url(&self) -> &Url { + match self { + Resource::Tile(tile) => tile.get_url(), + Resource::Allsky(allsky) => allsky.get_url(), + Resource::PixelMetadata(PixelMetadata { url, ..}) => url, + } + } +} diff --git a/src/core/src/fifo_cache.rs b/src/core/src/fifo_cache.rs new file mode 100644 index 00000000..7d328076 --- /dev/null +++ b/src/core/src/fifo_cache.rs @@ -0,0 +1,41 @@ +use std::collections::{HashMap, VecDeque}; + +pub struct Cache { + data: HashMap, + order: VecDeque, +} + +const SIZE_RESOURCE_CACHE: usize = 256; + +use std::hash::Hash; +impl Cache +where + K: Clone + std::cmp::Eq + Hash +{ + pub fn new() -> Self { + let data = HashMap::with_capacity(SIZE_RESOURCE_CACHE); + let order = VecDeque::with_capacity(SIZE_RESOURCE_CACHE); + Cache { + data, + order + } + } + + pub fn insert(&mut self, key: K, val: V) { + if self.order.len() == SIZE_RESOURCE_CACHE { + let k = self.order.pop_front().unwrap(); + self.data.remove(&k); + } + + self.data.insert(key.clone(), val); + self.order.push_back(key); + } + + pub fn extract(&mut self, key: &K) -> Option { + self.data.remove(key) + } + + pub fn contains(&self, key: &K) -> bool { + self.data.contains_key(key) + } +} \ No newline at end of file diff --git a/src/core/src/lib.rs b/src/core/src/lib.rs index 3a70735f..e4622846 100644 --- a/src/core/src/lib.rs +++ b/src/core/src/lib.rs @@ -43,6 +43,7 @@ mod shader; mod survey; mod tile_fetcher; mod time; +mod fifo_cache; use crate::{ camera::CameraViewPort, colormap::Colormaps, math::lonlat::LonLatT, shader::ShaderManager, time::DeltaTime, diff --git a/src/core/src/survey/mod.rs b/src/core/src/survey/mod.rs index 23eb5532..1bd868ba 100644 --- a/src/core/src/survey/mod.rs +++ b/src/core/src/survey/mod.rs @@ -338,7 +338,6 @@ pub fn get_raytracer_shader<'a, P: Projection>( //const MAX_NUM_CELLS_TO_DRAW: usize = 768; use cgmath::{Vector3, Vector4}; use render::rasterizer::uv::{TileCorner, TileUVW}; -use al_api::coo_system::CooSystem; //#[cfg(feature = "webgl1")] fn add_vertices_grid( cell: &HEALPixCell, @@ -1061,19 +1060,6 @@ impl ImageSurveys { } } - pub fn last(&self) -> Option<&ImageSurvey> { - if let Some(last_rendered_layer) = self.layers.last() { - let url = self - .urls - .get(last_rendered_layer) - .expect("Url from layer name not found."); - - self.surveys.get(url) - } else { - None - } - } - pub fn reset_frame(&mut self) { for survey in self.surveys.values_mut() { survey.reset_frame(); diff --git a/src/core/src/utils.rs b/src/core/src/utils.rs index ac82c976..5d0f9eaa 100644 --- a/src/core/src/utils.rs +++ b/src/core/src/utils.rs @@ -34,4 +34,4 @@ pub unsafe fn transmute_boxed_slice(s: Box<[I]>) -> Box<[O]> { let out_slice_ptr = std::slice::from_raw_parts_mut(in_slice_ptr as *mut O, new_len); Box::from_raw(out_slice_ptr) -} +} \ No newline at end of file