1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use std::cmp::Ordering;
use idx_sized::{
IdxSized
,Removed
,Avltriee
};
use various_data_file::VariousDataFile;
pub mod entity;
use entity::FieldEntity;
pub struct FieldData{
index: IdxSized<FieldEntity>
,data_file:VariousDataFile
}
impl FieldData{
pub fn new(path_prefix:&str)->Result<Self,std::io::Error>{
let index=IdxSized::new(&(path_prefix.to_string()+".i"))?;
let data_file=VariousDataFile::new(&(path_prefix.to_string()+".d"))?;
Ok(FieldData{
index
,data_file
})
}
pub fn entity(&self,row:u32)->Option<&FieldEntity>{
if let Some(v)=self.index.triee().value(row){
Some(&v)
}else{
None
}
}
pub fn get<'a>(&self,row:u32)->Option<&'a [u8]>{
if let Some(e)=self.entity(row){
Some(unsafe{
std::slice::from_raw_parts(self.data_file.offset(e.addr()) as *const u8,e.len())
})
}else{
None
}
}
pub fn num(&self,row:u32)->Option<f64>{
if let Some(e)=self.entity(row){
Some(e.num())
}else{
None
}
}
pub fn index(&self)->&IdxSized<FieldEntity>{
&self.index
}
pub fn triee(&self)->&Avltriee<FieldEntity>{
&self.index.triee()
}
pub fn update(&mut self,row:u32,content:&[u8])->Result<u32,std::io::Error>{
if let Removed::Last(data)=self.index.delete(row){
self.data_file.remove(&data.data_address()); }
let cont_str=std::str::from_utf8(content).unwrap();
let tree=self.index.triee();
let (ord,found_row)=tree.search_cb(|data|->Ordering{
let bytes=self.data_file.bytes(data.data_address());
if content==bytes{
Ordering::Equal
}else{
natord::compare(cont_str,std::str::from_utf8(bytes).unwrap())
}
});
if ord==Ordering::Equal && found_row!=0{
self.index.insert_same(found_row,row)
}else{
let data_address=self.data_file.insert(content)?;
let e=FieldEntity::new(
data_address.address()
,cont_str.parse().unwrap_or(0.0)
);
if let Some(_entity)=self.index.triee().node(row){
self.index.triee_mut().update_node(
found_row
,row
,e
,ord
);
Ok(row)
}else{
self.index.insert_unique(e,found_row,ord,row)
}
}
}
pub fn delete(&mut self,row:u32){
self.index.delete(row);
}
pub(crate) fn search_cb(&self,cont:&[u8])->(Ordering,u32){
self.index.triee().search_cb(|data|->Ordering{
let str2=unsafe{
std::slice::from_raw_parts(self.data_file.offset(data.addr()) as *const u8,data.len())
};
if cont==str2{
Ordering::Equal
}else{
natord::compare(
std::str::from_utf8(cont).unwrap()
,std::str::from_utf8(str2).unwrap()
)
}
})
}
}