diff --git a/src/dem.rs b/src/dem.rs index 33c1906..16ed4e9 100644 --- a/src/dem.rs +++ b/src/dem.rs @@ -14,15 +14,16 @@ use gdal::Dataset; use gdal; use tracing_subscriber::registry::Data; -use crate::{SharedState}; +use crate::{DSC}; struct Pos { lat: f64, lon: f64, } -struct MyDataset(OnceCell); -pub unsafe impl Send for MyDataset{} +pub struct MyDataset{pub ds: Dataset} +unsafe impl Send for MyDataset{} +unsafe impl Sync for MyDataset{} #[derive(Default)] pub struct DatasetCache { @@ -42,7 +43,7 @@ impl DatasetCache { if !self.hm.contains_key(&filename){ let ds = Dataset::open(filename.clone()).unwrap(); - self.hm.insert(filename.clone(), MyDataset(OnceCell::new(ds))); + self.hm.insert(filename.clone(), MyDataset{ds: ds}); } @@ -87,7 +88,7 @@ fn geo_to_pixel(dataset: &Dataset, lat: f64, lon: f64) -> Result<(isize, isize), Ok((x_pixel, y_pixel)) } -pub async fn elevation_from_coordinates(dsc: SharedState, lat: f64, lon: f64) -> f64 { +pub async fn elevation_from_coordinates(dsc: DSC, lat: f64, lon: f64) -> f64 { let file = get_filename_from_latlon(lat, lon); let full_filename = format!("data/{file}"); @@ -102,8 +103,15 @@ pub async fn elevation_from_coordinates(dsc: SharedState, lat: f64, lon: f64) -> // ds = dd; // //ds = cache.await.get_dataset_for_filename(full_filename); //} - let x = dsc.get_dataset_for_filename(full_filename); - let ds = x.0.read().unwrap(); + //let x = dsc.get_dataset_for_filename(full_filename); + + if !dsc.contains_key(&full_filename) { + println!(">>> WILL GET {full_filename} because not in cache!"); + let ds = Arc::new(MyDataset{ds:Dataset::open(full_filename.clone()).unwrap()}); + dsc.insert(full_filename.clone(), ds).await; + } + + let ds = &dsc.get(&full_filename).await.unwrap().ds; //let ds = dsc.get_dataset_for_filename(full_filename); diff --git a/src/main.rs b/src/main.rs index e121f1a..379e5fa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,31 +9,39 @@ use axum_macros::debug_handler; use axum::{ body::Bytes, extract::{Path, State}, http::StatusCode, routing::{get, post}, Json, Router }; -use dem::DatasetCache; +use dem::{DatasetCache, MyDataset}; use gdal::Dataset; +use moka::future::Cache; -pub type SharedState = Arc; //#[derive(Default)] //struct AppState { // db: RwLock>, //} +type DSC = Cache>; + #[tokio::main(flavor = "current_thread")] async fn main() { // initialize tracing tracing_subscriber::fmt::init(); - let data_set_cache = SharedState::default(); //Arc::new(RwLock::new(dem::DatasetCache::new())); + // Evict based on the number of entries in the cache. + let cache = Cache::builder() + // Up to 10,000 entries. + .max_capacity(10_000) + // Create the cache. + .build(); + //cache.insert("hello".to_string(), Arc::new(dem::MyDataset{ds: Dataset::open("oueou").unwrap()})).await; // build our application with a route let app = Router::new() // `GET /` goes to `root` .route("/", get(root)) .route("/elevation/:lat/:lon", get(get_elevation)) - .with_state(Arc::clone(&data_set_cache)); + .with_state(cache); // run our app with hyper, listening globally on port 3000 let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); @@ -48,7 +56,7 @@ async fn root() -> &'static str { //async fn get_elevation(State(data_set_cache): State>>, Path((lat, lon)): Path<(f64, f64)>) -> String{ #[debug_handler] -async fn get_elevation(State(shared): State, Path((lat, lon)): Path<(f64, f64)>) -> String{ +async fn get_elevation(State(shared): State, Path((lat, lon)): Path<(f64, f64)>) -> String{ // let x = AppState::default(); // x.db.get("hello");