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
use once_cell::sync::Lazy;
use std::collections::HashMap;
use crate::common::{CurrentSrc};
use crate::history::{HistoryOptions, PeekableCacheInfo};
use std::path::{PathBuf, Path};
use crate::error::FsResult;
use crate::imp::history::history_info::HistoryInfo;
use crate::imp::history::current_root_obj_info::current_root_obj_info::CurrentRootObjInfo;
use crate::imp::history::current_root_obj_info::history_cache_item::{SyncedItem, HistoryCacheItem};
use crate::imp::history::current_root_obj_info::mutex_g::MutexG;
use crate::imp::history::diff_and_cache::dochy_cache::DochyCache;
use crate::imp::history::current_root_obj_info::fifo_thread::FifoThread;
use std::sync::{Mutex, MutexGuard};
static MAP : Lazy<Mutex<HashMap<PathBuf, Box<HistoryCacheItem>>>> = Lazy::new(||{
Mutex::new(HashMap::new())
});
pub(crate) fn init_dochy_cache(history_dir : &Path, current_src : CurrentSrc, op : &HistoryOptions) -> FsResult<HistoryInfo>{
let map = MAP.lock().unwrap();
if let Some(item) = map.get(history_dir){
if item.peekable().current_src() != ¤t_src{
Err(format!("Source alternation while running is not supported {:?}", history_dir))?
} else if item.peekable().history_options() != op{
Err(format!("Changing HistoryOptions while running is not supported {:?}", history_dir))?
} else{
return Ok(HistoryInfo::new(history_dir.to_path_buf()));
}
}
init_dochy_cache_impl(map, history_dir, current_src, op)
}
pub unsafe fn init_dochy_cache_us(history_dir : &Path,
current_src : CurrentSrc,
op : &HistoryOptions) -> FsResult<HistoryInfo>{
let map = MAP.lock().unwrap();
init_dochy_cache_impl(map, history_dir, current_src, op)
}
fn init_dochy_cache_impl(mut map : MutexGuard<HashMap<PathBuf, Box<HistoryCacheItem>>>,
history_dir : &Path,
current_src : CurrentSrc,
op : &HistoryOptions) -> FsResult<HistoryInfo>{
let cache = DochyCache::new(current_src.clone())?;
let hash = cache.hash();
let src_root = cache.clone_src_root();
map.insert(history_dir.to_path_buf(), Box::new(HistoryCacheItem::new(
PeekableCacheInfo::new(
current_src,
hash,
op.clone(),
src_root),
Mutex::new(SyncedItem::new(
cache,
None))
)));
return Ok(HistoryInfo::new(history_dir.to_path_buf()));
}
pub(crate) fn get_map_item<'a>(history_dir : &Path) -> Option<&'a HistoryCacheItem>{
let ptr: *const HistoryCacheItem = {
let map = MAP.lock().unwrap();
let b = map.get(history_dir)?;
b.as_ref()
};
Some(unsafe{ &*ptr })
}
pub(crate) fn get_mutex<'a>(history_dir : &Path) -> Option<MutexG<'a>>{
let item = get_map_item(history_dir)?;
let peekable_info = item.peekable();
let guard = item.synced().lock().unwrap();
Some(MutexG::new(guard, peekable_info))
}
pub fn get_peekable_info<'a>(history_info : &HistoryInfo) -> &'a PeekableCacheInfo{
let item = get_map_item(history_info.history_dir()).unwrap();
item.peekable()
}
pub(crate) fn get_fifo_thread<'a>(history_info : &HistoryInfo) -> Option<&'a FifoThread>{
let item = get_map_item(history_info.history_dir())?;
Some(item.fifo_thread())
}
pub fn set_current_root_obj_info(history_info : &HistoryInfo, current_root_obj_info : Option<CurrentRootObjInfo>){
let m = get_map_item(history_info.history_dir()).unwrap();
let mut s = m.synced().lock().unwrap();
let (_,h) = s.muts();
*h = current_root_obj_info;
}