Refactor and improve
This commit is contained in:
parent
1f148b2185
commit
242acff987
22 changed files with 754 additions and 1053 deletions
|
|
@ -2,15 +2,31 @@ use std::sync::Arc;
|
|||
|
||||
use axum::extract::Query;
|
||||
use axum::http::StatusCode;
|
||||
use axum::response::{IntoResponse, Json};
|
||||
use axum::response::Json;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::info;
|
||||
|
||||
use crate::consts::MAX_POIS_PER_REQUEST;
|
||||
use crate::state::{AppState, POICategoryGroup};
|
||||
use crate::data::POICategoryGroup;
|
||||
use crate::parsing::parse_bounds;
|
||||
use crate::state::AppState;
|
||||
|
||||
use super::hexagons::write_json_escaped;
|
||||
use super::parse::parse_bounds;
|
||||
#[derive(Serialize)]
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
pub struct POI {
|
||||
id: String,
|
||||
name: String,
|
||||
category: String,
|
||||
group: String,
|
||||
lat: f32,
|
||||
lng: f32,
|
||||
emoji: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct POIsResponse {
|
||||
pois: Vec<POI>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct POIParams {
|
||||
|
|
@ -22,7 +38,7 @@ pub struct POIParams {
|
|||
pub async fn get_pois(
|
||||
state: Arc<AppState>,
|
||||
Query(params): Query<POIParams>,
|
||||
) -> Result<impl IntoResponse, (StatusCode, String)> {
|
||||
) -> Result<Json<POIsResponse>, (StatusCode, String)> {
|
||||
let bounds_str = params.bounds.ok_or((
|
||||
StatusCode::BAD_REQUEST,
|
||||
"bounds parameter is required".into(),
|
||||
|
|
@ -43,12 +59,10 @@ pub async fn get_pois(
|
|||
|
||||
let num_categories = category_filter.as_ref().map(|cats| cats.len()).unwrap_or(0);
|
||||
|
||||
let json_body = tokio::task::spawn_blocking(move || {
|
||||
let pois = tokio::task::spawn_blocking(move || {
|
||||
let t0 = std::time::Instant::now();
|
||||
let row_indices = state.poi_grid.query(south, west, north, east);
|
||||
|
||||
// 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| {
|
||||
|
|
@ -73,36 +87,22 @@ pub async fn get_pois(
|
|||
}
|
||||
}
|
||||
|
||||
// Write JSON directly to string buffer, avoiding intermediate POI allocations
|
||||
let mut buf = String::with_capacity(matching_rows.len() * 128);
|
||||
buf.push_str("{\"pois\":[");
|
||||
|
||||
for (i, &row) in matching_rows.iter().enumerate() {
|
||||
if i > 0 {
|
||||
buf.push(',');
|
||||
}
|
||||
buf.push_str("{\"id\":\"");
|
||||
write_json_escaped(&mut buf, &state.poi_data.id[row]);
|
||||
buf.push_str("\",\"name\":\"");
|
||||
write_json_escaped(&mut buf, &state.poi_data.name[row]);
|
||||
buf.push_str("\",\"category\":\"");
|
||||
write_json_escaped(&mut buf, state.poi_data.category.get(row));
|
||||
buf.push_str("\",\"group\":\"");
|
||||
write_json_escaped(&mut buf, state.poi_data.group.get(row));
|
||||
buf.push_str("\",\"lat\":");
|
||||
buf.push_str(&state.poi_data.lat[row].to_string());
|
||||
buf.push_str(",\"lng\":");
|
||||
buf.push_str(&state.poi_data.lng[row].to_string());
|
||||
buf.push_str(",\"emoji\":\"");
|
||||
write_json_escaped(&mut buf, state.poi_data.emoji.get(row));
|
||||
buf.push_str("\"}");
|
||||
}
|
||||
|
||||
buf.push_str("]}");
|
||||
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.get(row).to_string(),
|
||||
group: state.poi_data.group.get(row).to_string(),
|
||||
lat: state.poi_data.lat[row],
|
||||
lng: state.poi_data.lng[row],
|
||||
emoji: state.poi_data.emoji.get(row).to_string(),
|
||||
})
|
||||
.collect();
|
||||
|
||||
let elapsed = t0.elapsed();
|
||||
info!(
|
||||
results = matching_rows.len(),
|
||||
results = pois.len(),
|
||||
candidates = row_indices.len(),
|
||||
categories = num_categories,
|
||||
categories_raw = categories_str.as_deref().unwrap_or("-"),
|
||||
|
|
@ -110,12 +110,12 @@ pub async fn get_pois(
|
|||
"GET /api/pois"
|
||||
);
|
||||
|
||||
buf
|
||||
pois
|
||||
})
|
||||
.await
|
||||
.map_err(|error| (StatusCode::INTERNAL_SERVER_ERROR, error.to_string()))?;
|
||||
|
||||
Ok(([("content-type", "application/json")], json_body))
|
||||
Ok(Json(POIsResponse { pois }))
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue