5OUVESUQDAEU3PEYFDXDMEULBNBJYEEHWV2LWFOOUKCTKRSZQMSAC
AOO3FCSGBMVD5YFMP2JO2P7ACWZF7IS6G3EI75GRYOIS4EIKPKHQC
5Y7ZXB53EMG34VZI5VQIZ77TZKBB4V6BGIILFZ5ZY73QYK4V2YHQC
QEKHTVB7CH754NUMHJ3AKVGRNKW3KOAKMALS7B3ZNKCUEH6GP4HQC
YCWYAX6K2DJKT7FO4IAYL6HJOIJLYFKAPGLFJ5XMYSYAS42LP3FQC
RNW6D77774CYWWM7JIFXI5TGKBOU6ADJIEZB5N2FXGDCTLUXEQZQC
HMOBTVJ4FEPZWMUV2JDPZYH3EFCW6ED5M6KKNKQJQZVKTDAKTVFQC
// If this task fails the worst that will happen is I compare more
// names than I otherwise would. .
let check =
tokio::spawn(async move {
let prefs =
pdb.list_preferences().await.unwrap_or_else(|_| Vec::new());
tokio::task::spawn_blocking(move || {
depths(prefs.into_iter().map(|(better, worse)| {
(better as usize, worse as usize)
}))
})
.await
.unwrap_or_else(|_| Vec::new())
});
for name in db
.list_names()
.await
.ok()
.into_iter()
.flat_map(Vec::into_iter)
{
match ntx.send(name).await {
Ok(_) => (),
Err(_) => break,
let names = db.list_names().await;
let depth_list = check.await.unwrap_or_else(|_| Vec::new());
for name in names.ok().into_iter().flat_map(Vec::into_iter) {
if depth_list.get(name.1 as usize).cloned().unwrap_or(0)
< count.into()
{
match ntx.send(name).await {
Ok(_) => (),
Err(_) => break,
}
pub fn depths<I: IntoIterator<Item = (usize, usize)>>(
preferences: I,
) -> Vec<usize> {
let mut workspace = Vec::new();
let mut result = Vec::new();
for (better, worse) in preferences {
while workspace.len() <= worse {
workspace.push(Vec::new());
result.push(0);
}
workspace[worse].push(better);
}
let mut stack: Vec<(usize, Option<usize>)> =
(0..workspace.len()).rev().map(|x| (x, None)).collect();
while let Some((i, r)) = stack.pop() {
let d = std::mem::take(&mut workspace[i]);
if !d.is_empty() {
stack.push((i, r));
for j in d {
stack.push((j, Some(i)));
}
} else if let Some(s) = r {
result[s] = result[s].max(result[i] + 1);
}
}
result
}