1use plugmem_arena::{BlobId, ListHandle, Slot, TermId, key};
16
17use crate::id::{EntityId, FactId, NONE_U32};
18
19pub const VALID_TO_OPEN: u64 = u64::MAX;
21
22pub mod fact_flags {
24 pub const TOMBSTONE: u16 = 1;
26 pub const CLOSED: u16 = 1 << 1;
29 pub const HAS_VECTOR: u16 = 1 << 2;
32}
33
34#[derive(Clone, Copy, Debug, PartialEq, Eq)]
49#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
50pub struct FactRecord {
51 pub id: FactId,
53 pub entity: EntityId,
55 pub flags: u16,
57 pub kind: u16,
59 pub text: BlobId,
61 pub vector: u32,
64 pub revises: FactId,
69 pub recorded_at: u64,
71 pub valid_from: u64,
73 pub valid_to: u64,
75}
76
77impl FactRecord {
78 pub fn is_tombstone(&self) -> bool {
80 self.flags & fact_flags::TOMBSTONE != 0
81 }
82
83 pub fn is_closed(&self) -> bool {
85 self.flags & fact_flags::CLOSED != 0
86 }
87
88 pub fn has_vector(&self) -> bool {
90 self.flags & fact_flags::HAS_VECTOR != 0
91 }
92
93 pub fn is_live_at(&self, t: u64) -> bool {
96 !self.is_tombstone() && self.recorded_at <= t && self.valid_from <= t && t < self.valid_to
97 }
98}
99
100impl Slot for FactRecord {
101 const SIZE: usize = 48;
102 const KEY_LEN: usize = 4;
103
104 fn write(&self, out: &mut [u8]) {
105 key::write_u32(out, self.id.0);
106 key::write_u32(&mut out[4..], self.entity.0);
107 out[8..10].copy_from_slice(&self.flags.to_be_bytes());
108 out[10..12].copy_from_slice(&self.kind.to_be_bytes());
109 key::write_u32(&mut out[12..], self.text.0);
110 key::write_u32(&mut out[16..], self.vector);
111 key::write_u32(&mut out[20..], self.revises.0);
112 key::write_u64(&mut out[24..], self.recorded_at);
113 key::write_u64(&mut out[32..], self.valid_from);
114 key::write_u64(&mut out[40..], self.valid_to);
115 }
116
117 fn read(bytes: &[u8]) -> Self {
118 Self {
119 id: FactId(key::read_u32(bytes)),
120 entity: EntityId(key::read_u32(&bytes[4..])),
121 flags: u16::from_be_bytes(bytes[8..10].try_into().unwrap()),
122 kind: u16::from_be_bytes(bytes[10..12].try_into().unwrap()),
123 text: BlobId(key::read_u32(&bytes[12..])),
124 vector: key::read_u32(&bytes[16..]),
125 revises: FactId(key::read_u32(&bytes[20..])),
126 recorded_at: key::read_u64(&bytes[24..]),
127 valid_from: key::read_u64(&bytes[32..]),
128 valid_to: key::read_u64(&bytes[40..]),
129 }
130 }
131}
132
133#[derive(Clone, Copy, Debug, PartialEq, Eq)]
141#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
142pub struct FactAux {
143 pub id: FactId,
145 pub tags: ListHandle,
147 pub meta: BlobId,
151}
152
153impl Slot for FactAux {
154 const SIZE: usize = 20;
155 const KEY_LEN: usize = 4;
156
157 fn write(&self, out: &mut [u8]) {
158 key::write_u32(out, self.id.0);
159 out[4..16].copy_from_slice(&self.tags.to_bytes());
160 key::write_u32(&mut out[16..], self.meta.0);
161 }
162
163 fn read(bytes: &[u8]) -> Self {
164 Self {
165 id: FactId(key::read_u32(bytes)),
166 tags: ListHandle::from_bytes(bytes[4..16].try_into().unwrap()),
167 meta: BlobId(key::read_u32(&bytes[16..])),
168 }
169 }
170}
171
172#[derive(Clone, Copy, Debug, PartialEq, Eq)]
182#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
183pub struct EntityRecord {
184 pub id: EntityId,
186 pub name: BlobId,
188 pub name_term: TermId,
190 pub created_at: u64,
192 pub flags: u32,
194}
195
196impl Slot for EntityRecord {
197 const SIZE: usize = 24;
198 const KEY_LEN: usize = 4;
199
200 fn write(&self, out: &mut [u8]) {
201 key::write_u32(out, self.id.0);
202 key::write_u32(&mut out[4..], self.name.0);
203 key::write_u32(&mut out[8..], self.name_term.0);
204 key::write_u64(&mut out[12..], self.created_at);
205 key::write_u32(&mut out[20..], self.flags);
206 }
207
208 fn read(bytes: &[u8]) -> Self {
209 Self {
210 id: EntityId(key::read_u32(bytes)),
211 name: BlobId(key::read_u32(&bytes[4..])),
212 name_term: TermId(key::read_u32(&bytes[8..])),
213 created_at: key::read_u64(&bytes[12..]),
214 flags: key::read_u32(&bytes[20..]),
215 }
216 }
217}
218
219#[derive(Clone, Copy, Debug, PartialEq, Eq)]
226#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
227pub struct EntityByName {
228 pub name_term: TermId,
230 pub id: EntityId,
232}
233
234impl Slot for EntityByName {
235 const SIZE: usize = 8;
236 const KEY_LEN: usize = 8;
237
238 fn write(&self, out: &mut [u8]) {
239 key::write_u32(out, self.name_term.0);
240 key::write_u32(&mut out[4..], self.id.0);
241 }
242
243 fn read(bytes: &[u8]) -> Self {
244 Self {
245 name_term: TermId(key::read_u32(bytes)),
246 id: EntityId(key::read_u32(&bytes[4..])),
247 }
248 }
249}
250
251#[derive(Clone, Copy, Debug, PartialEq, Eq)]
260#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
261pub struct EdgeSlot {
262 pub a: EntityId,
264 pub rel: TermId,
266 pub b: EntityId,
268 pub fact: FactId,
272}
273
274impl Slot for EdgeSlot {
275 const SIZE: usize = 16;
276 const KEY_LEN: usize = 12;
277
278 fn write(&self, out: &mut [u8]) {
279 key::write_u32(out, self.a.0);
280 key::write_u32(&mut out[4..], self.rel.0);
281 key::write_u32(&mut out[8..], self.b.0);
282 key::write_u32(&mut out[12..], self.fact.0);
283 }
284
285 fn read(bytes: &[u8]) -> Self {
286 Self {
287 a: EntityId(key::read_u32(bytes)),
288 rel: TermId(key::read_u32(&bytes[4..])),
289 b: EntityId(key::read_u32(&bytes[8..])),
290 fact: FactId(key::read_u32(&bytes[12..])),
291 }
292 }
293}
294
295#[derive(Clone, Copy, Debug, PartialEq, Eq)]
301#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
302pub struct TemporalSlot {
303 pub recorded_at: u64,
305 pub fact: FactId,
307}
308
309impl Slot for TemporalSlot {
310 const SIZE: usize = 12;
311 const KEY_LEN: usize = 12;
312
313 fn write(&self, out: &mut [u8]) {
314 key::write_pair(out, self.recorded_at, self.fact.0);
315 }
316
317 fn read(bytes: &[u8]) -> Self {
318 let (recorded_at, fact) = key::read_pair(bytes);
319 Self {
320 recorded_at,
321 fact: FactId(fact),
322 }
323 }
324}
325
326const _: () = {
329 assert!(FactRecord::SIZE == 48 && FactRecord::KEY_LEN == 4);
330 assert!(FactAux::SIZE == 20 && FactAux::KEY_LEN == 4);
331 assert!(EntityRecord::SIZE == 24 && EntityRecord::KEY_LEN == 4);
332 assert!(EntityByName::SIZE == 8 && EntityByName::KEY_LEN == 8);
333 assert!(EdgeSlot::SIZE == 16 && EdgeSlot::KEY_LEN == 12);
334 assert!(TemporalSlot::SIZE == 12 && TemporalSlot::KEY_LEN == 12);
335 assert!(NONE_U32 == u32::MAX);
337};