@@ -674,6 +674,34 @@ impl ZeboPage {
674674 }
675675 }
676676
677+ self . find_from_start ( target_doc_id)
678+ }
679+
680+ fn find_from_start ( & self , target_doc_id : u64 ) -> Result < Option < ( u64 , u32 , u32 ) > > {
681+ let document_count = self . get_document_count ( ) ? as u64 ;
682+
683+ for i in 0 ..document_count {
684+ match self . get_at ( i) {
685+ Ok ( Some ( ( doc_id, document_offset, document_len) ) ) => {
686+ if doc_id == target_doc_id {
687+ if Self :: is_uninitialized_entry ( document_offset)
688+ || Self :: is_deleted ( doc_id, document_offset, document_len)
689+ {
690+ return Ok ( None ) ;
691+ }
692+
693+ debug ! ( "Found in full scan" ) ;
694+ return Ok ( Some ( ( doc_id, document_offset, document_len) ) ) ;
695+ }
696+ }
697+ Ok ( None ) => break ,
698+ Err ( e) => {
699+ error ! ( "Error during full scan: {:?}" , e) ;
700+ continue ;
701+ }
702+ }
703+ }
704+
677705 Ok ( None )
678706 }
679707
@@ -1733,7 +1761,7 @@ mod tests {
17331761 let r = page. reserve_space ( 5 , 5 ) . unwrap ( ) ;
17341762 r. write ( b"ccccc" ) . unwrap ( ) ;
17351763
1736- let a = page
1764+ let docs = page
17371765 . get_documents :: < u64 > ( & [
17381766 ( 1 , ProbableIndex ( 0 ) ) ,
17391767 ( 2 , ProbableIndex ( 1 ) ) ,
@@ -1743,11 +1771,70 @@ mod tests {
17431771 ] )
17441772 . unwrap ( ) ;
17451773
1746- assert_eq ! ( a. len( ) , 5 ) ;
1747- assert_eq ! ( a[ 0 ] , ( 1 , b"hello" . to_vec( ) ) ) ;
1748- assert_eq ! ( a[ 1 ] , ( 2 , b"world" . to_vec( ) ) ) ;
1749- assert_eq ! ( a[ 2 ] , ( 3 , b"bbbbb" . to_vec( ) ) ) ;
1750- assert_eq ! ( a[ 3 ] , ( 4 , b"aaaaa" . to_vec( ) ) ) ;
1751- assert_eq ! ( a[ 4 ] , ( 5 , b"ccccc" . to_vec( ) ) ) ;
1774+ assert_eq ! ( docs. len( ) , 5 ) ;
1775+ assert_eq ! ( docs[ 0 ] , ( 1 , b"hello" . to_vec( ) ) ) ;
1776+ assert_eq ! ( docs[ 1 ] , ( 2 , b"world" . to_vec( ) ) ) ;
1777+ assert_eq ! ( docs[ 2 ] , ( 3 , b"bbbbb" . to_vec( ) ) ) ;
1778+ assert_eq ! ( docs[ 3 ] , ( 4 , b"aaaaa" . to_vec( ) ) ) ;
1779+ assert_eq ! ( docs[ 4 ] , ( 5 , b"ccccc" . to_vec( ) ) ) ;
1780+
1781+ for doc_id in 1 ..=5 {
1782+ let docs = page. fallback_search_document ( doc_id, None ) . unwrap ( ) ;
1783+ assert ! ( docs. is_some( ) ) ;
1784+ }
1785+ }
1786+
1787+ #[ test]
1788+ fn test_fallback_search_start_from_initial ( ) {
1789+ // Test that fallback_search_document optimization chooses the optimal starting point
1790+ // when target is closer to the end of the page
1791+ use crate :: tests:: prepare_test_dir;
1792+
1793+ let _ = tracing_subscriber:: fmt:: try_init ( ) ;
1794+
1795+ let test_dir = prepare_test_dir ( ) ;
1796+ let file_path = test_dir. join ( "wrong_document_order.zebo" ) ;
1797+ let page_file = std:: fs:: File :: options ( )
1798+ . create ( true )
1799+ . truncate ( true )
1800+ . read ( true )
1801+ . write ( true )
1802+ . open ( & file_path)
1803+ . expect ( "Failed to create page file" ) ;
1804+
1805+ let mut page = ZeboPage :: try_new ( 10 , 1000 , page_file) . expect ( "Failed to create page" ) ;
1806+
1807+ let r = page. reserve_space ( 1 , 5 ) . unwrap ( ) ;
1808+ r. write ( b"hello" ) . unwrap ( ) ;
1809+ let r = page. reserve_space ( 2 , 5 ) . unwrap ( ) ;
1810+ r. write ( b"world" ) . unwrap ( ) ;
1811+ let r = page. reserve_space ( 4 , 5 ) . unwrap ( ) ;
1812+ r. write ( b"aaaaa" ) . unwrap ( ) ;
1813+ let r = page. reserve_space ( 3 , 5 ) . unwrap ( ) ;
1814+ r. write ( b"bbbbb" ) . unwrap ( ) ;
1815+ let r = page. reserve_space ( 5 , 5 ) . unwrap ( ) ;
1816+ r. write ( b"ccccc" ) . unwrap ( ) ;
1817+
1818+ let docs = page
1819+ . get_documents :: < u64 > ( & [
1820+ ( 1 , ProbableIndex ( 0 ) ) ,
1821+ ( 2 , ProbableIndex ( 1 ) ) ,
1822+ ( 3 , ProbableIndex ( 3 ) ) ,
1823+ ( 4 , ProbableIndex ( 2 ) ) ,
1824+ ( 5 , ProbableIndex ( 4 ) ) ,
1825+ ] )
1826+ . unwrap ( ) ;
1827+
1828+ assert_eq ! ( docs. len( ) , 5 ) ;
1829+ assert_eq ! ( docs[ 0 ] , ( 1 , b"hello" . to_vec( ) ) ) ;
1830+ assert_eq ! ( docs[ 1 ] , ( 2 , b"world" . to_vec( ) ) ) ;
1831+ assert_eq ! ( docs[ 2 ] , ( 3 , b"bbbbb" . to_vec( ) ) ) ;
1832+ assert_eq ! ( docs[ 3 ] , ( 4 , b"aaaaa" . to_vec( ) ) ) ;
1833+ assert_eq ! ( docs[ 4 ] , ( 5 , b"ccccc" . to_vec( ) ) ) ;
1834+
1835+ for doc_id in 1 ..=5 {
1836+ let docs = page. find_from_start ( doc_id) . unwrap ( ) ;
1837+ assert ! ( docs. is_some( ) ) ;
1838+ }
17521839 }
17531840}
0 commit comments