changeset 165:bb7c31aa2825

Implement bare-bones version of TableCache.
author Lewin Bormann <lbo@spheniscida.de>
date Mon, 10 Jul 2017 20:01:47 +0200
parents fbab9802c402
children ef5426303667
files src/table_cache.rs
diffstat 1 files changed, 44 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/table_cache.rs	Mon Jul 10 20:01:31 2017 +0200
+++ b/src/table_cache.rs	Mon Jul 10 20:01:47 2017 +0200
@@ -1,9 +1,15 @@
 
-use cache::Cache;
-use env::RandomAccessFile;
+use cache::{self, Cache};
+use env::RandomAccess;
+use error::Result;
 use options::Options;
 use table_reader::Table;
 
+use integer_encoding::FixedIntWriter;
+
+use std::path::Path;
+use std::sync::Arc;
+
 const DEFAULT_SUFFIX: &str = "ldb";
 
 fn table_name(name: &str, num: usize, suff: &str) -> String {
@@ -11,8 +17,14 @@
     format!("{}/{:06}.{}", name, num, suff)
 }
 
+fn filenum_to_key(num: usize) -> cache::CacheKey {
+    let mut buf = Vec::new();
+    buf.write_fixedint(num).unwrap();
+    buf
+}
+
 struct TableAndFile {
-    file: Box<RandomAccessFile>,
+    file: Arc<Box<RandomAccess>>,
     table: Table,
 }
 
@@ -30,6 +42,33 @@
             opts: opt,
         }
     }
+    pub fn evict(&mut self, id: usize) {
+        self.cache.remove(&filenum_to_key(id));
+    }
+    /// Return a table from cache, or open the backing file, then cache and return it.
+    pub fn get_table(&mut self, file_num: usize, file_size: usize) -> Result<Table> {
+        let key = filenum_to_key(file_num);
+        match self.cache.get(&key) {
+            Some(t) => return Ok(t.table.clone()),
+            _ => {}
+        }
+        self.open_table(file_num, file_size)
+    }
+
+    fn open_table(&mut self, file_num: usize, file_size: usize) -> Result<Table> {
+        let name = table_name(&self.dbname, file_num, DEFAULT_SUFFIX);
+        let path = Path::new(&name);
+        let file = self.opts.env.open_random_access_file(&path)?;
+        let rc_file = Arc::new(file);
+        // No SSTable file name compatibility.
+        let table = Table::new(self.opts.clone(), rc_file.clone(), file_size)?;
+        self.cache.insert(&filenum_to_key(file_num),
+                          TableAndFile {
+                              file: rc_file.clone(),
+                              table: table.clone(),
+                          });
+        Ok(table)
+    }
 }
 
 #[cfg(test)]
@@ -40,4 +79,6 @@
     fn test_table_name() {
         assert_eq!("abc/000122.ldb", table_name("abc", 122, "ldb"));
     }
+
+    // TODO: Write tests after memenv has been implemented.
 }