2023-05-17 19:32:32 +00:00
|
|
|
use std::collections::HashMap;
|
2023-05-18 07:44:54 +00:00
|
|
|
use std::net::SocketAddr;
|
2023-05-17 19:32:32 +00:00
|
|
|
use std::sync::{Arc, Mutex};
|
2023-05-18 07:44:54 +00:00
|
|
|
use tokio::sync::mpsc;
|
|
|
|
|
use tracing::debug;
|
2023-05-17 19:32:32 +00:00
|
|
|
|
|
|
|
|
use crate::frame::ServerFrames;
|
|
|
|
|
|
2023-05-18 07:44:54 +00:00
|
|
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
|
|
|
|
|
pub(crate) struct DispatcherId(pub(crate) SocketAddr);
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
|
|
|
|
|
pub(crate) struct CameraId(pub(crate) SocketAddr);
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
|
|
|
|
|
pub(crate) struct Plate {
|
|
|
|
|
pub(crate) plate: String,
|
|
|
|
|
pub(crate) timestamp: u32,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
|
|
|
|
|
pub(crate) struct Camera {
|
|
|
|
|
pub(crate) road: u16,
|
|
|
|
|
pub(crate) mile: u16,
|
|
|
|
|
pub(crate) limit: u16,
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-17 19:32:32 +00:00
|
|
|
pub(crate) struct DbHolder {
|
|
|
|
|
/// The `Db` instance that will be shut down when this `DbHolder` struct
|
|
|
|
|
/// is dropped.
|
|
|
|
|
db: Db,
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-18 07:44:54 +00:00
|
|
|
#[derive(Clone)]
|
2023-05-17 19:32:32 +00:00
|
|
|
pub(crate) struct Db {
|
|
|
|
|
state: Arc<Mutex<State>>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
struct State {
|
2023-05-18 07:44:54 +00:00
|
|
|
cameras: HashMap<CameraId, Camera>,
|
|
|
|
|
dispatchers: HashMap<DispatcherId, (Vec<u16>, mpsc::Sender<ServerFrames>)>,
|
|
|
|
|
plates: HashMap<CameraId, Plate>,
|
2023-05-17 19:32:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl DbHolder {
|
|
|
|
|
/// Create a new `DbHolder`, wrapping a `Db` instance. When this is dropped
|
|
|
|
|
/// the `Db`'s purge task will be shut down.
|
|
|
|
|
pub(crate) fn new() -> DbHolder {
|
|
|
|
|
DbHolder { db: Db::new() }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Get the shared database. Internally, this is an
|
|
|
|
|
/// `Arc`, so a clone only increments the ref count.
|
|
|
|
|
pub(crate) fn db(&self) -> Db {
|
|
|
|
|
self.db.clone()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Db {
|
|
|
|
|
pub(crate) fn new() -> Db {
|
|
|
|
|
let state = Arc::new(Mutex::new(State {
|
2023-05-18 07:44:54 +00:00
|
|
|
cameras: HashMap::new(),
|
2023-05-17 19:32:32 +00:00
|
|
|
dispatchers: HashMap::new(),
|
|
|
|
|
plates: HashMap::new(),
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
Db { state }
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-18 07:44:54 +00:00
|
|
|
pub(crate) fn add_camera(&self, camera_id: CameraId, camera: Camera) {
|
|
|
|
|
let mut state = self.state.lock().unwrap();
|
|
|
|
|
state.cameras.insert(camera_id, camera);
|
|
|
|
|
debug!(?state);
|
|
|
|
|
}
|
2023-05-17 19:32:32 +00:00
|
|
|
|
|
|
|
|
pub(crate) fn add_dispatcher(
|
|
|
|
|
&self,
|
2023-05-18 07:44:54 +00:00
|
|
|
dispatcher_id: DispatcherId,
|
2023-05-17 19:32:32 +00:00
|
|
|
roads: Vec<u16>,
|
2023-05-18 07:44:54 +00:00
|
|
|
writer_stream: mpsc::Sender<ServerFrames>,
|
2023-05-17 19:32:32 +00:00
|
|
|
) {
|
|
|
|
|
let mut state = self.state.lock().unwrap();
|
2023-05-18 07:44:54 +00:00
|
|
|
state
|
|
|
|
|
.dispatchers
|
|
|
|
|
.insert(dispatcher_id, (roads, writer_stream));
|
|
|
|
|
debug!(?state);
|
2023-05-17 19:32:32 +00:00
|
|
|
}
|
|
|
|
|
|
2023-05-18 07:44:54 +00:00
|
|
|
pub(crate) fn insert_plate(&self, camera_id: CameraId, plate: Plate) {
|
2023-05-17 19:32:32 +00:00
|
|
|
let mut state = self.state.lock().unwrap();
|
2023-05-18 07:44:54 +00:00
|
|
|
state.plates.insert(camera_id, plate);
|
|
|
|
|
debug!(?state);
|
2023-05-17 19:32:32 +00:00
|
|
|
}
|
|
|
|
|
}
|