diff --git a/common/src/writer.rs b/common/src/writer.rs index f871a9b9e..8056b11d8 100644 --- a/common/src/writer.rs +++ b/common/src/writer.rs @@ -65,7 +65,7 @@ pub struct AntiCallToken(()); /// /// Thread-safety is enforced at the call sites that require it. pub trait TerminatingWrite: Write { - /// Indicates that the writer will no longer be used. Internally calls `terminate_ref`. + /// Indicate that the writer will no longer be used. Internally call terminate_ref. fn terminate(mut self) -> io::Result<()> where Self: Sized { self.terminate_ref(AntiCallToken(())) @@ -84,9 +84,7 @@ impl TerminatingWrite for Box { impl TerminatingWrite for BufWriter { fn terminate_ref(&mut self, a: AntiCallToken) -> io::Result<()> { - if !self.buffer().is_empty() { - self.flush()?; - } + self.flush()?; self.get_mut().terminate_ref(a) } } diff --git a/src/directory/directory.rs b/src/directory/directory.rs index 46b3c669f..9e3a7b14d 100644 --- a/src/directory/directory.rs +++ b/src/directory/directory.rs @@ -139,15 +139,21 @@ pub trait Directory: DirectoryClone + fmt::Debug + Send + Sync + 'static { /// Opens a writer for the *virtual file* associated with /// a [`Path`]. /// - /// Depending on the directory implementation, [`Directory::sync_directory()`] may be required - /// after terminating the writer to ensure that the file is durably created. + /// After the writer is terminated, the file should be created and any subsequent call to + /// [`Directory::open_read()`] for the same path should return a [`FileSlice`]. /// - /// Write operations may be aggressively buffered. The client must call - /// [`TerminatingWrite::terminate()`] to finalize the file and make all writes available to - /// subsequent reads. The directory implementation owns its buffering strategy; clients should - /// not rely on `flush()` making an incomplete file available. + /// However, depending on the directory implementation, + /// it might be required to call [`Directory::sync_directory()`] to ensure + /// that the file is durably created. + /// (The semantics here are the same when dealing with + /// a POSIX filesystem.) /// - /// The user shall not rely on [`Drop`] finalizing the file. + /// Write operations may be aggressively buffered. + /// The client of this trait is responsible for calling terminate + /// to ensure that subsequent `read` operations + /// will take into account preceding `write` operations. + /// + /// The user shall not rely on [`Drop`] triggering terminate. /// /// The file may not previously exist. fn open_write(&self, path: &Path) -> Result; diff --git a/src/directory/footer.rs b/src/directory/footer.rs index d2ff52f9a..bffa2f2cf 100644 --- a/src/directory/footer.rs +++ b/src/directory/footer.rs @@ -126,9 +126,9 @@ impl Footer { } pub(crate) struct FooterProxy { - /// Always `Some` except after `terminate()` is called. + /// always Some except after terminate call hasher: Option, - /// Always `Some` except after `terminate()` is called. + /// always Some except after terminate call writer: Option, } diff --git a/src/directory/mmap_directory/mod.rs b/src/directory/mmap_directory/mod.rs index 061a4ca5f..1c33f0358 100644 --- a/src/directory/mmap_directory/mod.rs +++ b/src/directory/mmap_directory/mod.rs @@ -318,7 +318,8 @@ impl Drop for ReleaseLockFile { } } -/// Wraps a file and syncs its data when the writer is terminated. +/// This Write wraps a File, but has the specificity of +/// calling `sync_all` on terminate. struct SafeFileWriter(File); impl SafeFileWriter { diff --git a/src/directory/ram_directory.rs b/src/directory/ram_directory.rs index 87b5b46a9..bfa3d0ecb 100644 --- a/src/directory/ram_directory.rs +++ b/src/directory/ram_directory.rs @@ -60,7 +60,7 @@ impl Drop for MemoryUsageTracker { /// Writer associated with the [`RamDirectory`]. /// -/// The writer stores its buffer in the directory when terminated. +/// The Writer just writes a buffer. struct VecWriter { path: PathBuf, shared_directory: RamDirectory, @@ -109,8 +109,6 @@ impl Write for VecWriter { Ok(buf.len()) } - /// Nothing to flush since the data is stored in memory. The memory usage is updated on each - /// write. fn flush(&mut self) -> io::Result<()> { Ok(()) } diff --git a/src/fastfield/alive_bitset.rs b/src/fastfield/alive_bitset.rs index ed2f8dfe8..bbdc82a45 100644 --- a/src/fastfield/alive_bitset.rs +++ b/src/fastfield/alive_bitset.rs @@ -8,7 +8,7 @@ use crate::DocId; /// Write an alive `BitSet` /// /// where `alive_bitset` is the set of alive `DocId`. -/// Warning: this function does not call `terminate()`. The caller is in charge of +/// Warning: this function does not call terminate. The caller is in charge of /// closing the writer properly. pub fn write_alive_bitset(alive_bitset: &BitSet, writer: &mut T) -> io::Result<()> { alive_bitset.serialize(writer)?; diff --git a/src/positions/serializer.rs b/src/positions/serializer.rs index 617033909..f41923e8b 100644 --- a/src/positions/serializer.rs +++ b/src/positions/serializer.rs @@ -86,8 +86,8 @@ impl PositionSerializer { Ok(()) } - /// Close the positions for this field. - pub fn close(self) -> io::Result<()> { - Ok(()) + /// Close the positions for this term and flushes the data. + pub fn close(mut self) -> io::Result<()> { + self.positions_wrt.flush() } }