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
116
use file_mmap::FileMmap;
mod flagment;
#[derive(Clone,Default,PartialEq)]
pub struct DataAddress{
offset:i64
,len:u64
}
impl DataAddress{
pub fn offset(&self)->i64{
self.offset
}
pub fn len(&self)->u64{
self.len
}
}
pub struct Data<'a>{
address:DataAddress
,data:&'a VariousDataFile
}
impl Data<'_>{
pub fn bytes(&self)->&[u8]{
unsafe{
self.data.bytes(&self.address)
}
}
pub fn address(&self)->&DataAddress{
&self.address
}
}
pub struct VariousDataFile{
filemmap:FileMmap
,fragment:flagment::Fragment
}
impl VariousDataFile{
pub fn new(path:&str) -> Result<Self,std::io::Error>{
let filemmap=FileMmap::new(path,1)?;
let fragment=flagment::Fragment::new(&(path.to_string()+".f"))?;
Ok(VariousDataFile{
filemmap
,fragment
})
}
pub unsafe fn bytes(&self,word:&DataAddress)->&[u8] {
self.filemmap.bytes(word.offset() as isize,word.len as usize)
}
pub unsafe fn offset(&self,addr:isize)->*const i8{
self.filemmap.offset(addr)
}
pub fn insert(&mut self,target:&[u8])->Result<Data,std::io::Error>{
let len=target.len() as u64;
match self.fragment.search_blank(len){
Some(r)=>{
unsafe{
self.filemmap.write(r.string_addr,target);
self.fragment.release(r.fragment_id,len);
}
Ok(Data{
address:DataAddress{offset:r.string_addr as i64,len}
,data:self
})
}
,None=>{
let addr=self.filemmap.append(target)?;
Ok(Data{
address:DataAddress{offset:addr as i64,len}
,data:self
})
}
}
}
pub unsafe fn remove(&mut self,ystr:&DataAddress){
self.filemmap.write_0(ystr.offset as isize,ystr.len);
self.fragment.insert(ystr).unwrap();
}
}
#[test]
fn test(){
let dir="./vdf-test";
if std::path::Path::new(dir).exists(){
std::fs::remove_dir_all(dir).unwrap();
std::fs::create_dir_all(dir).unwrap();
}else{
std::fs::create_dir_all(dir).unwrap();
}
if let Ok(mut s)=VariousDataFile::new(&(dir.to_owned()+"/test.str")){
let noah=s.insert(b"Noah").unwrap().address;
let liam=s.insert(b"Liam").unwrap().address;
let olivia=s.insert(b"Olivia").unwrap().address;
unsafe{s.remove(&noah);}
if let Ok(w)=s.insert(b"Renamed Noah"){
assert_eq!("Renamed Noah".to_string(),std::str::from_utf8(w.bytes()).unwrap().to_string());
}
unsafe{s.remove(&liam)};
if let Ok(w)=s.insert(b"Renamed Liam"){
assert_eq!("Renamed Liam".to_string(),std::str::from_utf8(w.bytes()).unwrap().to_string());
}
unsafe{s.remove(&olivia)};
if let Ok(w)=s.insert(b"Renamed Olivia"){
assert_eq!("Renamed Olivia".to_string(),std::str::from_utf8(w.bytes()).unwrap().to_string());
}
if let Ok(w)=s.insert(b"Noah"){
assert_eq!("Noah".to_string(),std::str::from_utf8(w.bytes()).unwrap().to_string());
}
if let Ok(w)=s.insert(b"Liam"){
assert_eq!("Liam".to_string(),std::str::from_utf8(w.bytes()).unwrap().to_string());
}
if let Ok(w)=s.insert(b"Olivia"){
assert_eq!("Olivia".to_string(),std::str::from_utf8(w.bytes()).unwrap().to_string());
}
}
}