feat: parallelise the location route
This commit is contained in:
parent
73fdfd3263
commit
73bf8a41fe
File diff suppressed because it is too large
Load Diff
|
@ -11,7 +11,9 @@ base64 = "0.21"
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
if_chain = "1"
|
if_chain = "1"
|
||||||
|
parking_lot = "0.12"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
|
rayon = "1"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_yaml = "0.9"
|
serde_yaml = "0.9"
|
||||||
sha3 = "0.10"
|
sha3 = "0.10"
|
||||||
|
|
|
@ -2,8 +2,10 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use chrono::{Duration, Utc};
|
use chrono::{Duration, Utc};
|
||||||
|
use parking_lot::RwLock;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
|
use rayon::prelude::*;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use warp::{Filter, Rejection, Reply};
|
use warp::{Filter, Rejection, Reply};
|
||||||
use warp::filters::BoxedFilter;
|
use warp::filters::BoxedFilter;
|
||||||
|
@ -99,75 +101,80 @@ fn filter_messages(messages: &mut Vec<RetrievedMessage>, id: i64) {
|
||||||
messages.shuffle(&mut rand::thread_rng());
|
messages.shuffle(&mut rand::thread_rng());
|
||||||
|
|
||||||
// just count nearby messages. this is O(n^2) but alternatives are hard
|
// just count nearby messages. this is O(n^2) but alternatives are hard
|
||||||
let mut ids = Vec::with_capacity(messages.len());
|
let ids = RwLock::new(Vec::with_capacity(messages.len()));
|
||||||
for a in messages.iter() {
|
messages.par_iter()
|
||||||
if a.user == id {
|
.for_each(|a| {
|
||||||
// always include own messages
|
if a.user == id {
|
||||||
ids.push(a.id.clone());
|
ids.write().push(a.id.clone());
|
||||||
continue;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
let mut nearby_ids = Vec::new();
|
|
||||||
for b in messages.iter() {
|
|
||||||
if a.id == b.id {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let distance = (a.x - b.x).powi(2)
|
let mut nearby_ids = Vec::new();
|
||||||
+ (a.y - b.y).powi(2)
|
for b in messages.iter() {
|
||||||
+ (a.z - b.z).powi(2);
|
if a.id == b.id {
|
||||||
// 10 squared
|
continue;
|
||||||
if distance >= 100.0 {
|
}
|
||||||
continue;
|
|
||||||
|
let distance = (a.x - b.x).powi(2)
|
||||||
|
+ (a.y - b.y).powi(2)
|
||||||
|
+ (a.z - b.z).powi(2);
|
||||||
|
// 10 squared
|
||||||
|
if distance >= 100.0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
nearby_ids.push(&b.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
nearby_ids.push(&b.id);
|
let mut nearby = nearby_ids.len() as u32;
|
||||||
}
|
let (numerator, denominator) = if nearby <= 2 {
|
||||||
|
// no need to do calculations for groups of three or fewer
|
||||||
|
(17, 20)
|
||||||
|
} else {
|
||||||
|
let already_visible = {
|
||||||
|
let ids = ids.read();
|
||||||
|
nearby_ids.iter()
|
||||||
|
.filter(|id| ids.contains(id))
|
||||||
|
.count()
|
||||||
|
};
|
||||||
|
|
||||||
let mut nearby = nearby_ids.len() as u32;
|
if already_visible >= 3 {
|
||||||
let (numerator, denominator) = if nearby <= 2 {
|
return;
|
||||||
// no need to do calculations for groups of three or fewer
|
}
|
||||||
(17, 20)
|
|
||||||
} else {
|
let time_since_creation = a.created.signed_duration_since(Utc::now().naive_utc());
|
||||||
let already_visible = nearby_ids.iter()
|
let brand_new = time_since_creation < Duration::minutes(30);
|
||||||
.filter(|id| ids.contains(id))
|
let new = time_since_creation < Duration::hours(2);
|
||||||
.count();
|
|
||||||
if already_visible >= 3 {
|
let mut numerator = 1;
|
||||||
continue;
|
if brand_new {
|
||||||
|
numerator = nearby;
|
||||||
|
} else if new {
|
||||||
|
numerator += (nearby / 3).min(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let score = (a.positive_votes - a.negative_votes).max(0);
|
||||||
|
if score > 0 {
|
||||||
|
let pad = score as f32 / nearby as f32;
|
||||||
|
let rounded = pad.floor() as u32;
|
||||||
|
numerator += rounded.max(nearby / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
nearby *= 2;
|
||||||
|
|
||||||
|
if numerator * 5 > nearby * 4 {
|
||||||
|
numerator = 4;
|
||||||
|
nearby = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
(numerator, nearby)
|
||||||
|
};
|
||||||
|
|
||||||
|
if rand::thread_rng().gen_ratio(numerator.min(denominator), denominator) {
|
||||||
|
ids.write().push(a.id.clone());
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let time_since_creation = a.created.signed_duration_since(Utc::now().naive_utc());
|
let ids = ids.into_inner();
|
||||||
let brand_new = time_since_creation < Duration::minutes(30);
|
|
||||||
let new = time_since_creation < Duration::hours(2);
|
|
||||||
|
|
||||||
let mut numerator = 1;
|
|
||||||
if brand_new {
|
|
||||||
numerator = nearby;
|
|
||||||
} else if new {
|
|
||||||
numerator += (nearby / 3).min(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let score = (a.positive_votes - a.negative_votes).max(0);
|
|
||||||
if score > 0 {
|
|
||||||
let pad = score as f32 / nearby as f32;
|
|
||||||
let rounded = pad.floor() as u32;
|
|
||||||
numerator += rounded.max(nearby / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
nearby *= 2;
|
|
||||||
|
|
||||||
if numerator * 5 > nearby * 4 {
|
|
||||||
numerator = 4;
|
|
||||||
nearby = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
(numerator, nearby)
|
|
||||||
};
|
|
||||||
|
|
||||||
if rand::thread_rng().gen_ratio(numerator.min(denominator), denominator) {
|
|
||||||
ids.push(a.id.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
messages.drain_filter(|msg| !ids.contains(&msg.id));
|
messages.drain_filter(|msg| !ids.contains(&msg.id));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue