state_engine/common/bit.rs
1/// Key record: 64-bit fixed-length record for Trie nodes.
2///
3/// Layout (MSB to LSB):
4/// | category | field | bits | offset |
5/// |-------------|---------------|-------|--------|
6/// | flags | is_path | 1 | 63 |
7/// | flags | has_children | 1 | 62 |
8/// | flags | is_leaf | 1 | 61 |
9/// | key index | root index | 2 | 59 |
10/// | key index | client index | 4 | 55 |
11/// | key index | prop index | 4 | 51 |
12/// | key index | type index | 5 | 46 |
13/// | key index | dynamic index | 16 | 30 |
14/// | child index | child index | 16 | 14 |
15/// | padding | - | 14 | 0 |
16
17/// Value object record: 128-bit (2×u64) fixed-length record for YAML values.
18///
19/// Layout (MSB to LSB), vo = [u64; 2]:
20/// | word | category | field | bits | offset |
21/// |-------|----------|---------------|------|--------|
22/// | vo[0] | flags | is_template | 1 | 63 |
23/// | vo[0] | token[0] | is_path | 1 | 62 |
24/// | vo[0] | token[0] | dynamic index | 16 | 46 |
25/// | vo[0] | token[1] | is_path | 1 | 45 |
26/// | vo[0] | token[1] | dynamic index | 16 | 29 |
27/// | vo[0] | token[2] | is_path | 1 | 28 |
28/// | vo[0] | token[2] | dynamic index | 16 | 12 |
29/// | vo[0] | padding | - | 12 | 0 |
30/// | vo[1] | token[3] | is_path | 1 | 63 |
31/// | vo[1] | token[3] | dynamic index | 16 | 47 |
32/// | vo[1] | token[4] | is_path | 1 | 46 |
33/// | vo[1] | token[4] | dynamic index | 16 | 30 |
34/// | vo[1] | token[5] | is_path | 1 | 29 |
35/// | vo[1] | token[5] | dynamic index | 16 | 13 |
36/// | vo[1] | padding | - | 13 | 0 |
37
38// vo[0] offsets
39pub const VO_OFFSET_IS_TEMPLATE: u32 = 63;
40pub const VO_OFFSET_T0_IS_PATH: u32 = 62;
41pub const VO_OFFSET_T0_DYNAMIC: u32 = 46;
42pub const VO_OFFSET_T1_IS_PATH: u32 = 45;
43pub const VO_OFFSET_T1_DYNAMIC: u32 = 29;
44pub const VO_OFFSET_T2_IS_PATH: u32 = 28;
45pub const VO_OFFSET_T2_DYNAMIC: u32 = 12;
46
47// vo[1] offsets
48pub const VO_OFFSET_T3_IS_PATH: u32 = 63;
49pub const VO_OFFSET_T3_DYNAMIC: u32 = 47;
50pub const VO_OFFSET_T4_IS_PATH: u32 = 46;
51pub const VO_OFFSET_T4_DYNAMIC: u32 = 30;
52pub const VO_OFFSET_T5_IS_PATH: u32 = 29;
53pub const VO_OFFSET_T5_DYNAMIC: u32 = 13;
54
55// vo masks (shared)
56pub const VO_MASK_IS_TEMPLATE: u64 = 0x1;
57pub const VO_MASK_IS_PATH: u64 = 0x1;
58pub const VO_MASK_DYNAMIC: u64 = 0xFFFF;
59
60// --- key record offsets ---
61
62pub const OFFSET_IS_PATH: u32 = 63;
63pub const OFFSET_HAS_CHILDREN: u32 = 62;
64pub const OFFSET_IS_LEAF: u32 = 61;
65pub const OFFSET_ROOT: u32 = 59;
66pub const OFFSET_CLIENT: u32 = 55;
67pub const OFFSET_PROP: u32 = 51;
68pub const OFFSET_TYPE: u32 = 46;
69pub const OFFSET_DYNAMIC: u32 = 30;
70pub const OFFSET_CHILD: u32 = 14;
71
72// --- key record masks ---
73
74pub const MASK_IS_PATH: u64 = 0x1;
75pub const MASK_HAS_CHILDREN: u64 = 0x1;
76pub const MASK_IS_LEAF: u64 = 0x1;
77pub const MASK_ROOT: u64 = 0x3;
78pub const MASK_CLIENT: u64 = 0xF;
79pub const MASK_PROP: u64 = 0xF;
80pub const MASK_TYPE: u64 = 0x1F;
81pub const MASK_DYNAMIC: u64 = 0xFFFF;
82pub const MASK_CHILD: u64 = 0xFFFF;
83
84/// # Examples
85///
86/// ```
87/// use state_engine::common::bit;
88///
89/// let ko = bit::new();
90/// assert_eq!(ko, 0u64);
91/// ```
92// --- pool values ---
93
94// root pool (2bit)
95pub const ROOT_NULL: u64 = 0b00; // field key
96pub const ROOT_LOAD: u64 = 0b01;
97pub const ROOT_STORE: u64 = 0b10;
98pub const ROOT_STATE: u64 = 0b11;
99
100// client pool (4bit)
101pub const CLIENT_NULL: u64 = 0b0000;
102pub const CLIENT_STATE: u64 = 0b0001;
103pub const CLIENT_IN_MEMORY:u64 = 0b0010;
104pub const CLIENT_ENV: u64 = 0b0011;
105pub const CLIENT_KVS: u64 = 0b0100;
106pub const CLIENT_DB: u64 = 0b0101;
107pub const CLIENT_API: u64 = 0b0110;
108pub const CLIENT_FILE: u64 = 0b0111;
109
110// prop pool (4bit)
111pub const PROP_NULL: u64 = 0b0000;
112pub const PROP_TYPE: u64 = 0b0001;
113pub const PROP_KEY: u64 = 0b0010;
114pub const PROP_CONNECTION: u64 = 0b0011;
115pub const PROP_MAP: u64 = 0b0100;
116pub const PROP_TTL: u64 = 0b0101;
117pub const PROP_TABLE: u64 = 0b0110;
118pub const PROP_WHERE: u64 = 0b0111;
119
120// type pool (5bit)
121pub const TYPE_NULL: u64 = 0b00000;
122pub const TYPE_I32: u64 = 0b00100;
123pub const TYPE_I64: u64 = 0b00101; // "integer"
124pub const TYPE_U32: u64 = 0b00110;
125pub const TYPE_U64: u64 = 0b00111;
126pub const TYPE_UTF8: u64 = 0b01000; // "string"
127pub const TYPE_ASCII: u64 = 0b01001;
128pub const TYPE_DATETIME: u64 = 0b01010;
129pub const TYPE_F32: u64 = 0b01100;
130pub const TYPE_F64: u64 = 0b01101; // "float"
131pub const TYPE_BOOLEAN: u64 = 0b11100;
132
133pub fn new() -> u64 {
134 0
135}
136
137/// Reads a field from a key object record.
138///
139/// # Examples
140///
141/// ```
142/// use state_engine::common::bit;
143///
144/// let ko = 0b11u64 << bit::OFFSET_ROOT; // root index at offset 59
145/// assert_eq!(bit::get(ko, bit::OFFSET_ROOT, bit::MASK_ROOT), 0b11);
146/// ```
147pub fn get(ko: u64, offset: u32, mask: u64) -> u64 {
148 (ko >> offset) & mask
149}
150
151/// Writes a field into a key object record, returning the updated value.
152/// Adjacent fields are not affected.
153///
154/// # Examples
155///
156/// ```
157/// use state_engine::common::bit;
158///
159/// let ko = bit::new();
160///
161/// // set root index to 0b01 (load)
162/// let ko = bit::set(ko, bit::OFFSET_ROOT, bit::MASK_ROOT, 0b01);
163/// assert_eq!(bit::get(ko, bit::OFFSET_ROOT, bit::MASK_ROOT), 0b01);
164///
165/// // set client index to 0b0101 (Db), root must be unchanged
166/// let ko = bit::set(ko, bit::OFFSET_CLIENT, bit::MASK_CLIENT, 0b0101);
167/// assert_eq!(bit::get(ko, bit::OFFSET_CLIENT, bit::MASK_CLIENT), 0b0101);
168/// assert_eq!(bit::get(ko, bit::OFFSET_ROOT, bit::MASK_ROOT), 0b01);
169///
170/// // overwrite clamps to field width
171/// let ko = bit::set(ko, bit::OFFSET_ROOT, bit::MASK_ROOT, 0xFF);
172/// assert_eq!(bit::get(ko, bit::OFFSET_ROOT, bit::MASK_ROOT), 0b11);
173/// ```
174pub fn set(ko: u64, offset: u32, mask: u64, value: u64) -> u64 {
175 (ko & !(mask << offset)) | ((value & mask) << offset)
176}