@@ -7,17 +7,16 @@ use std::{
77
88use  crate :: bincode_options; 
99
10- type  EntryReader < ' t >  = CountingReader < BufReader < & ' t  mut  File > > ; 
11- 
1210/// Iterator over entries in a file store. 
1311/// 
1412/// Reads and returns an entry each time [`next`] is called. If an error occurs while reading the 
1513/// iterator will yield a `Result::Err(_)` instead and then `None` for the next call to `next`. 
1614/// 
1715/// [`next`]: Self::next 
1816pub  struct  EntryIter < ' t ,  T >  { 
19-     db_file :  Option < EntryReader < ' t > > , 
20- 
17+     /// Buffered reader around the file 
18+      db_file :  BufReader < & ' t  mut  File > , 
19+     finished :  bool , 
2120    /// The file position for the first read of `db_file`. 
2221     start_pos :  Option < u64 > , 
2322    types :  PhantomData < T > , 
@@ -26,8 +25,9 @@ pub struct EntryIter<'t, T> {
2625impl < ' t ,  T >  EntryIter < ' t ,  T >  { 
2726    pub  fn  new ( start_pos :  u64 ,  db_file :  & ' t  mut  File )  -> Self  { 
2827        Self  { 
29-             db_file :  Some ( CountingReader :: new ( BufReader :: new ( db_file) ) ) , 
28+             db_file :  BufReader :: new ( db_file) , 
3029            start_pos :  Some ( start_pos) , 
30+             finished :  false , 
3131            types :  PhantomData , 
3232        } 
3333    } 
@@ -40,45 +40,34 @@ where
4040    type  Item  = Result < T ,  IterError > ; 
4141
4242    fn  next ( & mut  self )  -> Option < Self :: Item >  { 
43-         // closure which reads a single entry starting from `self.pos` 
44-         let  read_one =
45-             |f :  & mut  EntryReader ,  start_pos :  Option < u64 > | -> Result < Option < T > ,  IterError >  { 
46-                 if  let  Some ( pos)  = start_pos { 
47-                     f. seek ( io:: SeekFrom :: Start ( pos) ) ?; 
48-                 } 
49-                 match  bincode_options ( ) . deserialize_from ( & mut  * f)  { 
50-                     Ok ( changeset)  => { 
51-                         f. clear_count ( ) ; 
52-                         Ok ( Some ( changeset) ) 
53-                     } 
54-                     Err ( e)  => { 
55-                         // allow unexpected EOF if 0 bytes were read 
56-                         if  let  bincode:: ErrorKind :: Io ( inner)  = & * e { 
57-                             if  inner. kind ( )  == io:: ErrorKind :: UnexpectedEof  && f. count ( )  == 0  { 
58-                                 f. clear_count ( ) ; 
59-                                 return  Ok ( None ) ; 
60-                             } 
43+         if  self . finished  { 
44+             return  None ; 
45+         } 
46+         ( || { 
47+             if  let  Some ( start)  = self . start_pos . take ( )  { 
48+                 self . db_file . seek ( io:: SeekFrom :: Start ( start) ) ?; 
49+             } 
50+ 
51+             let  pos_before_read = self . db_file . stream_position ( ) ?; 
52+             match  bincode_options ( ) . deserialize_from ( & mut  self . db_file )  { 
53+                 Ok ( changeset)  => Ok ( Some ( changeset) ) , 
54+                 Err ( e)  => { 
55+                     self . finished  = true ; 
56+                     let  pos_after_read = self . db_file . stream_position ( ) ?; 
57+                     // allow unexpected EOF if 0 bytes were read 
58+                     if  let  bincode:: ErrorKind :: Io ( inner)  = & * e { 
59+                         if  inner. kind ( )  == io:: ErrorKind :: UnexpectedEof 
60+                             && pos_after_read == pos_before_read
61+                         { 
62+                             return  Ok ( None ) ; 
6163                        } 
62-                         f. rewind ( ) ?; 
63-                         Err ( IterError :: Bincode ( * e) ) 
6464                    } 
65+                     self . db_file . seek ( io:: SeekFrom :: Start ( pos_before_read) ) ?; 
66+                     Err ( IterError :: Bincode ( * e) ) 
6567                } 
66-             } ; 
67-         let  result = read_one ( self . db_file . as_mut ( ) ?,  self . start_pos . take ( ) ) ; 
68-         if  result. is_err ( )  { 
69-             self . db_file  = None ; 
70-         } 
71-         result. transpose ( ) 
72-     } 
73- } 
74- 
75- impl < ' t ,  T >  Drop  for  EntryIter < ' t ,  T >  { 
76-     fn  drop ( & mut  self )  { 
77-         if  let  Some ( r)  = self . db_file . as_mut ( )  { 
78-             // This syncs the underlying file's offset with the buffer's position. This way, no data 
79-             // is lost with future reads. 
80-             let  _ = r. stream_position ( ) ; 
81-         } 
68+             } 
69+         } ) ( ) 
70+         . transpose ( ) 
8271    } 
8372} 
8473
@@ -107,51 +96,3 @@ impl From<io::Error> for IterError {
10796} 
10897
10998impl  std:: error:: Error  for  IterError  { } 
110- 
111- /// A wrapped [`Reader`] which counts total bytes read. 
112- struct  CountingReader < R >  { 
113-     r :  R , 
114-     n :  u64 , 
115- } 
116- 
117- impl < R >  CountingReader < R >  { 
118-     fn  new ( file :  R )  -> Self  { 
119-         Self  {  r :  file,  n :  0  } 
120-     } 
121- 
122-     /// Counted bytes read. 
123-      fn  count ( & self )  -> u64  { 
124-         self . n 
125-     } 
126- 
127-     /// Clear read count. 
128-      fn  clear_count ( & mut  self )  { 
129-         self . n  = 0 ; 
130-     } 
131- } 
132- 
133- impl < R :  io:: Seek >  CountingReader < R >  { 
134-     /// Rewind file descriptor offset to before all counted read operations. Then clear the read 
135-      /// count. 
136-      fn  rewind ( & mut  self )  -> io:: Result < u64 >  { 
137-         let  read = self . r . seek ( std:: io:: SeekFrom :: Current ( -( self . n  as  i64 ) ) ) ?; 
138-         self . n  = 0 ; 
139-         Ok ( read) 
140-     } 
141- } 
142- 
143- impl < R :  io:: Read >  io:: Read  for  CountingReader < R >  { 
144-     fn  read ( & mut  self ,  buf :  & mut  [ u8 ] )  -> io:: Result < usize >  { 
145-         let  read = self . r . read ( & mut  * buf) ?; 
146-         self . n  += read as  u64 ; 
147-         Ok ( read) 
148-     } 
149- } 
150- 
151- impl < R :  io:: Seek >  io:: Seek  for  CountingReader < R >  { 
152-     fn  seek ( & mut  self ,  pos :  io:: SeekFrom )  -> io:: Result < u64 >  { 
153-         let  res = self . r . seek ( pos) ; 
154-         self . n  = 0 ; 
155-         res
156-     } 
157- } 
0 commit comments