Skip to main content

state_engine/core/
fixed_bits.rs

1// fixed bits record for intern pools
2// note:
3// - Value 0 means null in each field.
4
5// key record (64 bits)
6//
7// | category    | field         | bits | offset |
8// |-------------|---------------|------|--------|
9// | flags       | is_path       |    1 |     63 |
10// | flags       | has_children  |    1 |     62 |
11// | flags       | is_leaf       |    1 |     61 |
12// | key index   | root index    |    2 |     59 |
13// | key index   | client index  |    4 |     55 |
14// | key index   | prop index    |    4 |     51 |
15// | key index   | type index    |    5 |     46 |
16// | key index   | dynamic index |   16 |     30 |
17// | child index | child index   |   16 |     14 |
18// | padding     | -             |   14 |      0 |
19
20// value record (128 bits, [u64; 2])
21//
22// | category | field         | bits | offset |
23// |----------|---------------|------|--------|
24// | flags    | is_template   |    1 |     63 |
25// | token[0] | is_path       |    1 |     62 |
26// | token[0] | dynamic index |   16 |     46 |
27// | token[1] | is_path       |    1 |     45 |
28// | token[1] | dynamic index |   16 |     29 |
29// | token[2] | is_path       |    1 |     28 |
30// | token[2] | dynamic index |   16 |     12 |
31// | padding  | -             |   12 |      0 |
32// | token[3] | is_path       |    1 |     63 |
33// | token[3] | dynamic index |   16 |     47 |
34// | token[4] | is_path       |    1 |     46 |
35// | token[4] | dynamic index |   16 |     30 |
36// | token[5] | is_path       |    1 |     29 |
37// | token[5] | dynamic index |   16 |     13 |
38// | padding  | -             |   13 |      0 |
39
40// --- key record offsets ---
41
42pub const K_OFFSET_IS_PATH: u32      = 63;
43pub const K_OFFSET_HAS_CHILDREN: u32 = 62;
44pub const K_OFFSET_IS_LEAF: u32      = 61;
45pub const K_OFFSET_ROOT: u32         = 59;
46pub const K_OFFSET_CLIENT: u32       = 55;
47pub const K_OFFSET_PROP: u32         = 51;
48pub const K_OFFSET_TYPE: u32         = 46;
49pub const K_OFFSET_DYNAMIC: u32      = 30;
50pub const K_OFFSET_CHILD: u32        = 14;
51
52// --- key record masks ---
53
54pub const K_MASK_IS_PATH: u64      = 0x1;
55pub const K_MASK_HAS_CHILDREN: u64 = 0x1;
56pub const K_MASK_IS_LEAF: u64      = 0x1;
57pub const K_MASK_ROOT: u64         = 0x3;
58pub const K_MASK_CLIENT: u64       = 0xF;
59pub const K_MASK_PROP: u64         = 0xF;
60pub const K_MASK_TYPE: u64         = 0x1F;
61pub const K_MASK_DYNAMIC: u64      = 0xFFFF;
62pub const K_MASK_CHILD: u64        = 0xFFFF;
63
64// --- value record offsets ---
65
66pub const V_OFFSET_IS_TEMPLATE: u32 = 63;
67pub const V_OFFSET_T0_IS_PATH: u32  = 62;
68pub const V_OFFSET_T0_DYNAMIC: u32  = 46;
69pub const V_OFFSET_T1_IS_PATH: u32  = 45;
70pub const V_OFFSET_T1_DYNAMIC: u32  = 29;
71pub const V_OFFSET_T2_IS_PATH: u32  = 28;
72pub const V_OFFSET_T2_DYNAMIC: u32  = 12;
73
74pub const V_OFFSET_T3_IS_PATH: u32  = 63;
75pub const V_OFFSET_T3_DYNAMIC: u32  = 47;
76pub const V_OFFSET_T4_IS_PATH: u32  = 46;
77pub const V_OFFSET_T4_DYNAMIC: u32  = 30;
78pub const V_OFFSET_T5_IS_PATH: u32  = 29;
79pub const V_OFFSET_T5_DYNAMIC: u32  = 13;
80
81// --- value record masks ---
82
83pub const V_MASK_IS_TEMPLATE: u64 = 0x1;
84pub const V_MASK_IS_PATH: u64     = 0x1;
85pub const V_MASK_DYNAMIC: u64     = 0xFFFF;
86
87// --- static ---
88
89pub const ROOT_NULL:  u64 = 0b00; // means field key
90pub const ROOT_LOAD:  u64 = 0b01;
91pub const ROOT_STORE: u64 = 0b10;
92pub const ROOT_STATE: u64 = 0b11;
93
94pub const CLIENT_NULL:      u64 = 0b0000;
95pub const CLIENT_STATE:     u64 = 0b0001;
96pub const CLIENT_IN_MEMORY: u64 = 0b0010;
97pub const CLIENT_ENV:       u64 = 0b0011;
98pub const CLIENT_KVS:       u64 = 0b0100;
99pub const CLIENT_DB:        u64 = 0b0101;
100pub const CLIENT_HTTP:       u64 = 0b0110;
101pub const CLIENT_FILE:      u64 = 0b0111;
102
103pub const PROP_NULL:       u64 = 0b0000;
104pub const PROP_TYPE:       u64 = 0b0001;
105pub const PROP_KEY:        u64 = 0b0010;
106pub const PROP_CONNECTION: u64 = 0b0011;
107pub const PROP_MAP:        u64 = 0b0100;
108pub const PROP_TTL:        u64 = 0b0101;
109pub const PROP_TABLE:      u64 = 0b0110;
110pub const PROP_WHERE:      u64 = 0b0111;
111pub const PROP_URL:        u64 = 0b1000;
112pub const PROP_HEADERS:    u64 = 0b1001;
113
114pub const TYPE_NULL:     u64 = 0b00000;
115pub const TYPE_I32:      u64 = 0b00100;
116pub const TYPE_I64:      u64 = 0b00101; // "integer"
117pub const TYPE_U32:      u64 = 0b00110;
118pub const TYPE_U64:      u64 = 0b00111;
119pub const TYPE_UTF8:     u64 = 0b01000; // "string"
120pub const TYPE_ASCII:    u64 = 0b01001;
121pub const TYPE_DATETIME: u64 = 0b01010;
122pub const TYPE_F32:      u64 = 0b01100;
123pub const TYPE_F64:      u64 = 0b01101; // "float"
124pub const TYPE_BOOLEAN:  u64 = 0b11100;
125
126pub fn new() -> u64 {
127    0
128}
129
130pub fn get(ko: u64, offset: u32, mask: u64) -> u64 {
131    (ko >> offset) & mask
132}
133
134pub fn set(ko: u64, offset: u32, mask: u64, value: u64) -> u64 {
135    (ko & !(mask << offset)) | ((value & mask) << offset)
136}
137
138#[cfg(test)]
139mod tests {
140    use super::*;
141
142    #[test]
143    fn test_set_get_independent_fields() {
144        let ko = new();
145        let ko = set(ko, K_OFFSET_ROOT, K_MASK_ROOT, 0b01);
146        assert_eq!(get(ko, K_OFFSET_ROOT, K_MASK_ROOT), 0b01);
147
148        let ko = set(ko, K_OFFSET_CLIENT, K_MASK_CLIENT, 0b0101);
149        assert_eq!(get(ko, K_OFFSET_CLIENT, K_MASK_CLIENT), 0b0101);
150        assert_eq!(get(ko, K_OFFSET_ROOT, K_MASK_ROOT), 0b01);
151    }
152
153    #[test]
154    fn test_set_clamps_to_field_width() {
155        let ko = set(new(), K_OFFSET_ROOT, K_MASK_ROOT, 0xFF);
156        assert_eq!(get(ko, K_OFFSET_ROOT, K_MASK_ROOT), K_MASK_ROOT);
157    }
158}