Skip to content

Commit f768f13

Browse files
committed
refactor(gdal): streamline dataset creation in GdalPool and RasterSource
1 parent a8625eb commit f768f13

3 files changed

Lines changed: 24 additions & 35 deletions

File tree

versatiles_pipeline/src/operations/read/from_gdal/dem/dem_source.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ use super::{GdalPool, Instance, ResampleAlg, get_spatial_ref};
22
use anyhow::{Context, Result, bail, ensure};
33
use gdal::{Dataset, DriverManager, GeoTransform};
44
use imageproc::image::{DynamicImage, RgbImage};
5-
use std::path::Path;
6-
#[cfg(test)]
7-
use std::sync::Arc;
5+
use std::{path::Path, sync::Arc};
86
use versatiles_core::GeoBBox;
97
use versatiles_derive::context;
108

@@ -124,18 +122,19 @@ unsafe impl Sync for DemSource {}
124122
impl DemSource {
125123
#[context("Failed to create DemSource from file {:?}", filename)]
126124
pub async fn new(filename: &Path, reuse_limit: u32, concurrency_limit: usize) -> Result<DemSource> {
127-
let pool = GdalPool::new(filename, reuse_limit, concurrency_limit).await?;
128-
Ok(DemSource { pool })
125+
let path = filename.to_path_buf();
126+
let factory: Arc<dyn Fn() -> Result<Dataset> + Send + Sync + 'static> =
127+
Arc::new(move || Dataset::open(&path).with_context(|| format!("failed to open GDAL dataset: {path:?}")));
128+
Self::new_with_factory(factory, reuse_limit, concurrency_limit).await
129129
}
130130

131-
#[cfg(test)]
132131
#[context("Failed to create DemSource via factory")]
133132
pub async fn new_with_factory(
134133
open_dataset: Arc<dyn Fn() -> Result<Dataset> + Send + Sync + 'static>,
135134
reuse_limit: u32,
136135
concurrency_limit: usize,
137136
) -> Result<DemSource> {
138-
let pool = GdalPool::new_with_factory(open_dataset, reuse_limit, concurrency_limit).await?;
137+
let (pool, _) = GdalPool::new_with_factory(open_dataset, reuse_limit, concurrency_limit).await?;
139138
Ok(DemSource { pool })
140139
}
141140

versatiles_pipeline/src/operations/read/from_gdal/gdal_pool.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::Instance;
22
use anyhow::{Result, ensure};
33
use deadpool::managed::{Manager, Object, Pool, RecycleResult};
44
use gdal::{Dataset, config::set_config_option};
5-
use std::{ops::Deref, path::Path, sync::Arc};
5+
use std::{ops::Deref, sync::Arc};
66
use versatiles_core::{GeoBBox, WORLD_SIZE, utils::float_to_int};
77
use versatiles_derive::context;
88

@@ -56,22 +56,17 @@ pub struct GdalPool {
5656
unsafe impl Sync for GdalPool {}
5757

5858
impl GdalPool {
59-
/// Create a `GdalPool` from a file path.
60-
#[context("Failed to create GDAL dataset from file {:?}", filename)]
61-
pub async fn new(filename: &Path, reuse_limit: u32, concurrency_limit: usize) -> Result<GdalPool> {
62-
let path = filename.to_path_buf();
63-
let factory: Arc<dyn Fn() -> Result<Dataset> + Send + Sync + 'static> =
64-
Arc::new(move || Dataset::open(&path).with_context(|| format!("failed to open GDAL dataset: {path:?}")));
65-
Self::new_with_factory(factory, reuse_limit, concurrency_limit).await
66-
}
67-
6859
/// Create a `GdalPool` from a factory that opens a fresh GDAL `Dataset` on demand.
60+
///
61+
/// Returns the pool together with a probe `Dataset` that was opened during
62+
/// construction. Callers can inspect this dataset for additional metadata
63+
/// (e.g. band mapping) without going through the pool.
6964
#[context("Failed to create GDAL dataset via factory")]
7065
pub async fn new_with_factory(
7166
open_dataset: Arc<dyn Fn() -> Result<Dataset> + Send + Sync + 'static>,
7267
reuse_limit: u32,
7368
concurrency_limit: usize,
74-
) -> Result<GdalPool> {
69+
) -> Result<(GdalPool, Dataset)> {
7570
set_config_option("GDAL_NUM_THREADS", "ALL_CPUS")?;
7671
log::trace!("GDAL_NUM_THREADS set to ALL_CPUS");
7772

@@ -89,6 +84,10 @@ impl GdalPool {
8984
log::trace!("Dataset pixel_size (m/px): {pixel_size:.6}");
9085
log::trace!("Dataset bbox (EPSG:4326): {bbox:?}");
9186

87+
// Open a second probe dataset for callers to inspect
88+
// (the first one was consumed by Instance::new above).
89+
let probe = (open_dataset)()?;
90+
9291
// Create deadpool manager and pool - single synchronization point!
9392
let manager = GdalManager {
9493
open_dataset,
@@ -100,7 +99,7 @@ impl GdalPool {
10099
.build()
101100
.context("failed to build deadpool")?;
102101

103-
Ok(GdalPool { pool, bbox, pixel_size })
102+
Ok((GdalPool { pool, bbox, pixel_size }, probe))
104103
}
105104

106105
/// Get an instance from the pool.

versatiles_pipeline/src/operations/read/from_gdal/raster/raster_source.rs

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -92,32 +92,23 @@ impl RasterSource {
9292
/// Create a `RasterSource` from a file path.
9393
#[context("Failed to create RasterSource from file {:?}", filename)]
9494
pub async fn new(filename: &Path, reuse_limit: u32, concurrency_limit: usize) -> Result<RasterSource> {
95-
let pool = GdalPool::new(filename, reuse_limit, concurrency_limit).await?;
96-
97-
// Probe band mapping from one instance
98-
let instance = pool.get_instance().await?;
99-
let band_mapping = BandMapping::try_from(instance.dataset())?;
100-
log::trace!("Band mapping: {band_mapping:?}");
101-
102-
Ok(RasterSource {
103-
pool,
104-
band_mapping: Arc::new(band_mapping),
105-
})
95+
let path = filename.to_path_buf();
96+
let factory: Arc<dyn Fn() -> Result<gdal::Dataset> + Send + Sync + 'static> =
97+
Arc::new(move || gdal::Dataset::open(&path).with_context(|| format!("failed to open GDAL dataset: {path:?}")));
98+
Self::new_with_factory(factory, reuse_limit, concurrency_limit).await
10699
}
107100

108101
/// Create a `RasterSource` from a factory that opens a fresh GDAL `Dataset` on demand.
109-
#[cfg(test)]
110102
#[context("Failed to create RasterSource via factory")]
111103
pub async fn new_with_factory(
112104
open_dataset: Arc<dyn Fn() -> Result<gdal::Dataset> + Send + Sync + 'static>,
113105
reuse_limit: u32,
114106
concurrency_limit: usize,
115107
) -> Result<RasterSource> {
116-
let pool = GdalPool::new_with_factory(open_dataset, reuse_limit, concurrency_limit).await?;
108+
let (pool, probe) = GdalPool::new_with_factory(open_dataset, reuse_limit, concurrency_limit).await?;
117109

118-
// Probe band mapping from one instance
119-
let instance = pool.get_instance().await?;
120-
let band_mapping = BandMapping::try_from(instance.dataset())?;
110+
// Probe band mapping from the probe dataset
111+
let band_mapping = BandMapping::try_from(&probe)?;
121112
log::trace!("Band mapping: {band_mapping:?}");
122113

123114
Ok(RasterSource {

0 commit comments

Comments
 (0)