Compare commits

...

3 Commits

Author SHA1 Message Date
363e94aa28 Update dependencies and fix linter warnings 2024-08-10 23:14:51 +02:00
09cdd3d569 Update dependencies 2020-07-28 10:19:20 +02:00
5af7d8cb4b Switch to iterators 2020-07-28 10:18:38 +02:00
3 changed files with 104 additions and 94 deletions

View File

@@ -19,12 +19,11 @@ license = "MIT"
include = ["Cargo.toml", "README.md", "LICENSE", "ACKNOWLEDGEMENTS", "src/**/*.rs"] include = ["Cargo.toml", "README.md", "LICENSE", "ACKNOWLEDGEMENTS", "src/**/*.rs"]
[dependencies] [dependencies]
ironsea_index = "^0.1" ironsea_index = "0.1"
#ironsea_store = "^0.1"
arrayref = "^0.3" arrayref = "0.3"
#log = { version = "^0.4", features = ["max_level_trace", "release_max_level_info"] } #log = { version = "0.4", features = ["max_level_trace", "release_max_level_info"] }
log = { version = "^0.4", features = ["max_level_trace", "release_max_level_trace"] } log = { version = "0.4", features = ["max_level_trace", "release_max_level_trace"] }
serde = { version = "^1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
bincode = "^1.1" bincode = "1.3"

View File

@@ -171,7 +171,7 @@ impl<'de> Deserialize<'de> for MortonEncoder {
enum Field { enum Field {
CellBits, CellBits,
Dimensions, Dimensions,
}; }
impl<'de> Deserialize<'de> for Field { impl<'de> Deserialize<'de> for Field {
fn deserialize<D>(deserializer: D) -> Result<Field, D::Error> fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>

View File

@@ -28,13 +28,13 @@ type SFCOffset = u32;
// type-num crate? // type-num crate?
const MAX_K: usize = 3; const MAX_K: usize = 3;
#[derive(Debug)] #[derive(Clone, Debug)]
struct Limit<V> { struct Limit<V> {
idx: usize, idx: usize,
position: Vec<V>, position: Vec<V>,
} }
#[derive(Debug)] #[derive(Clone, Debug)]
struct Limits<'a, V> { struct Limits<'a, V> {
start: Limit<&'a V>, start: Limit<&'a V>,
end: Limit<&'a V>, end: Limit<&'a V>,
@@ -154,19 +154,25 @@ where
/// Returns a vector of keys which have stored values in the index /// Returns a vector of keys which have stored values in the index
/// equal to `value`. /// equal to `value`.
pub fn find_by_value(&self, value: &F) -> Vec<K> { pub fn find_by_value<'s>(&'s self, value: &'s F) -> Box<dyn Iterator<Item = K> + 's> {
let mut results = vec![]; Box::new(
for cell in &self.index { self.index
for record in &cell.records { .iter()
if &record.fields == value { .map(|cell| (cell, cell.records.iter()))
if let Ok(key) = self.position(cell.code, &record.offsets) { .flat_map(move |(cell, records)| {
results.push(key); records.filter_map(move |record| {
} if &record.fields == value {
} if let Ok(key) = self.position(cell.code, &record.offsets) {
} Some(key)
} } else {
None
results }
} else {
None
}
})
}),
)
} }
// Map the cell_ids of a point to its SFCcode // Map the cell_ids of a point to its SFCcode
@@ -184,14 +190,14 @@ where
} }
fn value(&self, code: SFCCode, offsets: &[SFCOffset]) -> Result<Vec<&V>, String> { fn value(&self, code: SFCCode, offsets: &[SFCOffset]) -> Result<Vec<&V>, String> {
Ok(self.space.value( self.space.value(
self.morton self.morton
.decode(code) .decode(code)
.iter() .iter()
.map(|e| *e as usize) .map(|e| *e as usize)
.collect(), .collect(),
offsets.iter().map(|e| *e as usize).collect(), offsets.iter().map(|e| *e as usize).collect(),
)?) )
} }
// Build coordinate values from encoded value // Build coordinate values from encoded value
@@ -249,95 +255,100 @@ where
K: Debug + FromIterator<V> + Index<usize, Output = V>, K: Debug + FromIterator<V> + Index<usize, Output = V>,
V: Clone + Debug + From<usize> + Hash + Ord, V: Clone + Debug + From<usize> + Hash + Ord,
{ {
fn find(&self, key: &K) -> Vec<&F> { fn find<'i>(&'i self, key: &K) -> Box<dyn Iterator<Item = &F> + 'i> {
let mut values = vec![];
if let Ok((cell_ids, offsets)) = self.space.key(key) { if let Ok((cell_ids, offsets)) = self.space.key(key) {
match self.encode(&cell_ids) { match self.encode(&cell_ids) {
Err(e) => error!("{}", e), Err(e) => error!("{}", e),
Ok(code) => { Ok(code) => {
if let Ok(cell) = self.index.binary_search_by(|a| a.code.cmp(&code)) { if let Ok(cell) = self.index.binary_search_by(|a| a.code.cmp(&code)) {
for record in &self.index[cell].records { return Box::new(self.index[cell].records.iter().filter_map(
let mut select = true; move |record| {
for (k, o) in offsets.iter().enumerate().take(self.dimensions) { let mut select = true;
select &= record.offsets[k] == (*o as SFCOffset); for (k, o) in offsets.iter().enumerate().take(self.dimensions) {
} select &= record.offsets[k] == (*o as SFCOffset);
}
if select { if select {
values.push(&record.fields); Some(&record.fields)
} } else {
} None
}
},
));
} }
} }
} }
} }
values Box::new(Vec::with_capacity(0).into_iter())
} }
fn find_range(&self, start: &K, end: &K) -> Vec<(K, &F)> { fn find_range<'i>(&'i self, start: &K, end: &K) -> Box<dyn Iterator<Item = (K, &F)> + 'i> {
let mut values = vec![];
match self.limits(start, end) { match self.limits(start, end) {
Ok(limits) => { Ok(limits) => {
for idx in limits.start.idx..limits.end.idx { let iter = (limits.start.idx..limits.end.idx)
let code = self.index[idx].code; .filter_map(move |idx| {
match self.value(self.index[idx].code, &self.index[idx].records[0].offsets)
let first = match self.value(code, &self.index[idx].records[0].offsets) { {
Err(e) => { Err(_) => None,
error!("Cannot retrieve first value of cell: {}", e); Ok(first) => Some((idx, first)),
continue;
} }
Ok(r) => r, })
}; .filter_map(move |(idx, first)| {
let (cell_ids, last_offsets) = self.last();
let (cell_ids, last_offsets) = self.last(); match self.space.value(cell_ids, last_offsets) {
let last = match self.space.value(cell_ids, last_offsets) { Err(_) => None,
Err(e) => { Ok(last) => Some((idx, first, last)),
error!("Cannot retrieve last value of cell: {}", e);
continue;
} }
Ok(r) => r, })
}; .flat_map(move |(idx, first, last)| {
// Check first & last point of the cell, if both are fully
// Check first & last point of the cell, if both are fully // in the bounding box, then all the points of the cell will
// in the bounding box, then all the points of the cell will // be.
// be. let limits = limits.clone();
if limits.start.position <= first let b: Box<dyn Iterator<Item = _>> = if limits.start.position <= first
&& first <= limits.end.position && first <= limits.end.position
&& limits.start.position <= last && limits.start.position <= last
&& last <= limits.end.position && last <= limits.end.position
{ {
for record in &self.index[idx].records { Box::new(self.index[idx].records.iter().filter_map(move |record| {
if let Ok(key) = self.position(code, &record.offsets) { let code = self.index[idx].code;
values.push((key, &record.fields));
}
}
} else {
// We have points which are outside of the bounding box,
// so check every points one by one.
for record in &self.index[idx].records {
let pos = match self.value(code, &record.offsets) {
Err(e) => {
error!("{}", e);
continue;
}
Ok(r) => r,
};
if limits.start.position <= pos && pos <= limits.end.position {
if let Ok(key) = self.position(code, &record.offsets) { if let Ok(key) = self.position(code, &record.offsets) {
values.push((key, &record.fields)); Some((key, &record.fields))
} else {
None
} }
} }))
} } else {
} // We have points which are outside of the bounding box,
} // so check every points one by one.
} Box::new(self.index[idx].records.iter().filter_map(move |record| {
Err(e) => error!("find_range: limits failed: {}", e), let code = self.index[idx].code;
}; if let Ok(pos) = self.value(code, &record.offsets) {
if limits.start.position <= pos && pos <= limits.end.position {
if let Ok(key) = self.position(code, &record.offsets) {
Some((key, &record.fields))
} else {
None
}
} else {
None
}
} else {
None
}
}))
};
values b
});
Box::new(iter)
}
Err(e) => {
error!("find_range: limits failed: {}", e);
Box::new(Vec::with_capacity(0).into_iter())
}
}
} }
} }