lance_core/utils/
address.rs1use std::ops::Range;
5
6#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
24pub struct RowAddress(u64);
25
26impl RowAddress {
27 pub const FRAGMENT_SIZE: u64 = 1 << 32;
28 pub const TOMBSTONE_FRAG: u32 = 0xffffffff;
30 pub const TOMBSTONE_ROW: u64 = 0xffffffffffffffff;
32
33 pub fn new_from_u64(row_addr: u64) -> Self {
34 Self(row_addr)
35 }
36
37 pub fn new_from_parts(fragment_id: u32, row_offset: u32) -> Self {
38 Self(((fragment_id as u64) << 32) | row_offset as u64)
39 }
40
41 pub fn first_row(fragment_id: u32) -> Self {
43 Self::new_from_parts(fragment_id, 0)
44 }
45
46 pub fn address_range(fragment_id: u32) -> Range<u64> {
56 u64::from(Self::first_row(fragment_id))..u64::from(Self::first_row(fragment_id + 1))
57 }
58
59 pub fn fragment_id(&self) -> u32 {
60 (self.0 >> 32) as u32
61 }
62
63 pub fn row_offset(&self) -> u32 {
64 self.0 as u32
65 }
66}
67
68impl From<RowAddress> for u64 {
69 fn from(row_addr: RowAddress) -> Self {
70 row_addr.0
71 }
72}
73
74impl From<u64> for RowAddress {
75 fn from(row_addr: u64) -> Self {
76 Self(row_addr)
77 }
78}
79
80impl std::fmt::Debug for RowAddress {
81 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
82 write!(f, "{}", self) }
84}
85
86impl std::fmt::Display for RowAddress {
87 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88 write!(f, "({}, {})", self.fragment_id(), self.row_offset())
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95
96 #[test]
97 fn test_row_address() {
98 let addr = RowAddress::new_from_u64(0x0000_0001_0000_0002);
100 assert_eq!(addr.fragment_id(), 1);
101 assert_eq!(addr.row_offset(), 2);
102
103 let range = RowAddress::address_range(3);
105 assert_eq!(range.start, 3 * RowAddress::FRAGMENT_SIZE);
106
107 let addr2 = RowAddress::new_from_parts(7, 8);
109 let raw: u64 = addr2.into();
110 let addr3: RowAddress = raw.into();
111 assert_eq!(addr2, addr3);
112
113 assert_eq!(format!("{:?}", addr), "(1, 2)");
115 }
116}