1pub mod search;
2
3mod field;
4mod operation;
5mod option;
6mod row_fragment;
7mod serial;
8mod sort;
9
10pub use field::{Field, FieldName, Fields};
11use idx_binary::AvltrieeSearch;
12pub use idx_binary::{self, AvltrieeIter, FileMmap, IdxBinary, IdxFile};
13pub use operation::*;
14pub use option::DataOption;
15pub use row_fragment::RowFragment;
16pub use search::{Condition, Search};
17pub use sort::{CustomOrderKey, CustomSort, Order, OrderKey};
18pub use uuid::Uuid;
19
20use std::{
21 collections::BTreeSet,
22 fs,
23 num::NonZeroU32,
24 path::{Path, PathBuf},
25 time::{SystemTime, UNIX_EPOCH},
26};
27
28use serial::SerialNumber;
29
30pub type RowSet = BTreeSet<NonZeroU32>;
31
32pub fn uuid_string(uuid: u128) -> String {
33 Uuid::from_u128(uuid).to_string()
34}
35
36pub struct Data {
37 fields_dir: PathBuf,
38 option: DataOption,
39 serial: SerialNumber,
40 uuid: Option<IdxFile<u128>>,
41 activity: Option<IdxFile<u8>>,
42 term_begin: Option<IdxFile<u64>>,
43 term_end: Option<IdxFile<u64>>,
44 last_updated: Option<IdxFile<u64>>,
45 fields: Fields,
46}
47
48impl Data {
49 pub fn new<P: AsRef<Path>>(dir: P, option: DataOption) -> Self {
51 let dir = dir.as_ref();
52 if !dir.exists() {
53 fs::create_dir_all(dir).unwrap();
54 }
55
56 let mut fields = Fields::default();
57
58 let mut fields_dir = dir.to_path_buf();
59 fields_dir.push("fields");
60 if fields_dir.exists() {
61 for d in fields_dir.read_dir().unwrap().into_iter() {
62 let d = d.unwrap();
63 if d.file_type().unwrap().is_dir() {
64 if let Some(name) = d.file_name().to_str() {
65 let field = Field::new(d.path(), option.allocation_lot);
66 fields.insert(FieldName::new(name.into()), field);
67 }
68 }
69 }
70 }
71
72 let serial = SerialNumber::new(
73 {
74 let mut path = dir.to_path_buf();
75 path.push("serial");
76 path
77 },
78 option.allocation_lot,
79 );
80 let uuid = option.uuid.then(|| {
81 IdxFile::new(
82 {
83 let mut path = dir.to_path_buf();
84 path.push("uuid.i");
85 path
86 },
87 option.allocation_lot,
88 )
89 });
90 let activity = option.activity.then(|| {
91 IdxFile::new(
92 {
93 let mut path = dir.to_path_buf();
94 path.push("activity.i");
95 path
96 },
97 option.allocation_lot,
98 )
99 });
100 let term_begin = option.term.then(|| {
101 IdxFile::new(
102 {
103 let mut path = dir.to_path_buf();
104 path.push("term_begin.i");
105 path
106 },
107 option.allocation_lot,
108 )
109 });
110 let term_end = option.term.then(|| {
111 IdxFile::new(
112 {
113 let mut path = dir.to_path_buf();
114 path.push("term_end.i");
115 path
116 },
117 option.allocation_lot,
118 )
119 });
120 let last_updated = option.last_updated.then(|| {
121 IdxFile::new(
122 {
123 let mut path = dir.to_path_buf();
124 path.push("last_updated.i");
125 path
126 },
127 option.allocation_lot,
128 )
129 });
130
131 Self {
132 fields_dir,
133 option,
134 serial,
135 uuid,
136 activity,
137 term_begin,
138 term_end,
139 last_updated,
140 fields,
141 }
142 }
143
144 pub fn serial(&self, row: NonZeroU32) -> &u32 {
146 unsafe { self.serial.value_unchecked(row) }
147 }
148
149 pub fn uuid(&self, row: NonZeroU32) -> Option<&u128> {
151 self.uuid.as_ref().and_then(|uuid| uuid.value(row))
152 }
153
154 pub fn uuid_string(&self, row: NonZeroU32) -> Option<String> {
156 self.uuid.as_ref().and_then(|uuid| {
157 uuid.value(row)
158 .map(|v| uuid::Uuid::from_u128(*v).to_string())
159 })
160 }
161
162 pub fn activity(&self, row: NonZeroU32) -> Option<Activity> {
164 self.activity.as_ref().and_then(|a| {
165 a.value(row).map(|v| {
166 if *v != 0 {
167 Activity::Active
168 } else {
169 Activity::Inactive
170 }
171 })
172 })
173 }
174
175 pub fn term_begin(&self, row: NonZeroU32) -> Option<&u64> {
177 self.term_begin.as_ref().and_then(|f| f.value(row))
178 }
179
180 pub fn term_end(&self, row: NonZeroU32) -> Option<&u64> {
182 self.term_end.as_ref().and_then(|f| f.value(row))
183 }
184
185 pub fn last_updated(&self, row: NonZeroU32) -> Option<&u64> {
187 self.last_updated.as_ref().and_then(|f| f.value(row))
188 }
189
190 pub fn all(&self) -> RowSet {
192 self.serial.iter().collect()
193 }
194
195 fn now() -> u64 {
196 SystemTime::now()
197 .duration_since(UNIX_EPOCH)
198 .unwrap()
199 .as_secs()
200 }
201}