1use std::collections::HashMap;
2use std::path::Path;
3use std::sync::Arc;
4use std::sync::atomic::{AtomicU64, Ordering};
5
6pub fn total_model_bytes(model: &Path) -> u64 {
9 let name = model.to_string_lossy();
10 if let Some(pos) = name.find("-00001-of-") {
11 let of_pos = pos + 10;
12 if let Some(ext_pos) = name[of_pos..].find(".gguf")
13 && let Ok(n_split) = name[of_pos..of_pos + ext_pos].parse::<u32>()
14 {
15 let prefix = &name[..pos + 1];
16 let suffix = &name[of_pos + ext_pos..];
17 let mut total: u64 = 0;
18 for i in 1..=n_split {
19 let split_name = format!("{}{:05}-of-{:05}{}", prefix, i, n_split, suffix);
20 total += std::fs::metadata(&split_name).map(|m| m.len()).unwrap_or(0);
21 }
22 return total;
23 }
24 }
25 std::fs::metadata(model).map(|m| m.len()).unwrap_or(0)
26}
27
28#[derive(Clone, Debug, PartialEq, Eq, Hash)]
30pub enum InferenceTarget {
31 None,
33 Local(u16),
35 Remote(iroh::EndpointId),
37}
38
39#[derive(Clone, Debug, Default)]
41pub struct ModelTargets {
42 pub targets: HashMap<String, Vec<InferenceTarget>>,
44 counter: Arc<AtomicU64>,
46}
47
48impl ModelTargets {
49 pub fn get(&self, model: &str) -> InferenceTarget {
51 match self.targets.get(model) {
52 Some(targets) if !targets.is_empty() => {
53 let idx = self.counter.fetch_add(1, Ordering::Relaxed) as usize % targets.len();
54 targets[idx].clone()
55 }
56 _ => InferenceTarget::None,
57 }
58 }
59
60 pub fn candidates(&self, model: &str) -> Vec<InferenceTarget> {
62 self.targets.get(model).cloned().unwrap_or_default()
63 }
64
65 pub fn pick_from(&self, candidates: &[InferenceTarget]) -> InferenceTarget {
67 if candidates.is_empty() {
68 InferenceTarget::None
69 } else {
70 let idx = self.counter.fetch_add(1, Ordering::Relaxed) as usize % candidates.len();
71 candidates[idx].clone()
72 }
73 }
74
75 pub fn pick_sticky_from(candidates: &[InferenceTarget], sticky_key: u64) -> InferenceTarget {
77 if candidates.is_empty() {
78 InferenceTarget::None
79 } else {
80 let idx = sticky_key as usize % candidates.len();
81 candidates[idx].clone()
82 }
83 }
84}