Skip to content

Commit da49d4f

Browse files
retrieve field index only once
1 parent 9817c31 commit da49d4f

File tree

1 file changed

+57
-24
lines changed
  • operators/src/source/ogr_source

1 file changed

+57
-24
lines changed

operators/src/source/ogr_source/mod.rs

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use crate::engine::{
55
CanonicOperatorName, OperatorData, OperatorName, QueryProcessor, WorkflowOperatorPath,
66
};
77
use crate::error::Error;
8-
use crate::util::Result;
98
use crate::util::input::StringOrNumberRange;
9+
use crate::util::{Result, safe_lock_mutex};
1010
use crate::{
1111
engine::{
1212
InitializedVectorOperator, MetaData, QueryContext, SourceOperator,
@@ -560,7 +560,7 @@ where
560560
}
561561
}
562562

563-
type TimeExtractorType = Box<dyn Fn(&Feature) -> Result<TimeInterval> + Send + Sync + 'static>;
563+
type TimeExtractorType = Box<dyn FnMut(&Feature) -> Result<TimeInterval> + Send + Sync + 'static>;
564564

565565
#[pin_project(project = OgrSourceStreamProjection)]
566566
pub struct OgrSourceStream<G>
@@ -571,7 +571,7 @@ where
571571
dataset_iterator: Arc<Mutex<OgrDatasetIterator>>,
572572
data_types: Arc<HashMap<String, FeatureDataType>>,
573573
feature_collection_builder: FeatureCollectionBuilder<G>,
574-
time_extractor: Arc<TimeExtractorType>,
574+
time_extractor: Arc<std::sync::Mutex<TimeExtractorType>>,
575575
time_attribute_parser:
576576
Arc<Box<dyn Fn(FieldValue) -> Result<TimeInstance> + Send + Sync + 'static>>,
577577
query_rectangle: VectorQueryRectangle,
@@ -849,7 +849,7 @@ where
849849
data_types: Arc::new(data_types),
850850
feature_collection_builder,
851851
query_rectangle,
852-
time_extractor: Arc::new(time_extractor),
852+
time_extractor: Arc::new(std::sync::Mutex::new(time_extractor)),
853853
time_attribute_parser: Arc::new(time_attribute_parser),
854854
chunk_byte_size,
855855
future: None,
@@ -867,7 +867,7 @@ where
867867
feature_collection_builder: FeatureCollectionBuilder<G>,
868868
data_types: Arc<HashMap<String, FeatureDataType>>,
869869
query_rectangle: VectorQueryRectangle,
870-
time_extractor: Arc<TimeExtractorType>,
870+
time_extractor: Arc<std::sync::Mutex<TimeExtractorType>>,
871871
time_attribute_parser: Arc<Box<dyn Fn(FieldValue) -> Result<TimeInstance> + Send + Sync>>,
872872
chunk_byte_size: usize,
873873
) -> Result<FeatureCollection<G>> {
@@ -880,7 +880,7 @@ where
880880
&dataset_information,
881881
&data_types,
882882
&query_rectangle,
883-
time_extractor.as_ref(),
883+
safe_lock_mutex(&time_extractor).as_mut(),
884884
time_attribute_parser.as_ref(),
885885
chunk_byte_size,
886886
);
@@ -975,10 +975,12 @@ where
975975
} => {
976976
let time_start_parser = Self::create_time_parser(start_format);
977977

978+
let mut field_index = None;
978979
Box::new(move |feature: &Feature| {
979-
let field_value = feature
980-
.field_index(&start_field)
981-
.and_then(|i| feature.field(i))?;
980+
let field_index =
981+
get_or_insert_field_index(&mut field_index, feature, &start_field)?;
982+
983+
let field_value = feature.field(field_index)?;
982984
if let Some(field_value) = field_value {
983985
let time_start = time_start_parser(field_value)?;
984986
TimeInterval::new(time_start, (time_start + duration)?).map_err(Into::into)
@@ -997,13 +999,17 @@ where
997999
let time_start_parser = Self::create_time_parser(start_format);
9981000
let time_end_parser = Self::create_time_parser(end_format);
9991001

1002+
let mut start_field_index = None;
1003+
let mut end_field_index = None;
1004+
10001005
Box::new(move |feature: &Feature| {
1001-
let start_field_value = feature
1002-
.field_index(&start_field)
1003-
.and_then(|i| feature.field(i))?;
1004-
let end_field_value = feature
1005-
.field_index(&end_field)
1006-
.and_then(|i| feature.field(i))?;
1006+
let start_field_index =
1007+
get_or_insert_field_index(&mut start_field_index, feature, &start_field)?;
1008+
let end_field_index =
1009+
get_or_insert_field_index(&mut end_field_index, feature, &end_field)?;
1010+
1011+
let start_field_value = feature.field(start_field_index)?;
1012+
let end_field_value = feature.field(end_field_index)?;
10071013

10081014
if let (Some(start_field_value), Some(end_field_value)) =
10091015
(start_field_value, end_field_value)
@@ -1025,13 +1031,20 @@ where
10251031
} => {
10261032
let time_start_parser = Self::create_time_parser(start_format);
10271033

1034+
let mut start_field_index = None;
1035+
let mut duration_field_index = None;
1036+
10281037
Box::new(move |feature: &Feature| {
1029-
let start_field_value = feature
1030-
.field_index(&start_field)
1031-
.and_then(|i| feature.field(i))?;
1032-
let duration_field_value = feature
1033-
.field_index(&duration_field)
1034-
.and_then(|i| feature.field(i))?;
1038+
let start_field_index =
1039+
get_or_insert_field_index(&mut start_field_index, feature, &start_field)?;
1040+
let duration_field_index = get_or_insert_field_index(
1041+
&mut duration_field_index,
1042+
feature,
1043+
&duration_field,
1044+
)?;
1045+
1046+
let start_field_value = feature.field(start_field_index)?;
1047+
let duration_field_value = feature.field(duration_field_index)?;
10351048

10361049
if let (Some(start_field_value), Some(duration_field_value)) =
10371050
(start_field_value, duration_field_value)
@@ -1110,7 +1123,7 @@ where
11101123
dataset_information: &OgrSourceDataset,
11111124
data_types: &HashMap<String, FeatureDataType>,
11121125
query_rectangle: &VectorQueryRectangle,
1113-
time_extractor: &dyn Fn(&Feature) -> Result<TimeInterval>,
1126+
time_extractor: &mut dyn FnMut(&Feature) -> Result<TimeInterval>,
11141127
time_attribute_parser: &dyn Fn(FieldValue) -> Result<TimeInstance>,
11151128
chunk_byte_size: usize,
11161129
) -> Result<FeatureCollection<G>> {
@@ -1265,7 +1278,7 @@ where
12651278
default_geometry: &Option<G>,
12661279
data_types: &HashMap<String, FeatureDataType>,
12671280
query_rectangle: &VectorQueryRectangle,
1268-
time_extractor: &dyn Fn(&Feature) -> Result<TimeInterval, Error>,
1281+
time_extractor: &mut dyn FnMut(&Feature) -> Result<TimeInterval, Error>,
12691282
time_attribute_parser: &dyn Fn(FieldValue) -> Result<TimeInstance>,
12701283
builder: &mut FeatureCollectionRowBuilder<G>,
12711284
feature: &Feature,
@@ -1306,8 +1319,14 @@ where
13061319
builder.push_generic_geometry(geometry);
13071320
builder.push_time_interval(time_interval);
13081321

1322+
let mut field_indices = HashMap::with_capacity(data_types.len());
1323+
13091324
for (column, data_type) in data_types {
1310-
let field = feature.field_index(column).and_then(|i| feature.field(i));
1325+
let field_index = field_indices
1326+
.entry(column.as_str())
1327+
.or_insert_with(|| feature.field_index(column));
1328+
1329+
let field = field_index.clone().and_then(|i| feature.field(i));
13111330
let value =
13121331
Self::convert_field_value(*data_type, field, time_attribute_parser, error_spec)?;
13131332
builder.push_data(column, value)?;
@@ -1319,6 +1338,20 @@ where
13191338
}
13201339
}
13211340

1341+
fn get_or_insert_field_index(
1342+
field_index: &mut Option<usize>,
1343+
feature: &Feature,
1344+
field_name: &str,
1345+
) -> Result<usize> {
1346+
if let Some(i) = field_index {
1347+
return Ok(*i);
1348+
}
1349+
1350+
let i = feature.field_index(field_name)?;
1351+
*field_index = Some(i);
1352+
Ok(i)
1353+
}
1354+
13221355
impl<G> Stream for OgrSourceStream<G>
13231356
where
13241357
G: Geometry + ArrowTyped + 'static + std::marker::Unpin + TryFromOgrGeometry,

0 commit comments

Comments
 (0)