1+ use crate :: Value ;
12use crate :: jstable;
23use crate :: log:: { Log , LogEntry , Logger , NullLogger , Operation } ;
34use crate :: storage:: MemTable ;
4- use serde_json:: Value ;
55use std:: collections:: HashMap ;
66use std:: fmt:: Debug ;
77use std:: fs;
@@ -59,10 +59,12 @@ impl<'a> Iterator for MergedIterator<'a> {
5959 }
6060 }
6161
62- if let Some ( doc) = result
63- && !doc. is_null ( )
64- {
65- return Some ( ( min_id, doc) ) ;
62+ // Check for tombstone (Null)
63+ if let Some ( doc) = result {
64+ use jsonb_schema:: Value as JsonbValue ;
65+ if !matches ! ( doc, JsonbValue :: Null ) {
66+ return Some ( ( min_id, doc) ) ;
67+ }
6668 }
6769 // If null (tombstone), loop again
6870 }
@@ -266,7 +268,8 @@ impl Collection {
266268 fn get ( & self , id : & str ) -> Option < Value > {
267269 // 1. Check MemTable
268270 if let Some ( doc) = self . memtable . documents . get ( id) {
269- if doc. is_null ( ) {
271+ use jsonb_schema:: Value as JsonbValue ;
272+ if matches ! ( doc, JsonbValue :: Null ) {
270273 return None ; // Tombstone
271274 }
272275 return Some ( doc. clone ( ) ) ;
@@ -281,29 +284,30 @@ impl Collection {
281284 } ;
282285
283286 for i in ( 0 ..self . jstable_count ) . rev ( ) {
284- if let Some ( table) = self . tables . get ( i as usize ) {
285- if table. filter . contains ( & hash) {
286- // Possible match, find offset using index
287- let index = & table. index ;
288- // Find first key > id. We want the one before that.
289- let idx = index. partition_point ( |( k, _) | k. as_str ( ) <= id) ;
290- let start_offset = if idx > 0 { index[ idx - 1 ] . 1 } else { 0 } ;
291-
292- let path = self . dir . join ( format ! ( "jstable-{}" , i) ) ;
293- if let Ok ( mut iter) = jstable:: JSTableIterator :: new ( path. to_str ( ) . unwrap ( ) ) {
294- if iter. seek ( start_offset) . is_ok ( ) {
295- for ( rid, doc) in iter. flatten ( ) {
296- if rid == id {
297- if doc. is_null ( ) {
298- return None ; // Tombstone
299- }
300- return Some ( doc) ;
301- }
302- if rid. as_str ( ) > id {
303- // Not found in this table (sorted)
304- break ;
305- }
287+ if let Some ( table) = self . tables . get ( i as usize )
288+ && table. filter . contains ( & hash)
289+ {
290+ // Possible match, find offset using index
291+ let index = & table. index ;
292+ // Find first key > id. We want the one before that.
293+ let idx = index. partition_point ( |( k, _) | k. as_str ( ) <= id) ;
294+ let start_offset = if idx > 0 { index[ idx - 1 ] . 1 } else { 0 } ;
295+
296+ let path = self . dir . join ( format ! ( "jstable-{}" , i) ) ;
297+ if let Ok ( mut iter) = jstable:: JSTableIterator :: new ( path. to_str ( ) . unwrap ( ) )
298+ && iter. seek ( start_offset) . is_ok ( )
299+ {
300+ for ( rid, doc) in iter. flatten ( ) {
301+ if rid == id {
302+ use jsonb_schema:: Value as JsonbValue ;
303+ if matches ! ( doc, JsonbValue :: Null ) {
304+ return None ; // Tombstone
306305 }
306+ return Some ( doc) ;
307+ }
308+ if rid. as_str ( ) > id {
309+ // Not found in this table (sorted)
310+ break ;
307311 }
308312 }
309313 }
@@ -485,6 +489,7 @@ impl DB {
485489#[ cfg( test) ]
486490mod tests {
487491 use super :: * ;
492+ use crate :: serde_to_jsonb;
488493 use serde_json:: json;
489494 use tempfile:: tempdir;
490495
@@ -505,13 +510,15 @@ mod tests {
505510 db. create_collection ( "test" ) . unwrap ( ) ;
506511
507512 for i in 0 ..MEMTABLE_THRESHOLD {
508- db. insert ( "test" , json ! ( { "a" : i } ) ) . unwrap ( ) ;
513+ db. insert ( "test" , serde_to_jsonb ( json ! ( { "a" : i } ) ) )
514+ . unwrap ( ) ;
509515 }
510516 let col = db. collections . get ( "test" ) . unwrap ( ) ;
511517 assert_eq ! ( col. memtable. len( ) , MEMTABLE_THRESHOLD ) ;
512518 assert_eq ! ( col. jstable_count, 0 ) ;
513519
514- db. insert ( "test" , json ! ( { "a" : MEMTABLE_THRESHOLD } ) ) . unwrap ( ) ;
520+ db. insert ( "test" , serde_to_jsonb ( json ! ( { "a" : MEMTABLE_THRESHOLD } ) ) )
521+ . unwrap ( ) ;
515522 let col = db. collections . get ( "test" ) . unwrap ( ) ;
516523 assert_eq ! ( col. memtable. len( ) , 1 ) ;
517524 assert_eq ! ( col. jstable_count, 1 ) ;
@@ -533,10 +540,10 @@ mod tests {
533540 Some ( 1024 * 1024 ) ,
534541 ) ;
535542 db. create_collection ( "test" ) . unwrap ( ) ;
536- let doc1 = json ! ( { "a" : 1 } ) ;
543+ let doc1 = serde_to_jsonb ( json ! ( { "a" : 1 } ) ) ;
537544 let id1 = db. insert ( "test" , doc1. clone ( ) ) . unwrap ( ) ;
538545
539- let doc2 = json ! ( { "b" : "hello" } ) ;
546+ let doc2 = serde_to_jsonb ( json ! ( { "b" : "hello" } ) ) ;
540547 db. update ( "test" , & id1, doc2. clone ( ) ) . unwrap ( ) ;
541548
542549 db. delete ( "test" , & id1) . unwrap ( ) ;
@@ -582,10 +589,10 @@ mod tests {
582589 Some ( 1024 * 1024 ) ,
583590 ) ;
584591 db. create_collection ( "test" ) . unwrap ( ) ;
585- let doc1 = json ! ( { "a" : 1 } ) ;
592+ let doc1 = serde_to_jsonb ( json ! ( { "a" : 1 } ) ) ;
586593 let id1 = db. insert ( "test" , doc1. clone ( ) ) . unwrap ( ) ;
587594
588- let doc2 = json ! ( { "b" : "hello" } ) ;
595+ let doc2 = serde_to_jsonb ( json ! ( { "b" : "hello" } ) ) ;
589596 let id2 = db. insert ( "test" , doc2. clone ( ) ) . unwrap ( ) ;
590597
591598 db. delete ( "test" , & id1) . unwrap ( ) ;
@@ -602,7 +609,11 @@ mod tests {
602609
603610 assert_eq ! ( col. memtable. len( ) , 2 ) ;
604611 assert_eq ! ( * col. memtable. documents. get( & id2) . unwrap( ) , doc2) ;
605- assert ! ( col. memtable. documents. get( & id1) . unwrap( ) . is_null( ) ) ;
612+ use jsonb_schema:: Value as JsonbValue ;
613+ assert ! ( matches!(
614+ col. memtable. documents. get( & id1) . unwrap( ) ,
615+ JsonbValue :: Null
616+ ) ) ;
606617 }
607618
608619 #[ test]
@@ -618,12 +629,14 @@ mod tests {
618629 db. create_collection ( "test" ) . unwrap ( ) ;
619630
620631 for i in 0 ..( MEMTABLE_THRESHOLD * JSTABLE_THRESHOLD as usize ) {
621- db. insert ( "test" , json ! ( { "a" : i } ) ) . unwrap ( ) ;
632+ db. insert ( "test" , serde_to_jsonb ( json ! ( { "a" : i } ) ) )
633+ . unwrap ( ) ;
622634 }
623635
624636 let col = db. collections . get ( "test" ) . unwrap ( ) ;
625637 assert_eq ! ( col. jstable_count, JSTABLE_THRESHOLD - 1 ) ;
626- db. insert ( "test" , json ! ( { "a" : 999 } ) ) . unwrap ( ) ;
638+ db. insert ( "test" , serde_to_jsonb ( json ! ( { "a" : 999 } ) ) )
639+ . unwrap ( ) ;
627640
628641 let col = db. collections . get ( "test" ) . unwrap ( ) ;
629642 assert_eq ! ( col. jstable_count, 1 ) ;
@@ -640,32 +653,39 @@ mod tests {
640653 Some ( 1024 * 1024 ) ,
641654 ) ;
642655 db. create_collection ( "test" ) . unwrap ( ) ;
643- let id_to_delete = db. insert ( "test" , json ! ( { "a" : 100 } ) ) . unwrap ( ) ;
656+ let id_to_delete = db
657+ . insert ( "test" , serde_to_jsonb ( json ! ( { "a" : 100 } ) ) )
658+ . unwrap ( ) ;
644659
645660 for i in 0 ..9 {
646- db. insert ( "test" , json ! ( { "fill" : i } ) ) . unwrap ( ) ;
661+ db. insert ( "test" , serde_to_jsonb ( json ! ( { "fill" : i } ) ) )
662+ . unwrap ( ) ;
647663 }
648- db. insert ( "test" , json ! ( { "trigger_1" : 1 } ) ) . unwrap ( ) ;
664+ db. insert ( "test" , serde_to_jsonb ( json ! ( { "trigger_1" : 1 } ) ) )
665+ . unwrap ( ) ;
649666
650667 let col = db. collections . get ( "test" ) . unwrap ( ) ;
651668 assert_eq ! ( col. jstable_count, 1 ) ;
652669
653670 db. delete ( "test" , & id_to_delete) . unwrap ( ) ;
654671
655672 for i in 0 ..8 {
656- db. insert ( "test" , json ! ( { "fill_2" : i } ) ) . unwrap ( ) ;
673+ db. insert ( "test" , serde_to_jsonb ( json ! ( { "fill_2" : i } ) ) )
674+ . unwrap ( ) ;
657675 }
658- db. insert ( "test" , json ! ( { "trigger_2" : 1 } ) ) . unwrap ( ) ;
676+ db. insert ( "test" , serde_to_jsonb ( json ! ( { "trigger_2" : 1 } ) ) )
677+ . unwrap ( ) ;
659678
660679 let col = db. collections . get ( "test" ) . unwrap ( ) ;
661680 assert_eq ! ( col. jstable_count, 2 ) ;
662681
663682 for t in 0 ..3 {
664683 for i in 0 ..9 {
665- db. insert ( "test" , json ! ( { "fill_more" : t, "i" : i } ) )
684+ db. insert ( "test" , serde_to_jsonb ( json ! ( { "fill_more" : t, "i" : i } ) ) )
666685 . unwrap ( ) ;
667686 }
668- db. insert ( "test" , json ! ( { "trigger_more" : t } ) ) . unwrap ( ) ;
687+ db. insert ( "test" , serde_to_jsonb ( json ! ( { "trigger_more" : t } ) ) )
688+ . unwrap ( ) ;
669689 }
670690
671691 let col = db. collections . get ( "test" ) . unwrap ( ) ;
@@ -690,21 +710,16 @@ mod tests {
690710 db. create_collection ( "test" ) . unwrap ( ) ;
691711
692712 for i in 0 ..MEMTABLE_THRESHOLD {
693- db. insert ( "test" , json ! ( { "val" : i} ) ) . unwrap ( ) ;
713+ db. insert ( "test" , serde_to_jsonb ( json ! ( { "val" : i} ) ) )
714+ . unwrap ( ) ;
694715 }
695- db. insert ( "test" , json ! ( { "val" : 10 } ) ) . unwrap ( ) ;
716+ db. insert ( "test" , serde_to_jsonb ( json ! ( { "val" : 10 } ) ) )
717+ . unwrap ( ) ;
696718
697719 let results: HashMap < String , Value > = db. scan ( "test" ) . unwrap ( ) . collect ( ) ;
698720 assert_eq ! ( results. len( ) , 11 ) ;
699721 }
700722
701- #[ test]
702- fn test_sanitize ( ) {
703- assert_eq ! ( sanitize_filename( "valid" ) , "valid" ) ;
704- assert_eq ! ( sanitize_filename( "foo/bar" ) , "foo_2fbar" ) ;
705- assert_eq ! ( sanitize_filename( "test.1" ) , "test_2e1" ) ;
706- }
707-
708723 #[ test]
709724 fn test_create_collection ( ) {
710725 let dir = tempdir ( ) . unwrap ( ) ;
@@ -792,7 +807,7 @@ mod tests {
792807 INDEX_THRESHOLD ,
793808 Some ( 1024 * 1024 ) ,
794809 ) ;
795- let res = db. insert ( "test" , json ! ( { "a" : 1 } ) ) ;
810+ let res = db. insert ( "test" , serde_to_jsonb ( json ! ( { "a" : 1 } ) ) ) ;
796811 assert ! ( res. is_err( ) ) ;
797812 }
798813
@@ -829,18 +844,21 @@ mod tests {
829844 Some ( 1024 * 1024 ) ,
830845 ) ;
831846 db. create_collection ( "test" ) . unwrap ( ) ;
832- let id = db. insert ( "test" , json ! ( { "a" : 1 } ) ) . unwrap ( ) ;
847+ let id = db
848+ . insert ( "test" , serde_to_jsonb ( json ! ( { "a" : 1 } ) ) )
849+ . unwrap ( ) ;
833850
834851 let doc = db. get ( "test" , & id) . unwrap ( ) . unwrap ( ) ;
835- assert_eq ! ( doc, json!( { "a" : 1 } ) ) ;
852+ assert_eq ! ( doc, serde_to_jsonb ( json!( { "a" : 1 } ) ) ) ;
836853
837854 // Flush to force creation of JSTable
838855 for i in 0 ..MEMTABLE_THRESHOLD {
839- db. insert ( "test" , json ! ( { "fill" : i } ) ) . unwrap ( ) ;
856+ db. insert ( "test" , serde_to_jsonb ( json ! ( { "fill" : i } ) ) )
857+ . unwrap ( ) ;
840858 }
841859
842860 let doc = db. get ( "test" , & id) . unwrap ( ) . unwrap ( ) ;
843- assert_eq ! ( doc, json!( { "a" : 1 } ) ) ;
861+ assert_eq ! ( doc, serde_to_jsonb ( json!( { "a" : 1 } ) ) ) ;
844862
845863 assert ! ( db. get( "test" , "non-existent" ) . unwrap( ) . is_none( ) ) ;
846864 }
0 commit comments