Checkpoint all changes
This commit is contained in:
parent
65877acf95
commit
66c2a25457
28 changed files with 3035 additions and 621 deletions
|
|
@ -39,37 +39,56 @@ pub async fn get_pois(
|
|||
let category_filter: Option<rustc_hash::FxHashSet<String>> = params
|
||||
.categories
|
||||
.as_deref()
|
||||
.filter(|s| !s.is_empty())
|
||||
.map(|s| s.split(',').map(|c| c.trim().to_string()).collect());
|
||||
.filter(|text| !text.is_empty())
|
||||
.map(|text| text.split(',').map(|part| part.trim().to_string()).collect());
|
||||
|
||||
let num_categories = category_filter.as_ref().map(|c| c.len()).unwrap_or(0);
|
||||
let num_categories = category_filter.as_ref().map(|cats| cats.len()).unwrap_or(0);
|
||||
|
||||
let result = tokio::task::spawn_blocking(move || {
|
||||
let t0 = std::time::Instant::now();
|
||||
let row_indices = state.poi_grid.query(south, west, north, east);
|
||||
|
||||
let pois: Vec<POI> = row_indices
|
||||
// Collect matching row indices first, then sample randomly so the
|
||||
// subset covers the viewport uniformly instead of clustering in one area.
|
||||
let mut matching_rows: Vec<usize> = row_indices
|
||||
.iter()
|
||||
.filter_map(|&row_idx| {
|
||||
let row = row_idx as usize;
|
||||
|
||||
if let Some(ref categories) = category_filter {
|
||||
if !categories.contains(&state.poi_data.category[row]) {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
Some(POI {
|
||||
id: state.poi_data.id[row].clone(),
|
||||
name: state.poi_data.name[row].clone(),
|
||||
category: state.poi_data.category[row].clone(),
|
||||
group: state.poi_data.group[row].clone(),
|
||||
lat: state.poi_data.lat[row],
|
||||
lng: state.poi_data.lng[row],
|
||||
emoji: state.poi_data.emoji[row].clone(),
|
||||
})
|
||||
Some(row)
|
||||
})
|
||||
.collect();
|
||||
|
||||
if matching_rows.len() > MAX_POIS_PER_REQUEST {
|
||||
// Use a power-of-2 sampling step so each POI's inclusion depends
|
||||
// only on its own priority hash, not on what other POIs are in
|
||||
// the viewport. This prevents visible reshuffling when panning.
|
||||
let ratio = (matching_rows.len() / MAX_POIS_PER_REQUEST) as u32;
|
||||
let step = ratio.next_power_of_two();
|
||||
let mask = step - 1;
|
||||
matching_rows.retain(|&row| state.poi_data.priority[row] & mask == 0);
|
||||
// Statistical noise may leave us slightly over the limit
|
||||
if matching_rows.len() > MAX_POIS_PER_REQUEST {
|
||||
matching_rows.sort_unstable_by_key(|&row| state.poi_data.priority[row]);
|
||||
matching_rows.truncate(MAX_POIS_PER_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
let pois: Vec<POI> = matching_rows
|
||||
.iter()
|
||||
.map(|&row| POI {
|
||||
id: state.poi_data.id[row].clone(),
|
||||
name: state.poi_data.name[row].clone(),
|
||||
category: state.poi_data.category[row].clone(),
|
||||
group: state.poi_data.group[row].clone(),
|
||||
lat: state.poi_data.lat[row],
|
||||
lng: state.poi_data.lng[row],
|
||||
emoji: state.poi_data.emoji[row].clone(),
|
||||
})
|
||||
.take(MAX_POIS_PER_REQUEST)
|
||||
.collect();
|
||||
|
||||
let elapsed = t0.elapsed();
|
||||
|
|
@ -85,7 +104,7 @@ pub async fn get_pois(
|
|||
POIsResponse { pois }
|
||||
})
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
||||
.map_err(|error| (StatusCode::INTERNAL_SERVER_ERROR, error.to_string()))?;
|
||||
|
||||
Ok(Json(result))
|
||||
}
|
||||
|
|
@ -98,7 +117,7 @@ pub struct POICategoriesResponse {
|
|||
pub async fn get_poi_categories(state: Arc<AppState>) -> Json<POICategoriesResponse> {
|
||||
let groups: Vec<POICategoryGroup> = state.poi_category_groups.clone();
|
||||
|
||||
let total: usize = groups.iter().map(|g| g.categories.len()).sum();
|
||||
let total: usize = groups.iter().map(|group| group.categories.len()).sum();
|
||||
info!(
|
||||
count = total,
|
||||
groups = groups.len(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue