1extern crate rocksdb;
2
3use crate::BITCOIN_DATADIR;
4use rocksdb::{DBCompressionType, DB, DBCompactionStyle};
5use std::fs;
6use std::path::Path;
7use std::sync::Arc;
8
9pub trait Database {
10 fn new() -> Self;
11 fn put(&self, header: &String, sequence: &String);
12 fn get(&self, header: &String) -> Option<String>;
13 fn delete(&self, header: &String) -> bool;
14}
15
16#[derive(Clone)]
17pub struct RocksDB {
18 pub db: Arc<DB>,
19}
20
21impl Database for RocksDB {
22 fn new() -> Self {
23 let rocksdb_path = format!("{}/{}", BITCOIN_DATADIR.lock().unwrap(), "rocksdb");
25 if !Path::new(&rocksdb_path).exists() {
26 match fs::create_dir_all(&rocksdb_path) {
27 Ok(_) => {}
28 Err(_error) => panic!("Unable to create directory at {}.", rocksdb_path),
29 };
30 }
31
32 let mut opts = rocksdb::Options::default();
34 opts.create_if_missing(true);
35 opts.set_compression_type(DBCompressionType::None);
36 opts.increase_parallelism(4);
38
39 let database = match DB::open(&opts, rocksdb_path.as_str()) {
41 Ok(r) => r,
42 Err(e) => panic!("Unable to open RocksDB at {}, error: {}", rocksdb_path, e),
43 };
44
45 RocksDB {
47 db: Arc::new(database),
48 }
49 }
50
51 fn put(&self, header: &String, sequence: &String) {
52 self.db.put(header.as_bytes(), sequence.as_bytes()).unwrap();
53 }
54
55 fn get(&self, header: &String) -> Option<String> {
56 let sequence = match self.db.get(header.as_bytes()) {
57 Ok(Some(r)) => String::from_utf8(r).unwrap(),
58 Ok(None) => return None,
59 Err(e) => panic!(
60 "Received database error when trying to retrieve sequence, error: {}",
61 e
62 ),
63 };
64
65 Some(sequence)
66 }
67
68 fn delete(&self, header: &String) -> bool {
69 self.db.delete(header.as_bytes()).is_ok()
70 }
71}