1use crate::*;
2use pstd::veca;
3use std::hash::Hasher;
4
5const SCHEMA: usize = 0;
7const TABLE: usize = 1;
8
9const OBJ_ID: usize = 0;
11const _OBJ_SCHEMA: usize = 1;
12const OBJ_NAME: usize = 2;
13const OBJ_INNER: usize = 3;
14
15pub fn make_obj_dt() -> DataType {
17 use pstd::veca;
18
19 let objenum = DataType::Enum(veca![
20 (LString::from("Schema"), DataType::Empty),
21 (LString::from("Table"), DataType::TabInfo),
22 ]);
23
24 DataType::Struct(veca![
25 (LString::from("Id"), DataType::Int),
26 (LString::from("Schema"), DataType::Int),
27 (LString::from("Name"), DataType::String),
28 (LString::from("Inner"), objenum),
29 ])
30}
31
32pub struct IdKey<'a> {
34 pub rid: i64,
35 pub dt: &'a DataType,
36}
37
38impl<'a> IdKey<'a> {
39 pub fn insert(&self, r: &Value, main: &mut BuckMapInfo, ps: &mut PageSet) {
40 let addr = VarValAddr::new(self.dt, r, ps);
42
43 let mut bm = BuckMap::restore(*main, ps);
45 bm.insert(self, addr);
46 if bm.root_changed() {
47 *main = bm.save();
48 }
49 }
50}
51
52impl<'a> Hash for IdKey<'a> {
53 fn hash<H: Hasher>(&self, h: &mut H) {
54 self.rid.hash(h);
55 }
56}
57
58impl<'a> Key<VarValAddr> for IdKey<'a> {
59 fn ok(&self, addr: VarValAddr, ps: &mut PageSet) -> Option<(VarValAddr, Value)> {
60 let v = addr.get(self.dt, ps);
61 let rid = v.list()[0].int();
62 if rid == self.rid {
63 return Some((addr, v));
64 }
65 None
66 }
67}
68
69pub fn get_obj(rid: i64, ps: &mut PageSet) -> Option<(VarValAddr, Value)> {
71 let dt = ps.obj_dt.clone();
72 let key = IdKey { rid, dt: &dt };
73 BuckMap::restore(ps.obj_map, ps).get(&key)
74}
75
76#[derive(Hash)]
77pub struct ObjNameKey<'a> {
78 name: &'a str,
79}
80
81impl<'a> Key<i64> for ObjNameKey<'a> {
82 fn ok(&self, addr: i64, ps: &mut PageSet) -> Option<(i64, Value)> {
83 let (_, v) = get_obj(addr, ps).unwrap();
84 let name = v.list()[OBJ_NAME].string();
85 if self.name == name {
86 return Some((addr, v));
87 }
88 None
89 }
90}
91
92pub fn list_obj_all(ps: &mut PageSet) {
94 let mut x = BuckMap::<VarValAddr>::restore(ps.obj_map, ps).all_addr();
95
96 x.sort();
97
98 let dt = ps.obj_dt.clone();
99
100 for addr in x {
101 let r = addr.get(&dt, ps);
102 println!("list_obj_all addr={:?} r={:?}", addr, r);
103 }
104}
105
106fn create_obj_inner(rid: i64, r: Value, ps: &mut PageSet) {
108 let dt = ps.obj_dt.clone();
109
110 let addr = VarValAddr::new(&dt, &r, ps);
111
112 let key = IdKey { rid, dt: &dt };
113
114 let mut bm = BuckMap::restore(ps.obj_map, ps);
115 bm.insert(&key, addr);
116 if bm.root_changed() {
117 ps.obj_map = bm.save();
118 }
119}
120
121fn index_obj_by_name(id: i64, name: &str, ps: &mut PageSet) {
123 let key = ObjNameKey { name };
124 let mut bm = BuckMap::restore(ps.obj_by_name, ps);
125 bm.insert(&key, id);
126 if bm.root_changed() {
127 ps.obj_by_name = bm.save();
128 }
129}
130
131pub fn create_obj(rid: i64, name: &str, inner: Value, ps: &mut PageSet) {
133 let r = Value::List(veca![
134 Value::Int(rid), Value::Int(0), Value::String(LString::from(name)),
137 inner
138 ]);
139
140 create_obj_inner(rid, r, ps);
141 index_obj_by_name(rid, name, ps);
142}
143
144pub fn get_obj_from_name(name: &str, ps: &mut PageSet) -> Option<(i64, Value)> {
146 let key = ObjNameKey { name };
147
148 let mut bm = BuckMap::restore(ps.obj_by_name, ps);
149 if let Some(x) = bm.get(&key) {
150 return Some(x);
151 }
152 None
153}
154
155pub fn save_obj(addr: VarValAddr, obj: Value, ps: &mut PageSet) {
157 let dt = ps.obj_dt.clone();
158 let addr2 = addr.update(&dt, &obj, ps);
159 if addr2 != addr {
160 let rid = obj.list()[OBJ_ID].int();
161 let key = IdKey { rid, dt: &dt };
162
163 let mut bm = BuckMap::restore(ps.obj_map, ps);
164 bm.remove(&key);
165 bm.insert(&key, addr2);
166 if bm.root_changed() {
167 ps.obj_map = bm.save();
168 }
169 }
170}
171
172pub fn create_schema(name: &str, ps: &mut PageSet) -> Option<(i64, Value)> {
174 let obj = get_obj_from_name(name, ps);
176
177 if obj.is_some() {
178 obj
179 } else {
180 let rid = ps.next_obj_id;
181 ps.next_obj_id = rid + 1;
182 let inner = Value::Enum(SCHEMA, LBox::new(Value::Empty));
183 create_obj(rid, name, inner, ps);
184 None
185 }
186}
187
188fn set_table_datatype(rid: i64, tdt: DataType, ps: &mut PageSet) {
189 let dt = DataType::Tuple(veca![DataType::Int, DataType::DataType]);
190 let v = Value::List(veca![Value::Int(rid), Value::DataType(tdt)]);
191
192 let addr = VarValAddr::new(&dt, &v, ps);
193 let key = IdKey { rid, dt: &dt };
194 let mut bm = BuckMap::restore(ps.table_datatype_map, ps);
195 bm.insert(&key, addr);
196 if bm.root_changed() {
197 ps.table_datatype_map = bm.save();
198 }
199}
200
201pub fn get_table_datatype(rid: i64, ps: &mut PageSet) -> DataType {
203 let dt = DataType::Tuple(veca![DataType::Int, DataType::DataType]);
204 let key = IdKey { rid, dt: &dt };
205 let mut bm = BuckMap::restore(ps.table_datatype_map, ps);
206 let mut av = bm.get(&key).unwrap();
207 let dt = av.1.list_mut()[1].datatype_mut();
208 std::mem::take(dt)
209}
210
211pub fn create_table(
213 name: &str,
214 dt: DataType,
215 ix_count: usize,
216 ps: &mut PageSet,
217) -> Option<(i64, Value)> {
218 let obj = get_obj_from_name(name, ps);
220
221 if obj.is_some() {
222 obj
223 } else {
224 let rid = ps.next_obj_id;
225 ps.next_obj_id = rid + 1;
226
227 let bm = BuckMap::<VarValAddr>::new(1, ps);
228 let main = bm.save();
229
230 let mut index = LVec::new();
231 for _ in 0..ix_count {
232 let bm = BuckMap::<VarValAddr>::new(1, ps);
233 index.push(bm.save());
234 }
235
236 let tableinfo = Value::TabInfo(TabInfo {
237 alloc: 0,
238 main,
239 index,
240 });
241
242 let inner = Value::Enum(TABLE, LBox::new(tableinfo));
243
244 create_obj(rid, name, inner, ps);
245
246 set_table_datatype(rid, dt, ps);
247
248 None
249 }
250}
251
252#[derive(
253 Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
254)]
255pub struct TabInfo {
256 alloc: i64,
257 pub main: BuckMapInfo,
258 pub index: LVec<BuckMapInfo>,
259}
260
261impl TabInfo {
262 pub fn id(&mut self) -> i64 {
263 let result = self.alloc;
264 self.alloc += 1;
265 result
266 }
267 pub fn to_bytes(&self) -> Vec<u8> {
268 postcard::to_stdvec(self).unwrap()
269 }
270 pub fn from_bytes(b: &[u8]) -> Self {
271 postcard::from_bytes(b).unwrap()
272 }
273}
274
275pub fn decode_table(obj: &mut Value) -> &mut TabInfo {
277 let (tag, inner) = obj.list_mut()[OBJ_INNER].en_mut();
278 assert!(*tag == TABLE);
279 inner.tabinfo_mut()
280}
281
282pub fn save_table(rid: i64, obj: Value, ps: &mut PageSet) {
284 let (addr, _) = get_obj(rid, ps).unwrap();
285 save_obj(addr, obj, ps);
286}