@ -1,368 +1,246 @@
//! TODO: This storage is dramatically naive.
use crate ::error ::invalid_input_error ;
use crate ::storage ::backend ::{ CompactionAction , CompactionFilter } ;
use std ::collections ::{ hash_map , BTreeMap , HashMap , HashSet } ;
use std ::ffi ::CString ;
use std ::io ::{ Error , Result } ;
use std ::sync ::{ Arc , RwLock } ;
use std ::cell ::RefCell ;
use std ::collections ::{ BTreeMap , HashMap } ;
use std ::io ::Result ;
use std ::mem ::transmute ;
use std ::rc ::{ Rc , Weak } ;
use std ::sync ::{ Arc , RwLock , RwLockWriteGuard } ;
pub struct ColumnFamilyDefinition {
pub name : & ' static str ,
pub merge_operator : Option < MergeOperator > ,
pub compaction_filter : Option < CompactionFilter > ,
pub use_iter : bool ,
pub min_prefix_size : usize ,
}
#[ derive(Clone) ]
pub struct Db ( Arc < DbInternals > ) ;
#[ derive(Default) ]
struct DbInternals {
trees : RwLock < HashMap < ColumnFamily , BTreeMap < Vec < u8 > , Vec < u8 > > > > ,
merge_operators : HashMap < ColumnFamily , MergeOperator > ,
compaction_filters : HashMap < ColumnFamily , CompactionFilter > ,
}
pub struct Db ( Arc < RwLock < HashMap < ColumnFamily , BTreeMap < Vec < u8 > , Vec < u8 > > > > > ) ;
impl Db {
pub fn new ( column_families : Vec < ColumnFamilyDefinition > ) -> Result < Self > {
let mut trees = HashMap ::new ( ) ;
let mut merge_operators = HashMap ::new ( ) ;
let mut compaction_filters = HashMap ::new ( ) ;
for cf in column_families {
let name = ColumnFamily ( cf . name ) ;
trees . insert ( name . clone ( ) , BTreeMap ::default ( ) ) ;
if let Some ( me ) = cf . merge_operator {
merge_operators . insert ( name . clone ( ) , me ) ;
}
if let Some ( cf ) = cf . compaction_filter {
compaction_filters . insert ( name . clone ( ) , cf ) ;
}
trees . insert ( ColumnFamily ( cf . name ) , BTreeMap ::default ( ) ) ;
}
trees . entry ( ColumnFamily ( "default" ) ) . or_default ( ) ; // We make sure that "default" key exists.
Ok ( Self ( Arc ::new ( DbInternals {
trees : RwLock ::new ( trees ) ,
merge_operators ,
compaction_filters ,
} ) ) )
Ok ( Self ( Arc ::new ( RwLock ::new ( trees ) ) ) )
}
pub fn column_family ( & self , name : & ' static str ) -> Option < ColumnFamily > {
let name = ColumnFamily ( name ) ;
if self . 0. trees . read ( ) . unwrap ( ) . contains_key ( & name ) {
if self . 0. read ( ) . unwrap ( ) . contains_key ( & name ) {
Some ( name )
} else {
None
}
}
pub fn flush ( & self , _column_family : & ColumnFamily ) -> Result < ( ) > {
Ok ( ( ) )
#[ must_use ]
pub fn snapshot ( & self ) -> Reader {
Reader ( InnerReader ::Simple ( self . 0. clone ( ) ) )
}
pub fn get ( & self , column_family : & ColumnFamily , key : & [ u8 ] ) -> Result < Option < Vec < u8 > > > {
Ok ( self
. 0
. trees
. read ( )
. unwrap ( )
. get ( column_family )
. and_then ( | cf | cf . get ( key ) . cloned ( ) ) )
}
pub fn contains_key ( & self , column_family : & ColumnFamily , key : & [ u8 ] ) -> Result < bool > {
Ok ( self
. 0
. trees
. read ( )
. unwrap ( )
. get ( column_family )
. map_or ( false , | cf | cf . contains_key ( key ) ) )
}
pub fn new_batch ( & self ) -> WriteBatchWithIndex {
WriteBatchWithIndex {
by_cf : HashMap ::new ( ) ,
db : self . clone ( ) ,
error : None ,
}
}
pub fn write ( & self , batch : & mut WriteBatchWithIndex ) -> Result < ( ) > {
if let Some ( error ) = batch . error . take ( ) {
return Err ( error ) ;
}
let mut trees = self . 0. trees . write ( ) . unwrap ( ) ;
for ( cf , ops ) in batch . by_cf . drain ( ) {
let tree = trees . get_mut ( & cf ) . ok_or_else ( | | {
invalid_input_error ( format! ( "Unsupported column family {}" , cf . 0 ) )
} ) ? ;
for k in ops . to_remove {
tree . remove ( & k ) ;
}
for ( k , v ) in ops . to_insert {
tree . insert ( k , v ) ;
}
for ( k , v ) in ops . to_merge {
let v = self . exec_merge ( & cf , & k , tree . get ( & k ) . map ( | v | v . as_slice ( ) ) , & v ) ? ;
tree . insert ( k , v ) ;
}
}
Ok ( ( ) )
pub fn transaction < ' a , ' b : ' a , T > (
& ' b self ,
f : impl Fn ( Transaction < ' a > ) -> Result < T > ,
) -> Result < T > {
f ( Transaction ( Rc ::new ( RefCell ::new ( self . 0. write ( ) . unwrap ( ) ) ) ) )
}
}
/* pub fn insert(
& self ,
column_family : & ColumnFamily ,
key : & [ u8 ] ,
value : & [ u8 ] ,
_low_priority : bool ,
) -> Result < ( ) > {
let mut db = self . 0. write ( ) . unwrap ( ) ;
let tree = db . get_mut ( column_family ) . unwrap ( ) ;
if let Some ( value ) = Self ::exec_filter ( tree , key , value . into ( ) ) {
tree . tree . insert ( key . into ( ) , value . into ( ) )
} else {
tree . tree . remove ( key )
} ;
Ok ( ( ) )
}
#[ derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash) ]
pub struct ColumnFamily ( & ' static str ) ;
pub fn insert_empty (
& self ,
column_family : & ColumnFamily ,
key : & [ u8 ] ,
low_priority : bool ,
) -> Result < ( ) > {
self . insert ( column_family , key , & [ ] , low_priority )
}
pub struct Reader ( InnerReader ) ;
pub fn remove (
& self ,
column_family : & ColumnFamily ,
key : & [ u8 ] ,
_low_priority : bool ,
) -> Result < bool > {
Ok ( self
. 0
. write ( )
. unwrap ( )
. get_mut ( column_family )
. unwrap ( )
. tree
. remove ( key . as_ref ( ) )
. is_some ( ) )
}
enum InnerReader {
Simple ( Arc < RwLock < HashMap < ColumnFamily , BTreeMap < Vec < u8 > , Vec < u8 > > > > > ) ,
Transaction (
Weak < RefCell < RwLockWriteGuard < ' static , HashMap < ColumnFamily , BTreeMap < Vec < u8 > , Vec < u8 > > > > > > ,
) ,
}
pub fn merge (
& self ,
column_family : & ColumnFamily ,
key : & [ u8 ] ,
value : & [ u8 ] ,
_low_priority : bool ,
) -> Result < ( ) > {
let mut db = self . 0. write ( ) . unwrap ( ) ;
let tree = db . get_mut ( column_family ) . unwrap ( ) ;
match tree . tree . entry ( key . into ( ) ) {
Entry ::Vacant ( e ) = > {
if let Some ( value ) =
Self ::exec_filter ( tree , key , Self ::exec_merge ( tree , key , None , value ) )
{
e . insert ( value ) ;
}
}
Entry ::Occupied ( mut e ) = > {
if let Some ( value ) =
Self ::exec_filter ( tree , key , Self ::exec_merge ( tree , key , None , value ) )
{
e . insert ( value ) ;
impl Reader {
pub fn get ( & self , column_family : & ColumnFamily , key : & [ u8 ] ) -> Result < Option < Vec < u8 > > > {
match & self . 0 {
InnerReader ::Simple ( reader ) = > Ok ( reader
. read ( )
. unwrap ( )
. get ( column_family )
. and_then ( | cf | cf . get ( key ) . cloned ( ) ) ) ,
InnerReader ::Transaction ( reader ) = > {
if let Some ( reader ) = reader . upgrade ( ) {
Ok ( ( * reader )
. borrow ( )
. get ( column_family )
. and_then ( | cf | cf . get ( key ) . cloned ( ) ) )
} else {
e . remove ( ) ;
Err ( invalid_input_error ( "The transaction is already ended" ) )
}
}
}
Ok ( ( ) )
} * /
fn exec_merge (
& self ,
cf : & ColumnFamily ,
key : & [ u8 ] ,
base : Option < & [ u8 ] > ,
value : & [ u8 ] ,
) -> Result < Vec < u8 > > {
let merge = self . 0. merge_operators . get ( cf ) . ok_or_else ( | | {
invalid_input_error ( format! ( "The column family {} has no merge operator" , cf . 0 ) )
} ) ? ;
Ok ( ( merge . full ) ( key , base , vec! [ value ] . into_iter ( ) ) )
}
fn exec_partial_merge (
& self ,
cf : & ColumnFamily ,
key : & [ u8 ] ,
a : & [ u8 ] ,
b : & [ u8 ] ,
) -> Result < Vec < u8 > > {
let merge = self . 0. merge_operators . get ( cf ) . ok_or_else ( | | {
invalid_input_error ( format! ( "The column family {} has no merge operator" , cf . 0 ) )
} ) ? ;
Ok ( ( merge . partial ) ( key , vec! [ a , b ] . into_iter ( ) ) )
}
fn exec_filter ( & self , cf : & ColumnFamily , key : & [ u8 ] , value : Vec < u8 > ) -> Option < Vec < u8 > > {
let action = if let Some ( filter ) = self . 0. compaction_filters . get ( cf ) {
( filter . filter ) ( key , & value )
} else {
CompactionAction ::Keep
} ;
match action {
CompactionAction ::Keep = > Some ( value ) ,
CompactionAction ::Remove = > None ,
pub fn contains_key ( & self , column_family : & ColumnFamily , key : & [ u8 ] ) -> Result < bool > {
match & self . 0 {
InnerReader ::Simple ( reader ) = > Ok ( reader
. read ( )
. unwrap ( )
. get ( column_family )
. map_or ( false , | cf | cf . contains_key ( key ) ) ) ,
InnerReader ::Transaction ( reader ) = > {
if let Some ( reader ) = reader . upgrade ( ) {
Ok ( ( * reader )
. borrow ( )
. get ( column_family )
. map_or ( false , | cf | cf . contains_key ( key ) ) )
} else {
Err ( invalid_input_error ( "The transaction is already ended" ) )
}
}
}
}
pub fn iter ( & self , column_family : & ColumnFamily ) -> Iter {
pub fn iter ( & self , column_family : & ColumnFamily ) -> Result < Iter > {
self . scan_prefix ( column_family , & [ ] )
}
pub fn scan_prefix ( & self , column_family : & ColumnFamily , prefix : & [ u8 ] ) -> Iter {
let trees = self . 0. trees . read ( ) . unwrap ( ) ;
let tree = if let Some ( tree ) = trees . get ( column_family ) {
tree
} else {
return Iter {
iter : Vec ::new ( ) . into_iter ( ) ,
current : None ,
} ;
} ;
let data : Vec < _ > = if prefix . is_empty ( ) {
tree . iter ( ) . map ( | ( k , v ) | ( k . clone ( ) , v . clone ( ) ) ) . collect ( )
} else {
tree . range ( prefix . to_vec ( ) .. )
. take_while ( | ( k , _ ) | k . starts_with ( prefix ) )
. map ( | ( k , v ) | ( k . clone ( ) , v . clone ( ) ) )
. collect ( )
pub fn scan_prefix ( & self , column_family : & ColumnFamily , prefix : & [ u8 ] ) -> Result < Iter > {
let data : Vec < _ > = match & self . 0 {
InnerReader ::Simple ( reader ) = > {
let trees = reader . read ( ) . unwrap ( ) ;
let tree = if let Some ( tree ) = trees . get ( column_family ) {
tree
} else {
return Ok ( Iter {
iter : Vec ::new ( ) . into_iter ( ) ,
current : None ,
} ) ;
} ;
if prefix . is_empty ( ) {
tree . iter ( ) . map ( | ( k , v ) | ( k . clone ( ) , v . clone ( ) ) ) . collect ( )
} else {
tree . range ( prefix . to_vec ( ) .. )
. take_while ( | ( k , _ ) | k . starts_with ( prefix ) )
. map ( | ( k , v ) | ( k . clone ( ) , v . clone ( ) ) )
. collect ( )
}
}
InnerReader ::Transaction ( reader ) = > {
if let Some ( reader ) = reader . upgrade ( ) {
let trees = ( * reader ) . borrow ( ) ;
let tree = if let Some ( tree ) = trees . get ( column_family ) {
tree
} else {
return Ok ( Iter {
iter : Vec ::new ( ) . into_iter ( ) ,
current : None ,
} ) ;
} ;
if prefix . is_empty ( ) {
tree . iter ( ) . map ( | ( k , v ) | ( k . clone ( ) , v . clone ( ) ) ) . collect ( )
} else {
tree . range ( prefix . to_vec ( ) .. )
. take_while ( | ( k , _ ) | k . starts_with ( prefix ) )
. map ( | ( k , v ) | ( k . clone ( ) , v . clone ( ) ) )
. collect ( )
}
} else {
return Err ( invalid_input_error ( "The transaction is already ended" ) ) ;
}
}
} ;
let mut iter = data . into_iter ( ) ;
let current = iter . next ( ) ;
Iter { iter , current }
Ok ( Iter { iter , current } )
}
pub fn len ( & self , column_family : & ColumnFamily ) -> Result < usize > {
Ok ( self
. 0
. trees
. read ( )
. unwrap ( )
. get ( column_family )
. map_or ( 0 , | tree | tree . len ( ) ) )
match & self . 0 {
InnerReader ::Simple ( reader ) = > Ok ( reader
. read ( )
. unwrap ( )
. get ( column_family )
. map_or ( 0 , | tree | tree . len ( ) ) ) ,
InnerReader ::Transaction ( reader ) = > {
if let Some ( reader ) = reader . upgrade ( ) {
Ok ( ( * reader )
. borrow ( )
. get ( column_family )
. map_or ( 0 , | tree | tree . len ( ) ) )
} else {
Err ( invalid_input_error ( "The transaction is already ended" ) )
}
}
}
}
pub fn is_empty ( & self , column_family : & ColumnFamily ) -> Result < bool > {
Ok ( self
. 0
. trees
. read ( )
. unwrap ( )
. get ( column_family )
. map_or ( true , | tree | tree . is_empty ( ) ) )
match & self . 0 {
InnerReader ::Simple ( reader ) = > Ok ( reader
. read ( )
. unwrap ( )
. get ( column_family )
. map_or ( true , | tree | tree . is_empty ( ) ) ) ,
InnerReader ::Transaction ( reader ) = > {
if let Some ( reader ) = reader . upgrade ( ) {
Ok ( ( * reader )
. borrow ( )
. get ( column_family )
. map_or ( true , | tree | tree . is_empty ( ) ) )
} else {
Err ( invalid_input_error ( "The transaction is already ended" ) )
}
}
}
}
}
#[ derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash) ]
pub struct ColumnFamily ( & ' static str ) ;
pub struct WriteBatchWithIndex {
by_cf : HashMap < ColumnFamily , WriteBatchWithIndexCF > ,
db : Db ,
error : Option < Error > ,
}
#[ derive(Default) ]
struct WriteBatchWithIndexCF {
// Evaluation order insert/remove then merge
to_insert : HashMap < Vec < u8 > , Vec < u8 > > ,
to_merge : HashMap < Vec < u8 > , Vec < u8 > > ,
to_remove : HashSet < Vec < u8 > > ,
}
impl WriteBatchWithIndex {
pub fn insert ( & mut self , column_family : & ColumnFamily , key : & [ u8 ] , value : & [ u8 ] ) {
let cf_state = self . by_cf . entry ( column_family . clone ( ) ) . or_default ( ) ;
cf_state . to_insert . insert ( key . into ( ) , value . into ( ) ) ;
cf_state . to_merge . remove ( key ) ;
cf_state . to_remove . remove ( key ) ;
}
pub struct Transaction < ' a > (
Rc < RefCell < RwLockWriteGuard < ' a , HashMap < ColumnFamily , BTreeMap < Vec < u8 > , Vec < u8 > > > > > > ,
) ;
pub fn insert_empty ( & mut self , column_family : & ColumnFamily , key : & [ u8 ] ) {
self . insert ( column_family , key , & [ ] )
}
pub fn remove ( & mut self , column_family : & ColumnFamily , key : & [ u8 ] ) {
let cf_state = self . by_cf . entry ( column_family . clone ( ) ) . or_default ( ) ;
cf_state . to_insert . remove ( key ) ;
cf_state . to_merge . remove ( key ) ;
cf_state . to_remove . insert ( key . into ( ) ) ;
}
pub fn merge ( & mut self , column_family : & ColumnFamily , key : & [ u8 ] , value : & [ u8 ] ) {
let cf_state = self . by_cf . entry ( column_family . clone ( ) ) . or_default ( ) ;
match cf_state . to_merge . entry ( key . into ( ) ) {
hash_map ::Entry ::Vacant ( e ) = > {
e . insert ( value . into ( ) ) ;
}
hash_map ::Entry ::Occupied ( mut e ) = > {
match self
. db
. exec_partial_merge ( column_family , key , e . get ( ) , value )
{
Ok ( value ) = > {
e . insert ( value ) ;
}
Err ( e ) = > self . error = Some ( e ) ,
}
}
}
impl Transaction < ' _ > {
#[ allow(unsafe_code) ]
pub fn reader ( & self ) -> Reader {
// This transmute is safe because we take a weak reference and the only Rc reference used is guarded by the lifetime.
Reader ( InnerReader ::Transaction ( Rc ::downgrade ( unsafe {
transmute ( & self . 0 )
} ) ) )
}
pub fn get ( & self , column_family : & ColumnFamily , key : & [ u8 ] ) -> Result < Option < Vec < u8 > > > {
if let Some ( cf_state ) = self . by_cf . get ( column_family ) {
let value = if cf_state . to_remove . contains ( key ) {
None
} else if let Some ( value ) = cf_state . to_insert . get ( key ) {
Some ( value . clone ( ) )
} else {
self . db . get ( column_family , key ) ?
} ;
Ok ( if let Some ( merge ) = cf_state . to_merge . get ( key ) {
Some (
self . db
. exec_merge ( column_family , key , value . as_deref ( ) , merge ) ? ,
)
} else {
value
}
. and_then ( | value | self . db . exec_filter ( column_family , key , value ) ) )
} else {
self . db . get ( column_family , key )
}
pub fn contains_key_for_update (
& self ,
column_family : & ColumnFamily ,
key : & [ u8 ] ,
) -> Result < bool > {
Ok ( ( * self . 0 )
. borrow ( )
. get ( column_family )
. map_or ( false , | cf | cf . contains_key ( key ) ) )
}
pub fn contains_key ( & self , column_family : & ColumnFamily , key : & [ u8 ] ) -> Result < bool > {
Ok ( self . get ( column_family , key ) ? . is_some ( ) ) //TODO: optimize
pub fn insert ( & mut self , column_family : & ColumnFamily , key : & [ u8 ] , value : & [ u8 ] ) -> Result < ( ) > {
self . 0
. borrow_mut ( )
. get_mut ( column_family )
. unwrap ( )
. insert ( key . into ( ) , value . into ( ) ) ;
Ok ( ( ) )
}
pub fn clear ( & mut self ) {
self . by_cf . clear ( ) ;
pub fn insert_empty ( & mut self , column_family : & ColumnFamily , key : & [ u8 ] ) -> Result < ( ) > {
self . insert ( column_family , key , & [ ] )
}
pub fn len ( & self ) -> usize {
self . by_cf
. values ( )
. map ( | v | v . to_insert . len ( ) + v . to_remove . len ( ) + v . to_merge . len ( ) )
. sum ( )
pub fn remove ( & mut self , column_family : & ColumnFamily , key : & [ u8 ] ) -> Result < ( ) > {
self . 0
. borrow_mut ( )
. get_mut ( column_family )
. unwrap ( )
. remove ( key ) ;
Ok ( ( ) )
}
}
@ -388,11 +266,3 @@ impl Iter {
Ok ( ( ) )
}
}
pub struct MergeOperator {
pub full : fn ( & [ u8 ] , Option < & [ u8 ] > , SlicesIterator < ' _ > ) -> Vec < u8 > ,
pub partial : fn ( & [ u8 ] , SlicesIterator < ' _ > ) -> Vec < u8 > ,
pub name : CString ,
}
pub type SlicesIterator < ' a > = std ::vec ::IntoIter < & ' a [ u8 ] > ;