Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 330ed30

Browse files
committed
add more docs for transactional methods, #67 and #71
1 parent 28ddf1e commit 330ed30

File tree

2 files changed

+56
-13
lines changed

2 files changed

+56
-13
lines changed

src/file.rs

+33-9
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use trans::{TxHandle, TxMgr};
1111

1212
/// A reader for a specific vesion of file content.
1313
///
14-
/// This reader can be obtained by [`version_reader`] function, and it
14+
/// This reader can be obtained by [`version_reader`] method, and it
1515
/// implements [`Read`] trait.
1616
///
1717
/// [`version_reader`]: struct.File.html#method.version_reader
@@ -130,7 +130,7 @@ impl Seek for VersionReader {
130130
/// File content is cached internally for deduplication and will be handled
131131
/// automatically, thus calling [`flush`] is **not** recommended.
132132
///
133-
/// `File` can be sent to multiple threads, but only thread can modify it at
133+
/// `File` can be sent to multiple threads, but only one thread can modify it at
134134
/// a time, which is similar to a `RwLock`.
135135
///
136136
/// `File` is multi-versioned, each time updating its content will create a new
@@ -143,9 +143,10 @@ impl Seek for VersionReader {
143143
/// version. Unless [`finish`] was successfully returned, no data will be
144144
/// written to the file.
145145
///
146-
/// Internally, a transaction is created when writing to the file and calling
147-
/// [`finish`] will commit that transaction. Thus, you should not call
148-
/// [`finish`] in case of any writing failure.
146+
/// Internally, a transaction is created when writing to the file first time
147+
/// and calling [`finish`] will commit that transaction. If any errors
148+
/// happened during [`write`], that transaction will be aborted. Thus, you
149+
/// should not call [`finish`] after any failed [`write`].
149150
///
150151
/// ## Examples
151152
///
@@ -207,6 +208,20 @@ impl Seek for VersionReader {
207208
/// # foo().unwrap();
208209
/// ```
209210
///
211+
/// To gurantee atomicity, ZboxFS uses transaction when updating file so the
212+
/// data either be wholly persisted or nothing has been written.
213+
///
214+
/// - For multi-part write, the transaction begins in the first-time [`write`]
215+
/// and will be committed in [`finish`]. Any failure in [`write`] will abort
216+
/// the transaction, thus [`finish`] should not be called after that. If error
217+
/// happened during [`finish`], the transaction will also be aborted.
218+
/// - For single-part write, [`write_once`] itself is transactional. The
219+
/// transaction begins and will be committed inside this method.
220+
///
221+
/// Keep in mind of those characteristics, especially when writing a large
222+
/// amount of data to file, because any uncomitted transactions will abort
223+
/// and data in those transactions won't be persisted.
224+
///
210225
/// # Reading
211226
///
212227
/// As `File` can contain multiple versions, [`Read`] operation can be
@@ -450,11 +465,16 @@ impl File {
450465

451466
/// Complete multi-part write to file and create a new version.
452467
///
468+
/// This method will try to commit the transaction internally, no data will
469+
/// be persisted if it failed. Do not call this method if any previous
470+
/// [`write`] failed.
471+
///
453472
/// # Errors
454473
///
455-
/// Calling this function without writing data before will return
474+
/// Calling this method without writing data before will return
456475
/// [`Error::NotWrite`] error.
457476
///
477+
/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
458478
/// [`Error::NotWrite`]: enum.Error.html
459479
pub fn finish(&mut self) -> Result<()> {
460480
self.check_closed()?;
@@ -486,9 +506,11 @@ impl File {
486506

487507
/// Single-part write to file and create a new version.
488508
///
489-
/// This function provides a convenient way of combining [`Write`] and
509+
/// This method provides a convenient way of combining [`Write`] and
490510
/// [`finish`].
491511
///
512+
/// This method is atomic.
513+
///
492514
/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
493515
/// [`finish`]: struct.File.html#method.finish
494516
pub fn write_once(&mut self, buf: &[u8]) -> Result<()> {
@@ -522,10 +544,12 @@ impl File {
522544
/// then the content will be extended to `size` and have all of the
523545
/// intermediate data filled in with 0s.
524546
///
547+
/// This method is atomic.
548+
///
525549
/// # Errors
526550
///
527-
/// This function will return an error if the file is not opened for
528-
/// writing or not finished writing.
551+
/// This method will return an error if the file is not opened for writing
552+
/// or not finished writing.
529553
pub fn set_len(&mut self, len: usize) -> Result<()> {
530554
self.check_closed()?;
531555
if self.wtr.is_some() {

src/repo.rs

+23-4
Original file line numberDiff line numberDiff line change
@@ -801,12 +801,13 @@ impl Repo {
801801
/// Create a file in read-write mode.
802802
///
803803
/// This method will create a file if it does not exist, and will
804-
/// truncate it if it does.
805-
///
806-
/// See the [`OpenOptions::open`](struct.OpenOptions.html#method.open)
807-
/// method for more details.
804+
/// truncate it if it does. See the
805+
/// [`OpenOptions::open`](struct.OpenOptions.html#method.open) method for
806+
/// more details.
808807
///
809808
/// `path` must be an absolute path.
809+
///
810+
/// This method is **not** atomic.
810811
#[inline]
811812
pub fn create_file<P: AsRef<Path>>(&mut self, path: P) -> Result<File> {
812813
OpenOptions::new()
@@ -849,6 +850,8 @@ impl Repo {
849850
/// Creates a new, empty directory at the specified path.
850851
///
851852
/// `path` must be an absolute path.
853+
///
854+
/// This method is atomic.
852855
#[inline]
853856
pub fn create_dir<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
854857
self.fs
@@ -860,6 +863,9 @@ impl Repo {
860863
/// are missing.
861864
///
862865
/// `path` must be an absolute path.
866+
///
867+
/// This method is **not** atomic in whole, but creating each entry is
868+
/// atomic.
863869
#[inline]
864870
pub fn create_dir_all<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
865871
self.fs.create_dir_all(path.as_ref())
@@ -896,6 +902,8 @@ impl Repo {
896902
/// `from` and `to` must be absolute paths to regular files.
897903
///
898904
/// If `from` and `to` both point to the same file, this method is no-op.
905+
///
906+
/// This method is **not** atomic.
899907
#[inline]
900908
pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(
901909
&mut self,
@@ -919,6 +927,8 @@ impl Repo {
919927
///
920928
/// If `from` and `to` both point to the same directory, this method is
921929
/// no-op.
930+
///
931+
/// This method is **not** atomic.
922932
#[inline]
923933
pub fn copy_dir_all<P: AsRef<Path>, Q: AsRef<Path>>(
924934
&mut self,
@@ -931,6 +941,8 @@ impl Repo {
931941
/// Removes a regular file from the repository.
932942
///
933943
/// `path` must be an absolute path.
944+
///
945+
/// This method is atomic.
934946
#[inline]
935947
pub fn remove_file<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
936948
self.fs.remove_file(path.as_ref())
@@ -939,6 +951,8 @@ impl Repo {
939951
/// Remove an existing empty directory.
940952
///
941953
/// `path` must be an absolute path.
954+
///
955+
/// This method is atomic.
942956
#[inline]
943957
pub fn remove_dir<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
944958
self.fs.remove_dir(path.as_ref())
@@ -948,6 +962,9 @@ impl Repo {
948962
/// Use carefully!
949963
///
950964
/// `path` must be an absolute path.
965+
///
966+
/// This method is **not** atomic in whole, but removing each entry is
967+
/// atomic.
951968
#[inline]
952969
pub fn remove_dir_all<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
953970
self.fs.remove_dir_all(path.as_ref())
@@ -957,6 +974,8 @@ impl Repo {
957974
/// if `to` already exists.
958975
///
959976
/// `from` and `to` must be absolute paths.
977+
///
978+
/// This method is atomic.
960979
#[inline]
961980
pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(
962981
&mut self,

0 commit comments

Comments
 (0)