objectiveai_api/vector/completions/
pfx.rs1use indexmap::IndexMap;
18use rand::{Rng, seq::SliceRandom};
19use std::sync::Arc;
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
23pub enum Pfx {
24 A,
25 B,
26 C,
27 D,
28 E,
29 F,
30 G,
31 H,
32 I,
33 J,
34 K,
35 L,
36 M,
37 N,
38 O,
39 P,
40 Q,
41 R,
42 S,
43 T,
44}
45
46impl Pfx {
47 pub fn to_char(&self) -> char {
49 match self {
50 Pfx::A => 'A',
51 Pfx::B => 'B',
52 Pfx::C => 'C',
53 Pfx::D => 'D',
54 Pfx::E => 'E',
55 Pfx::F => 'F',
56 Pfx::G => 'G',
57 Pfx::H => 'H',
58 Pfx::I => 'I',
59 Pfx::J => 'J',
60 Pfx::K => 'K',
61 Pfx::L => 'L',
62 Pfx::M => 'M',
63 Pfx::N => 'N',
64 Pfx::O => 'O',
65 Pfx::P => 'P',
66 Pfx::Q => 'Q',
67 Pfx::R => 'R',
68 Pfx::S => 'S',
69 Pfx::T => 'T',
70 }
71 }
72
73 pub fn from_char(c: char) -> Option<Self> {
75 match c {
76 'A' => Some(Pfx::A),
77 'B' => Some(Pfx::B),
78 'C' => Some(Pfx::C),
79 'D' => Some(Pfx::D),
80 'E' => Some(Pfx::E),
81 'F' => Some(Pfx::F),
82 'G' => Some(Pfx::G),
83 'H' => Some(Pfx::H),
84 'I' => Some(Pfx::I),
85 'J' => Some(Pfx::J),
86 'K' => Some(Pfx::K),
87 'L' => Some(Pfx::L),
88 'M' => Some(Pfx::M),
89 'N' => Some(Pfx::N),
90 'O' => Some(Pfx::O),
91 'P' => Some(Pfx::P),
92 'Q' => Some(Pfx::Q),
93 'R' => Some(Pfx::R),
94 'S' => Some(Pfx::S),
95 'T' => Some(Pfx::T),
96 _ => None,
97 }
98 }
99
100 pub fn rng_vec(rng: &mut impl Rng) -> Vec<Self> {
102 let mut vec = vec![
103 Pfx::A,
104 Pfx::B,
105 Pfx::C,
106 Pfx::D,
107 Pfx::E,
108 Pfx::F,
109 Pfx::G,
110 Pfx::H,
111 Pfx::I,
112 Pfx::J,
113 Pfx::K,
114 Pfx::L,
115 Pfx::M,
116 Pfx::N,
117 Pfx::O,
118 Pfx::P,
119 Pfx::Q,
120 Pfx::R,
121 Pfx::S,
122 Pfx::T,
123 ];
124 vec.shuffle(rng);
125 vec
126 }
127}
128
129impl std::fmt::Display for Pfx {
130 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
131 write!(f, "{}", self.to_char())
132 }
133}
134
135#[derive(Debug, Clone)]
142pub enum PfxTree {
143 Branch(Arc<IndexMap<Pfx, PfxTree>>),
145 Leaf(usize),
147}
148
149impl PfxTree {
150 pub fn new(
155 rng: &mut impl Rng,
156 source_len: usize,
157 max_branch_len: usize,
158 ) -> Self {
159 let mut source: Vec<usize> = (0..source_len).collect();
160 source.shuffle(rng);
161 Self::new_inner(rng, &source, max_branch_len, false)
162 }
163
164 pub fn new_inner(
166 rng: &mut impl Rng,
167 source: &[usize],
168 max_branch_len: usize,
169 force_sub_branch: bool,
170 ) -> Self {
171 let pfxs = Pfx::rng_vec(rng);
172 if !force_sub_branch && source.len() <= max_branch_len {
173 let mut branch = IndexMap::with_capacity(source.len());
175 for (i, source_index) in source.iter().enumerate() {
176 branch.insert(pfxs[i], PfxTree::Leaf(*source_index));
177 }
178 Self::Branch(Arc::new(branch))
179 } else {
180 let n = {
182 let candidate =
183 (source.len() + max_branch_len - 1) / max_branch_len;
184 if candidate <= max_branch_len {
185 candidate
186 } else {
187 max_branch_len
188 }
189 };
190 let base_per = source.len() / n;
191 let extra = source.len() % n;
192 let force_sub_branch =
193 base_per + { if extra > 0 { 1 } else { 0 } } > max_branch_len;
194 let mut branch = IndexMap::with_capacity(n);
195 let mut i = 0;
196 let mut count = 0;
197 while i < n {
198 let branch_len = base_per + if i < extra { 1 } else { 0 };
199 branch.insert(
200 pfxs[i],
201 PfxTree::new_inner(
202 rng,
203 &source[count..count + branch_len],
204 max_branch_len,
205 force_sub_branch,
206 ),
207 );
208 count += branch_len;
209 i += 1;
210 }
211 Self::Branch(Arc::new(branch))
212 }
213 }
214
215 pub fn pfx_indices(
219 &self,
220 rng: &mut impl Rng,
221 source_len: usize,
222 ) -> Vec<(String, usize)> {
223 let mut indices = Vec::with_capacity(source_len);
224 self.pfx_indices_inner(None, &mut indices);
225 indices.shuffle(rng);
226 indices
227 }
228
229 pub fn pfx_indices_inner(
231 &self,
232 parent_pfx: Option<String>,
233 indices: &mut Vec<(String, usize)>,
234 ) {
235 match self {
236 PfxTree::Branch(branch) => {
237 for (pfx, child) in branch.as_ref() {
238 let parent_pfx = Some(match &parent_pfx {
239 Some(parent_pfx) => format!("{}`{}`", parent_pfx, pfx),
240 None => format!("`{}`", pfx),
241 });
242 child.pfx_indices_inner(parent_pfx, indices);
243 }
244 }
245 PfxTree::Leaf(index) => {
246 indices.push((parent_pfx.unwrap(), *index));
247 }
248 }
249 }
250
251 pub fn get(&self, pfx: Pfx) -> Option<PfxTree> {
253 match self {
254 PfxTree::Branch(branch) => branch.get(&pfx).cloned(),
255 PfxTree::Leaf(_) => None,
256 }
257 }
258
259 pub fn depth(&self) -> usize {
261 match self {
262 PfxTree::Branch(branch) => {
263 1 + branch
264 .values()
265 .next() .map(|v| v.depth())
267 .unwrap_or(0)
268 }
269 PfxTree::Leaf(_) => 0,
270 }
271 }
272
273 pub fn unwrap_leaf(&self) -> usize {
277 match self {
278 PfxTree::Leaf(index) => *index,
279 PfxTree::Branch(_) => {
280 panic!("Called unwrap_leaf on a Branch")
281 }
282 }
283 }
284
285 pub fn regex_patterns(&self, keys: &[(String, usize)]) -> (String, String) {
289 let depth = self.depth();
290 let mut with_ticks = String::with_capacity(
291 (keys.len() - 1) + (keys.len() * depth * 3) + keys.len() * 2, );
295 let mut without_ticks = String::with_capacity(
296 (keys.len() - 1) + keys.len() * (depth * 3 - 2) + keys.len() * 2, );
300 for (key, _) in keys {
301 if with_ticks.len() > 0 {
302 with_ticks.push('|');
303 without_ticks.push('|');
304 }
305 with_ticks.push('(');
306 without_ticks.push('(');
307 with_ticks.push_str(key);
308 without_ticks.push_str(&key[1..key.len() - 1]); with_ticks.push(')');
310 without_ticks.push(')');
311 }
312 (with_ticks, without_ticks)
313 }
314}
315
316#[derive(Debug, Clone)]
318pub struct PfxData {
319 pub pfx_tree: PfxTree,
321 pub responses_key_pattern: String,
323 pub responses_key_pattern_stripped: String,
325}