1use failure::Error;
2use keys_iterator::StoreKeys;
3use serde_yaml;
4use std;
5use std::fs::File;
6use std::path::{Path, PathBuf};
7use std::sync::Arc;
8use std::hash::Hash;
9use store::Store;
10use std::borrow::Borrow;
11
12pub type Key = Vec<u8>;
13pub type Value = Vec<u8>;
14pub type Result<T> = std::result::Result<T, Error>;
15
16#[derive(Builder, Clone)]
17#[builder(default)]
18#[derive(Serialize, Deserialize, Debug)]
19pub struct Config {
20 pub path: PathBuf,
21 pub max_size_per_segment: u64,
22 pub max_file_id: u64,
23 pub min_merge_file_id: u64,
24}
25
26impl Default for Config {
27 fn default() -> Self {
28 Config {
29 path: std::env::current_dir().expect("get current dir"),
30 max_size_per_segment: 100_000_000,
31 max_file_id: 1_000_000_000,
32 min_merge_file_id: 100_000_000_000,
33 }
34 }
35}
36
37impl Config {
38 pub fn new<T: AsRef<Path>>(config_path: T) -> Self {
39 let mut file = File::open(config_path).expect("open config path");
40 let config: Config = serde_yaml::from_reader(&mut file).expect("deserialize config file");
41 return config;
42 }
43}
44
45pub struct Bitcask {
46 config: Arc<Config>,
47 store: Arc<Store>,
48}
49
50impl Bitcask {
51 pub fn new(config: Config) -> Self {
52 let arc_config = Arc::new(config);
53
54 Bitcask {
55 store: Arc::new(Store::new(arc_config.clone())),
56 config: arc_config,
57 }
58 }
59
60 pub fn open(config: Config) -> Self {
61 let arc_config = Arc::new(config);
62 Bitcask {
63 store: Arc::new(Store::open(arc_config.clone())),
64 config: arc_config,
65 }
66 }
67
68 pub fn get<Q>(&self, key: &Q) -> Result<Option<Value>>
69 where Key: Borrow<Q>,
70 Q: Eq + Hash + ?Sized {
71 self.store.get(key)
72 }
73
74 pub fn set(&mut self, key: Key, value: Value) -> Result<()> {
75 self.store.insert(key, value)
76 }
77
78 pub fn delete(&mut self, key: Key) -> Result<()> {
79 self.store.delete(key)
80 }
81
82 pub fn exists(&self, key: &Key) -> Result<bool> {
83 self.store.exists(key)
84 }
85
86 pub fn merge(&mut self, since: Option<u64>) -> Result<()> {
87 let file_ids = if let Some(file_id) = since {
88 self.store.prepare_merging_since(file_id)
89 } else {
90 self.store.prepare_full_merging()
91 };
92 debug!(target: "core::merge", "file_ids: {:?}", file_ids);
93 let ret = self.store.merge(&file_ids)?;
94 self.store.finish_merging(ret)
95 }
96
97 pub fn keys(&self) -> StoreKeys {
98 self.store.keys()
99 }
100}
101
102impl Clone for Bitcask {
103 fn clone(&self) -> Self {
104 Bitcask {
105 config: self.config.clone(),
106 store: self.store.clone(),
107 }
108 }
109}