LogCabin
|
00001 /* Copyright (c) 2012-2014 Stanford University 00002 * 00003 * Permission to use, copy, modify, and distribute this software for any 00004 * purpose with or without fee is hereby granted, provided that the above 00005 * copyright notice and this permission notice appear in all copies. 00006 * 00007 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES 00008 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 00009 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR 00010 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 00011 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 00012 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 00013 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 00014 */ 00015 00016 #include <cinttypes> 00017 #include <memory> 00018 #include <vector> 00019 00020 #include "build/Protocol/Raft.pb.h" 00021 #include "build/Protocol/RaftLogMetadata.pb.h" 00022 00023 #ifndef LOGCABIN_STORAGE_LOG_H 00024 #define LOGCABIN_STORAGE_LOG_H 00025 00026 namespace LogCabin { 00027 00028 // forward declaration 00029 namespace Protocol { 00030 class ServerStats; 00031 } 00032 00033 namespace Storage { 00034 00035 /** 00036 * This interface is used by RaftConsensus to store log entries and metadata. 00037 * Typically, implementations will persist the log entries and metadata to 00038 * stable storage (but MemoryLog keeps it all in volatile memory). 00039 */ 00040 class Log { 00041 public: 00042 /** 00043 * An interface for flushing newly appended log entries to stable storage. 00044 * Leaders do this in a separate thread, while followers and candidates do 00045 * this immediately after appending the entries. 00046 * 00047 * Callers should wait() on all Sync objects prior to calling 00048 * truncateSuffix(). This never happens on leaders, so it's not a real 00049 * limitation, but things may go wonky otherwise. 00050 */ 00051 class Sync { 00052 public: 00053 explicit Sync(uint64_t lastIndex); 00054 virtual ~Sync(); 00055 /** 00056 * Wait for the log entries to be durable. 00057 * This is safe to call while the Log is being accessed and modified 00058 * from a separate thread. 00059 * PANICs on errors. 00060 */ 00061 virtual void wait() {} 00062 /** 00063 * The index of the last log entry that is being flushed. 00064 * After the call to wait, every entry in the log up to this one is 00065 * durable. 00066 */ 00067 uint64_t lastIndex; 00068 /** 00069 * Used by destructor to make sure that Log::syncComplete was called. 00070 */ 00071 bool completed; 00072 }; 00073 00074 /** 00075 * The type of a log entry (the same format that's used in AppendEntries). 00076 */ 00077 typedef Protocol::Raft::Entry Entry; 00078 00079 Log(); 00080 virtual ~Log(); 00081 00082 /** 00083 * Start to append new entries to the log. The entries may not be on disk 00084 * yet when this returns; see Sync. 00085 * \param entries 00086 * Entries to place at the end of the log. 00087 * \return 00088 * Range of indexes of the new entries in the log, inclusive. 00089 */ 00090 virtual std::pair<uint64_t, uint64_t> append( 00091 const std::vector<const Entry*>& entries) = 0; 00092 00093 /** 00094 * Look up an entry by its log index. 00095 * \param index 00096 * Must be in the range [getLogStartIndex(), getLastLogIndex()]. 00097 * Otherwise, this will crash the server. 00098 * \return 00099 * The entry corresponding to that index. This reference is only 00100 * guaranteed to be valid until the next time the log is modified. 00101 */ 00102 virtual const Entry& getEntry(uint64_t index) const = 0; 00103 00104 /** 00105 * Get the index of the first entry in the log (whether or not this 00106 * entry exists). 00107 * \return 00108 * 1 for logs that have never had truncatePrefix called, 00109 * otherwise the largest index passed to truncatePrefix. 00110 */ 00111 virtual uint64_t getLogStartIndex() const = 0; 00112 00113 /** 00114 * Get the index of the most recent entry in the log. 00115 * \return 00116 * The index of the most recent entry in the log, 00117 * or getLogStartIndex() - 1 if the log is empty. 00118 */ 00119 virtual uint64_t getLastLogIndex() const = 0; 00120 00121 /** 00122 * Return the name of the log implementation as it would be specified in 00123 * the config file. 00124 */ 00125 virtual std::string getName() const = 0; 00126 00127 /** 00128 * Get the size of the entire log in bytes. 00129 */ 00130 virtual uint64_t getSizeBytes() const = 0; 00131 00132 /** 00133 * Release resources attached to the Sync object. 00134 * Call this after waiting on the Sync object. 00135 */ 00136 void syncComplete(std::unique_ptr<Sync> sync) { 00137 sync->completed = true; 00138 syncCompleteVirtual(std::move(sync)); 00139 } 00140 protected: 00141 /** 00142 * See syncComplete(). Intended for subclasses to override. 00143 */ 00144 virtual void syncCompleteVirtual(std::unique_ptr<Sync> sync) {} 00145 public: 00146 00147 /** 00148 * Get and remove the Log's Sync object in order to wait on it. 00149 * This Sync object must later be returned to the Log with syncComplete(). 00150 * 00151 * While takeSync() and syncComplete() may not be done concurrently with 00152 * other Log operations, Sync::wait() may be done concurrently with all 00153 * operations except truncateSuffix(). 00154 */ 00155 virtual std::unique_ptr<Sync> takeSync() = 0; 00156 00157 /** 00158 * Delete the log entries before the given index. 00159 * Once you truncate a prefix from the log, there's no way to undo this. 00160 * The entries may still be on disk when this returns and file descriptors 00161 * and other resources may remain open; see Sync. 00162 * \param firstIndex 00163 * After this call, the log will contain no entries indexed less 00164 * than firstIndex. This can be any log index, including 0 and those 00165 * past the end of the log. 00166 */ 00167 virtual void truncatePrefix(uint64_t firstIndex) = 0; 00168 00169 /** 00170 * Delete the log entries past the given index. 00171 * This will not affect the log start index. 00172 * \param lastIndex 00173 * After this call, the log will contain no entries indexed greater 00174 * than lastIndex. This can be any log index, including 0 and those 00175 * past the end of the log. 00176 * \warning 00177 * Callers should wait() on all Sync object prior to calling 00178 * truncateSuffix(). This never happens on leaders, so it's not a real 00179 * limitation, but things may go wonky otherwise. 00180 */ 00181 virtual void truncateSuffix(uint64_t lastIndex) = 0; 00182 00183 /** 00184 * Call this after changing #metadata. 00185 */ 00186 virtual void updateMetadata() = 0; 00187 00188 /** 00189 * Add information about the log's state to the given structure. 00190 * Used for diagnostics. 00191 */ 00192 virtual void updateServerStats(Protocol::ServerStats& serverStats) const {} 00193 00194 /** 00195 * Opaque metadata that the log keeps track of. 00196 */ 00197 Protocol::RaftLogMetadata::Metadata metadata; 00198 00199 /** 00200 * Print out a Log for debugging purposes. 00201 */ 00202 friend std::ostream& operator<<(std::ostream& os, const Log& log); 00203 00204 protected: 00205 00206 // Log is not copyable 00207 Log(const Log&) = delete; 00208 Log& operator=(const Log&) = delete; 00209 }; 00210 00211 } // namespace LogCabin::Storage 00212 } // namespace LogCabin 00213 00214 #endif /* LOGCABIN_STORAGE_LOG_H */