1use std::{
26 fmt::{Debug, Display},
27 hash::Hash,
28 marker::PhantomData,
29 ops::{Deref, DerefMut, Index, IndexMut},
30 slice, vec,
31};
32
33use crate::intern::Intern;
34use serde::{Deserialize, Deserializer, Serialize, Serializer, ser::SerializeSeq};
35
36pub trait Identifier: Copy + Hash + From<usize> + Into<usize> + Eq + Ord + std::fmt::Debug {}
40
41impl Identifier for usize {}
42
43pub struct Identified<Id: Identifier, T> {
45 pub id: Id,
46 pub inner: T,
47}
48
49impl<Id: Identifier, T> Identified<Id, T> {
50 pub fn new(id: Id, data: T) -> Self {
52 Self { id, inner: data }
53 }
54}
55
56impl<Id: Identifier, T> Deref for Identified<Id, T> {
57 type Target = T;
58
59 fn deref(&self) -> &Self::Target {
60 &self.inner
61 }
62}
63
64impl<Id: Identifier, T> DerefMut for Identified<Id, T> {
65 fn deref_mut(&mut self) -> &mut Self::Target {
66 &mut self.inner
67 }
68}
69
70impl<'a, Id: Identifier, T> Identified<Id, &'a mut T> {
71 pub fn immutable(self) -> Identified<Id, &'a T> {
73 Identified::new(self.id, &*self.inner)
74 }
75}
76
77impl<Id: Identifier, T: Display> Display for Identified<Id, T> {
78 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79 self.inner.fmt(f)
80 }
81}
82
83impl<Id: Identifier, T: Debug> Debug for Identified<Id, T> {
84 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85 self.inner.fmt(f)
86 }
87}
88
89pub struct Registry<Id: Identifier, T> {
121 chunks: Vec<Vec<T>>,
122 len: usize,
123 _marker: PhantomData<Id>,
124}
125
126#[inline]
128fn locate(n: usize) -> (usize, usize) {
129 let m = n + 1;
130 let k = (usize::BITS - 1 - m.leading_zeros()) as usize;
131 (k, m - (1 << k))
132}
133
134impl<Id: Identifier, T: Serialize> Serialize for Registry<Id, T> {
135 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
136 where
137 S: Serializer,
138 {
139 let mut seq = serializer.serialize_seq(Some(self.len))?;
144 for e in self.chunks.iter().flatten() {
145 seq.serialize_element(e)?;
146 }
147 seq.end()
148 }
149}
150
151impl<'de, Id: Identifier, T: Deserialize<'de>> Deserialize<'de> for Registry<Id, T> {
152 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
153 where
154 D: Deserializer<'de>,
155 {
156 Ok(Vec::<T>::deserialize(deserializer)?.into_iter().collect())
157 }
158}
159
160impl<Id: Identifier, T: Clone> Clone for Registry<Id, T> {
161 fn clone(&self) -> Self {
162 self.chunks.iter().flatten().cloned().collect()
166 }
167}
168
169impl<Id: Identifier, T: Debug> Debug for Registry<Id, T> {
170 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
171 f.debug_list()
172 .entries(self.chunks.iter().flatten())
173 .finish()
174 }
175}
176
177impl<Id: Identifier, T: PartialEq> PartialEq for Registry<Id, T> {
178 fn eq(&self, other: &Self) -> bool {
179 self.len == other.len
180 && self
181 .chunks
182 .iter()
183 .flatten()
184 .eq(other.chunks.iter().flatten())
185 }
186}
187
188impl<Id: Identifier, T: Eq> Eq for Registry<Id, T> {}
189
190impl<Id: Identifier, T> Registry<Id, T> {
191 pub fn push(&mut self, e: T) -> Id {
193 let n = self.len;
194 let (k, offset) = locate(n);
195 if offset == 0 {
196 self.chunks.push(Vec::with_capacity(1 << k));
198 }
199 self.chunks[k].push(e);
200 self.len += 1;
201 n.into()
202 }
203
204 pub fn len(&self) -> usize {
206 self.len
207 }
208
209 pub fn is_empty(&self) -> bool {
211 self.len == 0
212 }
213
214 #[inline]
215 #[track_caller]
216 fn at(&self, n: usize) -> &T {
217 debug_assert!(
218 n < self.len,
219 "registry index {n} out of bounds for length {}",
220 self.len
221 );
222 let (k, offset) = locate(n);
223 &self.chunks[k][offset]
224 }
225
226 #[inline]
227 #[track_caller]
228 fn at_mut(&mut self, n: usize) -> &mut T {
229 debug_assert!(
230 n < self.len,
231 "registry index {n} out of bounds for length {}",
232 self.len
233 );
234 let (k, offset) = locate(n);
235 &mut self.chunks[k][offset]
236 }
237
238 #[track_caller]
246 pub fn replace(&mut self, id: Id, value: T) -> T {
247 std::mem::replace(self.at_mut(id.into()), value)
248 }
249
250 #[track_caller]
255 pub fn get(&self, id: Id) -> Identified<Id, &T> {
256 Identified::new(id, self.at(id.into()))
257 }
258
259 #[track_caller]
264 pub fn get_mut(&mut self, id: Id) -> Identified<Id, &mut T> {
265 Identified::new(id, self.at_mut(id.into()))
266 }
267
268 pub fn iter(&self) -> Iter<'_, Id, T> {
289 Iter {
290 iter: self.chunks.iter().flatten(),
291 index: 0,
292 _marker: PhantomData,
293 }
294 }
295
296 pub fn iter_mut(&mut self) -> IterMut<'_, Id, T> {
318 IterMut {
319 iter: self.chunks.iter_mut().flatten(),
320 index: 0,
321 _marker: PhantomData,
322 }
323 }
324
325 pub fn select_mut(&mut self, ids: &[Id]) -> Vec<&mut T> {
341 let mut want: std::collections::HashMap<usize, usize> =
345 std::collections::HashMap::with_capacity(ids.len());
346 for (pos, id) in ids.iter().enumerate() {
347 let n: usize = (*id).into();
348 assert!(
349 n < self.len,
350 "select_mut: id index {n} out of bounds (len {})",
351 self.len
352 );
353 let prev = want.insert(n, pos);
354 assert!(prev.is_none(), "select_mut: duplicate id index {n}");
355 }
356
357 let mut slots: Vec<Option<&mut T>> = (0..ids.len()).map(|_| None).collect();
361 for item in self.iter_mut() {
362 let n: usize = item.id.into();
363 if let Some(&pos) = want.get(&n) {
364 slots[pos] = Some(item.inner);
365 }
366 }
367 slots
368 .into_iter()
369 .map(|slot| slot.expect("select_mut: requested id had no backing slot"))
370 .collect()
371 }
372}
373
374pub struct Iter<'a, Id: Identifier, T> {
375 iter: std::iter::Flatten<slice::Iter<'a, Vec<T>>>,
376 index: usize,
377 _marker: PhantomData<Id>,
378}
379
380impl<'a, Id: Identifier, T> Iterator for Iter<'a, Id, T> {
381 type Item = Identified<Id, &'a T>;
382
383 fn next(&mut self) -> Option<Self::Item> {
384 let value = self.iter.next()?;
385 let id = Id::from(self.index);
386 self.index += 1;
387
388 Some(Identified::new(id, value))
389 }
390}
391
392pub struct IterMut<'a, Id: Identifier, T> {
393 iter: std::iter::Flatten<slice::IterMut<'a, Vec<T>>>,
394 index: usize,
395 _marker: PhantomData<Id>,
396}
397
398impl<'a, Id: Identifier, T> Iterator for IterMut<'a, Id, T> {
399 type Item = Identified<Id, &'a mut T>;
400
401 fn next(&mut self) -> Option<Self::Item> {
402 let value = self.iter.next()?;
403 let id = Id::from(self.index);
404 self.index += 1;
405
406 Some(Identified::new(id, value))
407 }
408}
409
410pub struct IntoIter<Id: Identifier, T> {
411 iter: std::iter::Flatten<vec::IntoIter<Vec<T>>>,
412 index: usize,
413 _marker: PhantomData<Id>,
414}
415
416impl<Id: Identifier, T> Iterator for IntoIter<Id, T> {
417 type Item = Identified<Id, T>;
418
419 fn next(&mut self) -> Option<Self::Item> {
420 let value = self.iter.next()?;
421 let id = Id::from(self.index);
422 self.index += 1;
423
424 Some(Identified::new(id, value))
425 }
426}
427
428impl<Id: Identifier, T> Default for Registry<Id, T> {
429 fn default() -> Self {
430 Self {
431 chunks: Vec::new(),
432 len: 0,
433 _marker: PhantomData,
434 }
435 }
436}
437
438impl<'a, Id: Identifier, T> IntoIterator for &'a Registry<Id, T> {
439 type Item = Identified<Id, &'a T>;
440
441 type IntoIter = Iter<'a, Id, T>;
442
443 fn into_iter(self) -> Self::IntoIter {
444 self.iter()
445 }
446}
447
448impl<'a, Id: Identifier, T> IntoIterator for &'a mut Registry<Id, T> {
449 type Item = Identified<Id, &'a mut T>;
450
451 type IntoIter = IterMut<'a, Id, T>;
452
453 fn into_iter(self) -> Self::IntoIter {
454 self.iter_mut()
455 }
456}
457
458impl<Id: Identifier, T> IntoIterator for Registry<Id, T> {
459 type Item = Identified<Id, T>;
460
461 type IntoIter = IntoIter<Id, T>;
462
463 fn into_iter(self) -> Self::IntoIter {
464 IntoIter {
465 iter: self.chunks.into_iter().flatten(),
466 index: 0,
467 _marker: PhantomData,
468 }
469 }
470}
471
472impl<Id: Identifier, T> FromIterator<T> for Registry<Id, T> {
473 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
474 let mut reg = Self::default();
475 for e in iter {
476 reg.push(e);
477 }
478 reg
479 }
480}
481
482impl<Id: Identifier, T> Index<Id> for Registry<Id, T> {
483 type Output = T;
484
485 #[track_caller]
486 fn index(&self, index: Id) -> &Self::Output {
487 self.at(index.into())
488 }
489}
490
491impl<Id: Identifier, T> IndexMut<Id> for Registry<Id, T> {
492 #[track_caller]
493 fn index_mut(&mut self, index: Id) -> &mut Self::Output {
494 self.at_mut(index.into())
495 }
496}
497
498impl<Id: Identifier, T: Intern> Intern for Registry<Id, T> {
499 type Static = Registry<Id, T::Static>;
500
501 fn intern(self, pool: &mut super::intern::StringPool) -> Self::Static {
502 self.into_iter()
503 .map(|item| item.inner.intern(pool))
504 .collect()
505 }
506}
507
508#[cfg(test)]
509mod tests {
510 use super::*;
511 use jstd_derive::Identifier;
512
513 #[derive(Identifier)]
514 struct Id(usize);
515
516 #[test]
518 fn locate_matches_doubling_layout() {
519 assert_eq!(locate(0), (0, 0)); assert_eq!(locate(1), (1, 0)); assert_eq!(locate(2), (1, 1));
522 assert_eq!(locate(3), (2, 0)); assert_eq!(locate(6), (2, 3));
524 assert_eq!(locate(7), (3, 0)); }
526
527 #[test]
529 fn push_index_iter_across_chunks() {
530 let mut reg = Registry::<Id, usize>::default();
531 let ids: Vec<Id> = (0..1000).map(|v| reg.push(v)).collect();
532 assert_eq!(reg.len(), 1000);
533 for (i, &id) in ids.iter().enumerate() {
534 assert_eq!(usize::from(id), i);
535 assert_eq!(reg[id], i);
536 }
537 let seen: Vec<usize> = reg.iter().map(|item| *item.inner).collect();
538 assert_eq!(seen, (0..1000).collect::<Vec<_>>());
539 }
540
541 #[test]
544 fn element_address_is_stable_across_pushes() {
545 let mut reg = Registry::<Id, usize>::default();
546 let first = reg.push(42);
547 let addr = ®[first] as *const usize;
548 for v in 0..10_000 {
549 reg.push(v);
550 }
551 assert_eq!(
552 ®[first] as *const usize, addr,
553 "address moved after growth"
554 );
555 assert_eq!(reg[first], 42);
556 }
557
558 #[test]
561 fn replace_swaps_in_place() {
562 let mut reg = Registry::<Id, i32>::default();
563 let a = reg.push(1);
564 let b = reg.push(2);
565 let addr_b = ®[b] as *const i32;
566 let old = reg.replace(b, 99);
567 assert_eq!(old, 2);
568 assert_eq!(reg[b], 99);
569 assert_eq!(reg[a], 1, "other ids untouched");
570 assert_eq!(®[b] as *const i32, addr_b, "slot address stable");
571 assert_eq!(reg.len(), 2, "len unchanged");
572 }
573
574 #[test]
575 #[cfg(debug_assertions)]
576 #[should_panic(expected = "registry index 0 out of bounds for length 0")]
577 fn indexing_reports_requested_index_and_length() {
578 let reg = Registry::<Id, usize>::default();
579 let _ = reg[Id::from(0)];
580 }
581
582 #[test]
586 fn select_mut_disjoint_in_input_order() {
587 let mut reg = Registry::<Id, usize>::default();
588 let ids: Vec<Id> = (0..100).map(|v| reg.push(v)).collect();
589
590 let picked = [ids[7], ids[0], ids[63], ids[64], ids[2]];
592 let refs = reg.select_mut(&picked);
593 assert_eq!(refs.len(), picked.len());
594 assert_eq!(
596 refs.iter().map(|r| **r).collect::<Vec<_>>(),
597 vec![7, 0, 63, 64, 2]
598 );
599 for r in refs {
601 *r += 1000;
602 }
603 for &id in &picked {
604 assert_eq!(reg[id], usize::from(id) + 1000);
605 }
606 assert_eq!(reg[ids[1]], 1);
608 }
609
610 #[test]
612 #[should_panic(expected = "duplicate id")]
613 fn select_mut_rejects_duplicates() {
614 let mut reg = Registry::<Id, usize>::default();
615 let a = reg.push(1);
616 reg.push(2);
617 let _ = reg.select_mut(&[a, a]);
618 }
619
620 #[test]
624 fn rebuild_from_flat_sequence() {
625 let reg: Registry<Id, i32> = (0..300).collect();
626 let flat: Vec<i32> = reg.iter().map(|item| *item.inner).collect();
627 let back: Registry<Id, i32> = flat.into_iter().collect();
628 assert_eq!(reg, back);
629 assert_eq!(back.len(), 300);
630 }
631
632 #[test]
636 fn clone_preserves_stability() {
637 let mut reg = Registry::<Id, usize>::default();
638 for v in 0..5 {
639 reg.push(v); }
641 let mut cloned = reg.clone();
642 assert_eq!(reg, cloned);
643 let last = Id::from(4);
644 let addr = &cloned[last] as *const usize;
645 cloned.push(99); assert_eq!(
647 &cloned[last] as *const usize, addr,
648 "clone's chunk reallocated"
649 );
650 }
651
652 #[test]
653 fn public_views_iterators_and_serialization_preserve_values() {
654 let mut reg = Registry::<Id, i32>::default();
655 assert!(reg.is_empty());
656 let first = reg.push(10);
657 let second = reg.push(20);
658 assert_eq!(reg.get(first).id, first);
659 assert_eq!(**reg.get(second), 20);
660
661 let mut mutable = reg.get_mut(first);
662 **mutable += 5;
663 let immutable = mutable.immutable();
664 assert_eq!(immutable.id, first);
665 assert_eq!(**immutable, 15);
666 assert_eq!(format!("{immutable}"), "15");
667 assert_eq!(format!("{immutable:?}"), "15");
668
669 let mut borrowed = (®).into_iter();
670 assert_eq!(borrowed.size_hint(), (0, None));
671 assert_eq!(borrowed.next().unwrap().id, first);
672 assert_eq!(borrowed.next().unwrap().id, second);
673 assert!(borrowed.next().is_none());
674
675 let owned: Vec<_> = reg.clone().into_iter().map(|entry| entry.inner).collect();
676 assert_eq!(owned, [15, 20]);
677 assert_eq!(format!("{reg:?}"), "[15, 20]");
678
679 let bytes = bincode::serde::encode_to_vec(®, bincode::config::standard()).unwrap();
680 let (decoded, used): (Registry<Id, i32>, _) =
681 bincode::serde::decode_from_slice(&bytes, bincode::config::standard()).unwrap();
682 assert_eq!(used, bytes.len());
683 assert_eq!(decoded, reg);
684 }
685}