#![deny(missing_docs)]
use std::collections::BTreeMap;
use s2::cellid::CellID;
use crate::{users::User, utils::ll};
pub trait CellScorer<UserCollection> {
fn score_cell_list<T: User>(&self, cell_list: CellList, users: UserCollection) -> CellList
where
UserCollection: Iterator<Item = T>;
}
pub struct UserCountScorer;
impl<UserCollection> CellScorer<UserCollection> for UserCountScorer {
fn score_cell_list<T>(&self, mut cell_list: CellList, users: UserCollection) -> CellList
where
UserCollection: Iterator<Item = T>,
T: User,
{
for user in users {
let cell_id = CellID::from(user.location()).parent(cell_list.storage_level);
let score = cell_list.cell_list.get_mut(&cell_id).unwrap();
*score += 1;
}
cell_list
}
}
pub struct CellList {
storage_level: u64,
cell_list: BTreeMap<CellID, i32>,
}
impl CellList {
pub fn new(storage_level: u64) -> Self {
let starting_cell_id = CellID::from(ll!(0.00000000, 0.00000000));
let cell_list = Self::gather_cells(storage_level, starting_cell_id);
Self {
storage_level,
cell_list,
}
}
pub fn mut_cell_list(&mut self) -> &mut BTreeMap<CellID, i32> {
&mut self.cell_list
}
pub fn cell_list(&self) -> &BTreeMap<CellID, i32> {
&self.cell_list
}
fn gather_cells(storage_level: u64, starting_cell_id: CellID) -> BTreeMap<CellID, i32> {
let mut seen = BTreeMap::new();
let mut current_stack = vec![starting_cell_id];
while let Some(current_neighbor) = current_stack.pop() {
if !seen.contains_key(¤t_neighbor) {
current_stack.append(&mut current_neighbor.all_neighbors(storage_level));
seen.insert(current_neighbor, 0);
}
}
seen
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_geoshard_cell_list() {
let cell_list = CellList::new(8).cell_list;
assert_eq!(cell_list.len(), 393217);
}
}