osiris_data/data/
identification.rs1use std::hash::{Hash, Hasher};
6
7use crate::data::atomic::Word;
8
9pub trait Identifier: Hash {
11 fn to_usize(&self) -> usize;
12}
13
14#[derive(Copy, Clone, Default, Debug, Eq, PartialEq, Ord, PartialOrd)]
18pub struct Address(u64);
19
20impl Address {
21 pub const fn new(value: u64) -> Self {
28 Self(value)
29 }
30
31 pub const fn to_u64(&self) -> u64 { self.0 }
33
34 pub const fn from_word(word: Word) -> Self { Self::new(word.to_u64()) }
36
37 pub fn from<T: Identifier>(identifier: T) -> Self { Self::new(identifier.to_usize() as u64) }
39
40 pub const fn to_word(&self) -> Word { Word::new(self.0) }
42
43 pub fn increment(&mut self) {
45 self.0 += 1;
46 }
47
48 pub fn offset(&self, offset: u64) -> Address { Address(self.0 + offset) }
50}
51
52impl Hash for Address {
53 fn hash<H: Hasher>(&self, state: &mut H) {
54 state.write(&self.0.to_be_bytes());
55 }
56}
57
58impl Identifier for Address {
59 fn to_usize(&self) -> usize { self.to_u64() as usize }
61}
62
63#[derive(Copy, Clone, Eq, PartialEq)]
65pub struct Area {
66 start: Address,
67 len: usize,
68 count: usize,
69}
70
71impl Area {
72 pub fn new(start: Address, item_size: usize, item_count: usize) -> Self {
74 Self { start, len: item_size, count: item_count }
75 }
76
77 pub fn region(start: Address, count: usize) -> Self { Self::new(start, 1, count) }
79
80 pub fn from(start: Address, end: Address) -> Self {
82 if start > end {
83 panic!("start > end")
84 }
85 Self::new(start, 1, end.to_usize() - start.to_usize())
86 }
87
88 pub fn count(&self) -> usize { self.count }
90
91 pub fn size(&self) -> usize { self.offset(self.count) }
93
94 pub fn is_null(&self) -> bool { self.size() == 0 }
96
97 pub fn start(&self) -> Address { self.start }
99
100 pub fn end(&self) -> Address { self.start.offset(self.size() as u64) }
102
103 pub fn constraint(&self, pointer: Address) -> Address {
105 match pointer {
106 Address(addr) if addr < self.start.to_u64() => self.start,
107 Address(addr) if addr > self.end().to_u64() => self.end(),
108 address => address
109 }
110 }
111
112 pub fn offset(&self, index: usize) -> usize { self.len * index }
114
115 pub fn next_address(&self, cursor: Address) -> Address {
117 let cursor = cursor.offset(self.offset(1) as u64);
118 self.constraint(cursor)
119 }
120}
121
122impl Hash for Area {
123 fn hash<H: Hasher>(&self, state: &mut H) {
124 state.write(&self.to_usize().to_be_bytes())
125 }
126}
127
128impl Identifier for Area {
129 fn to_usize(&self) -> usize { self.offset(0) }
131}
132
133#[derive(Copy, Clone, Eq, PartialEq)]
135pub struct Cursor {
136 pub area: Area,
138 pointer: Address,
139}
140
141impl Cursor {
142 pub fn new(area: Area) -> Self {
144 Self { area, pointer: area.start }
145 }
146
147 pub fn next(&self) -> Address { self.area.next_address(self.pointer) }
149
150 pub fn current(&self) -> Address { self.pointer }
152
153 pub fn advance(&mut self) {
155 self.pointer = self.next();
156 }
157
158 pub fn reset(&mut self) { self.pointer = self.area.start; }
160}
161
162impl Hash for Cursor {
163 fn hash<H: Hasher>(&self, state: &mut H) {
164 state.write(&self.to_usize().to_be_bytes())
165 }
166}
167
168impl Identifier for Cursor {
169 fn to_usize(&self) -> usize { self.current().to_usize() }
171}