Jing Yang %!s(int64=5) %!d(string=hai) anos
pai
achega
19e016ecea
Modificáronse 1 ficheiros con 48 adicións e 2 borrados
  1. 48 2
      src/log_array.rs

+ 48 - 2
src/log_array.rs

@@ -1,11 +1,37 @@
 use crate::{Index, LogEntry, Term};
 
+/// A log array that stores a tail of the whole Raft log.
+///
+/// The Raft log represented by the log array has length `end()`. Only log
+/// entries after `start()` are physically stored in the log array (with some
+/// caveats). The index and term of log entries in range `[start(), end())` are
+/// accessible. A snapshot is stored at the beginning of the log array, which
+/// covers all commands before and **including** `start()`. The command at
+/// `start()` is **not** accessible, but all commands after that are.
+///
+/// New entries can be appended to the end of the Raft log via `add_command()`
+/// or `push()`.
+///
+/// The log array can be truncated to at most one entry, which is at `start()`
+/// and contains the snapshot. The start of the log array can be shifted towards
+/// `end()`, if another snapshot at that position is provided.
+///
+/// The log array can also be reset to a single entry, contains an index, a term
+/// and a snapshot, via `reset()`.
+///
+/// The log array is guaranteed to have at least one element, containing an
+/// index, a term and a snapshot.
+///
+/// All APIs **will** panic if the given index(es) are out of bound.
+///
+/// NOT THREAD SAFE.
 pub(crate) struct LogArray<C> {
     inner: Vec<LogEntry<C>>,
     snapshot: bytes::Bytes,
 }
 
 impl<C: Default> LogArray<C> {
+    /// Create the initial Raft log with no user-supplied commands.
     pub fn create() -> LogArray<C> {
         let ret = LogArray {
             inner: vec![Self::build_first_entry(0, Term(0))],
@@ -25,45 +51,55 @@ impl<C: Default> LogArray<C> {
 
 // Log accessors
 impl<C> LogArray<C> {
+    /// The start of the stored log entries. The command at this index is no
+    /// longer accessible, since it is included in the snapshot.
     pub fn start(&self) -> Index {
         self.first_entry().index
     }
 
+    /// The end index of the Raft log.
     pub fn end(&self) -> usize {
         self.start() + self.inner.len()
     }
 
+    /// The first index and term stored in this log array.
     #[allow(dead_code)]
     pub fn first_index_term(&self) -> (Index, Term) {
         let first_entry = self.first_entry();
         (first_entry.index, first_entry.term)
     }
 
+    /// The last index and term of the Raft log.
     pub fn last_index_term(&self) -> (Index, Term) {
         let last_entry = self.last_entry();
         (last_entry.index, last_entry.term)
     }
 
+    /// The log entry at the given index.
     pub fn at(&self, index: Index) -> &LogEntry<C> {
         let index = self.check_start_index(index);
         &self.inner[index]
     }
 
+    /// All log entries after the given index.
     pub fn after(&self, index: Index) -> &[LogEntry<C>] {
         let index = self.check_start_index(index);
         &self.inner[index..]
     }
 
+    /// All log entries in range [start, end).
     pub fn between(&self, start: Index, end: Index) -> &[LogEntry<C>] {
         let start = self.check_start_index(start);
         let end = self.check_end_index(end);
         &self.inner[start..end]
     }
 
+    /// All log entries stored in the array.
     pub fn all(&self) -> &[LogEntry<C>] {
         &self.inner[..]
     }
 
+    /// The snapshot before and including `start()`.
     #[allow(dead_code)]
     pub fn snapshot(&self) -> &bytes::Bytes {
         &self.snapshot
@@ -80,6 +116,8 @@ impl<C> std::ops::Index<usize> for LogArray<C> {
 
 // Mutations
 impl<C> LogArray<C> {
+    /// Add a new entry to the Raft log, with term and command. The new index is
+    /// returned.
     pub fn add_command(&mut self, term: Term, command: C) -> Index {
         let index = self.end();
         self.push(LogEntry {
@@ -90,6 +128,8 @@ impl<C> LogArray<C> {
         index
     }
 
+    /// Push a LogEntry into the Raft log. The index of the log entry must match
+    /// the next index in the log.
     pub fn push(&mut self, log_entry: LogEntry<C>) {
         let index = log_entry.index;
         assert_eq!(index, self.end(), "Expecting new index to be exact at len");
@@ -107,6 +147,7 @@ impl<C> LogArray<C> {
         self.check_one_element();
     }
 
+    /// Remove all log entries on and after `index`.
     pub fn truncate(&mut self, index: Index) {
         let index = self.check_middle_index(index);
         self.inner.truncate(index);
@@ -115,6 +156,8 @@ impl<C> LogArray<C> {
 }
 
 impl<C: Default> LogArray<C> {
+    /// Shift the start of the array to `index`, and store a new snapshot that
+    /// covers all commands before and at `index`.
     #[allow(dead_code)]
     pub fn shift(&mut self, index: Index, snapshot: bytes::Bytes) {
         // Discard everything before index and store the snapshot.
@@ -123,8 +166,9 @@ impl<C: Default> LogArray<C> {
         self.inner.drain(0..offset);
         self.snapshot = snapshot;
 
-        // Override the first entry, we know there is at least one entry. This is not strictly
-        // needed. One benefit is that the command can be released after this point.
+        // Override the first entry, we know there is at least one entry. This
+        // is not strictly needed. One benefit is that the command can be
+        // released after this point.
         let (first_index, first_term) = self.first_index_term();
         self.inner[0] = Self::build_first_entry(first_index, first_term);
 
@@ -136,6 +180,8 @@ impl<C: Default> LogArray<C> {
         self.check_one_element()
     }
 
+    /// Reset the array to contain only one snapshot at the given `index` with
+    /// the given `term`.
     #[allow(dead_code)]
     pub fn reset(
         &mut self,