1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
11pub struct RowId(pub u64);
12
13impl RowId {
14 pub const MIN: RowId = RowId(0);
15 pub const NULL_SORT_KEY: u16 = 0xFFFF;
16
17 #[inline]
18 pub fn next(self) -> RowId {
19 RowId(self.0.wrapping_add(1))
20 }
21}
22
23impl std::fmt::Display for RowId {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 write!(f, "RowId({})", self.0)
26 }
27}
28
29impl From<u64> for RowId {
30 fn from(v: u64) -> Self {
31 RowId(v)
32 }
33}
34
35#[derive(Debug, Default)]
37pub struct RowIdAllocator {
38 next: u64,
39}
40
41impl RowIdAllocator {
42 pub fn new(start: u64) -> Self {
43 Self { next: start }
44 }
45
46 #[inline]
48 pub fn alloc(&mut self) -> RowId {
49 let id = self.next;
50 self.next += 1;
51 RowId(id)
52 }
53
54 pub fn alloc_range(&mut self, n: u64) -> RowId {
56 let start = self.next;
57 self.next = self.next.saturating_add(n);
58 RowId(start)
59 }
60
61 #[inline]
62 pub fn current(&self) -> RowId {
63 RowId(self.next)
64 }
65
66 pub fn advance_to(&mut self, id: RowId) {
68 if id.0 >= self.next {
69 self.next = id.0 + 1;
70 }
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[test]
79 fn allocates_monotonically() {
80 let mut a = RowIdAllocator::default();
81 assert_eq!(a.alloc(), RowId(0));
82 assert_eq!(a.alloc(), RowId(1));
83 let start = a.alloc_range(3);
84 assert_eq!(start, RowId(2));
85 assert_eq!(a.current(), RowId(5));
86 assert_eq!(a.alloc(), RowId(5));
87 }
88
89 #[test]
90 fn advance_to_moves_head() {
91 let mut a = RowIdAllocator::default();
92 a.advance_to(RowId(100));
93 assert_eq!(a.alloc(), RowId(101));
94 }
95}