1 #ifndef FILE_PERSIST_LOG_HPP 2 #define FILE_PERSIST_LOG_HPP 12 #define META_FILE_SUFFIX "meta" 13 #define LOG_FILE_SUFFIX "log" 14 #define DATA_FILE_SUFFIX "data" 15 #define SWAP_FILE_SUFFIX "swp" 50 #define MAX_LOG_ENTRY (this->m_iMaxLogEntry) 51 #define MAX_LOG_SIZE (sizeof(LogEntry) * MAX_LOG_ENTRY) 52 #define MAX_DATA_SIZE (this->m_iMaxDataSize) 53 #define META_SIZE (sizeof(MetaHeader)) 57 #define META_HEADER ((MetaHeader*)(&(this->m_currMetaHeader))) 58 #define META_HEADER_PERS ((MetaHeader*)(&(this->m_persMetaHeader))) 59 #define LOG_ENTRY_ARRAY ((LogEntry*)(this->m_pLog)) 61 #define NUM_USED_SLOTS (META_HEADER->fields.tail - META_HEADER->fields.head) 63 #define NUM_FREE_SLOTS (MAX_LOG_ENTRY - 1 - NUM_USED_SLOTS) 66 #define LOG_ENTRY_AT(idx) (LOG_ENTRY_ARRAY + (int)((idx) % MAX_LOG_ENTRY)) 67 #define NEXT_LOG_ENTRY LOG_ENTRY_AT(META_HEADER->fields.tail) 68 #define NEXT_LOG_ENTRY_PERS LOG_ENTRY_AT( \ 69 MAX(META_HEADER_PERS->fields.tail, META_HEADER->fields.head)) 70 #define CURR_LOG_IDX ((NUM_USED_SLOTS == 0) ? -1 : META_HEADER->fields.tail - 1) 71 #define LOG_ENTRY_DATA(e) ((void*)((uint8_t*)this->m_pData + (e)->fields.ofst % MAX_DATA_SIZE)) 73 #define NEXT_DATA_OFST ((CURR_LOG_IDX == -1) ? 0 : (LOG_ENTRY_AT(CURR_LOG_IDX)->fields.ofst + LOG_ENTRY_AT(CURR_LOG_IDX)->fields.dlen)) 74 #define NEXT_DATA ((void*)((uint64_t) this->m_pData + NEXT_DATA_OFST % MAX_DATA_SIZE)) 75 #define NEXT_DATA_PERS ((NEXT_LOG_ENTRY > NEXT_LOG_ENTRY_PERS) ? LOG_ENTRY_DATA(NEXT_LOG_ENTRY_PERS) : NULL) 77 #define NUM_USED_BYTES ((NUM_USED_SLOTS == 0) ? 0 : (LOG_ENTRY_AT(CURR_LOG_IDX)->fields.ofst + LOG_ENTRY_AT(CURR_LOG_IDX)->fields.dlen - LOG_ENTRY_AT(META_HEADER->fields.head)->fields.ofst)) 78 #define NUM_FREE_BYTES (MAX_DATA_SIZE - NUM_USED_BYTES) 80 #define PAGE_SIZE (getpagesize()) 81 #define ALIGN_TO_PAGE(x) ((void*)(((uint64_t)(x)) - ((uint64_t)(x)) % PAGE_SIZE)) 84 template <
typename TKey,
typename KeyGetter>
85 int64_t
binarySearch(
const KeyGetter&,
const TKey&,
const int64_t&,
const int64_t&);
124 if(pthread_rwlock_wrlock(&this->m_rwlock) != 0) { \ 125 throw PERSIST_EXP_RWLOCK_WRLOCK(errno); \ 131 if(pthread_rwlock_rdlock(&this->m_rwlock) != 0) { \ 132 throw PERSIST_EXP_RWLOCK_WRLOCK(errno); \ 138 if(pthread_rwlock_unlock(&this->m_rwlock) != 0) { \ 139 throw PERSIST_EXP_RWLOCK_UNLOCK(errno); \ 143 #define FPL_PERS_LOCK \ 145 if(pthread_mutex_lock(&this->m_perslock) != 0) { \ 146 throw PERSIST_EXP_MUTEX_LOCK(errno); \ 150 #define FPL_PERS_UNLOCK \ 152 if(pthread_mutex_unlock(&this->m_perslock) != 0) { \ 153 throw PERSIST_EXP_MUTEX_UNLOCK(errno); \ 159 virtual void load() noexcept(false);
162 virtual
void reset() noexcept(false);
166 virtual
void persistMetaHeaderAtomically(
MetaHeader*) noexcept(false);
170 FilePersistLog(const
std::
string& name, const
std::
string& dataPath) noexcept(false);
176 virtual void append(
const void* pdata,
177 const uint64_t& size,
const int64_t& ver,
178 const HLC& mhlc) noexcept(
false);
179 virtual void advanceVersion(
const int64_t& ver) noexcept(
false);
180 virtual int64_t getLength() noexcept(
false);
181 virtual int64_t getEarliestIndex() noexcept(
false);
182 virtual int64_t getLatestIndex() noexcept(
false);
183 virtual int64_t getVersionIndex(
const version_t& ver) noexcept(
false);
184 virtual int64_t getHLCIndex(
const HLC& hlc) noexcept(
false);
185 virtual version_t getEarliestVersion() noexcept(
false);
186 virtual version_t getLatestVersion() noexcept(
false);
187 virtual const version_t getLastPersisted() noexcept(
false);
188 virtual const void* getEntryByIndex(
const int64_t& eno) noexcept(
false);
189 virtual const void* getEntry(
const version_t& ver) noexcept(
false);
190 virtual const void* getEntry(
const HLC& hlc) noexcept(
false);
191 virtual const version_t persist(
const bool preLocked =
false) noexcept(
false);
192 virtual void trimByIndex(
const int64_t& eno) noexcept(
false);
193 virtual void trim(
const version_t& ver) noexcept(
false);
194 virtual void trim(
const HLC& hlc) noexcept(
false);
195 virtual void truncate(
const version_t& ver) noexcept(
false);
198 virtual void post_object(
const std::function<
void(
char const*
const, std::size_t)>& f,
200 virtual void applyLogTail(
char const* v) noexcept(
false);
202 template <
typename TKey,
typename KeyGetter>
203 void trim(
const TKey& key,
const KeyGetter& keyGetter) noexcept(
false) {
224 }
catch(uint64_t e) {
249 bool checkOrCreateMetaFile() noexcept(
false);
252 bool checkOrCreateLogFile() noexcept(
false);
255 bool checkOrCreateDataFile() noexcept(
false);
264 int64_t getMinimumIndexBeyondVersion(
const int64_t& ver) noexcept(
false);
271 size_t byteSizeOfLogEntry(
const LogEntry* ple) noexcept(
false);
278 size_t writeLogEntryToByteArray(
const LogEntry* ple,
char* ba) noexcept(
false);
286 size_t postLogEntry(
const std::function<
void(
char const*
const, std::size_t)>& f,
const LogEntry* ple) noexcept(
false);
293 size_t mergeLogEntryFromByteArray(
const char* ba) noexcept(
false);
307 template <
typename TKey,
typename KeyGetter>
309 const int64_t& logHead,
const int64_t& logTail) noexcept(
false) {
310 if(logTail <= logHead) {
314 int64_t head = logHead, tail = logTail - 1;
316 while(head <= tail) {
317 pivot = (head + tail) / 2;
322 }
else if(p_key < key) {
323 if(pivot + 1 >= logTail) {
344 dbg_default_trace(
"m_pData={0},m_pLog={1}", (
void*)this->m_pData, (
void*)this->m_pLog);
349 #endif //DERECHO_DEBUG 353 #endif //FILE_PERSIST_LOG_HPP const std::string m_sMetaFile
pthread_rwlock_t m_rwlock
This file include all common types internal to derecho and not necessarily being known by a client pr...
union persistent::log_entry LogEntry
union persistent::meta_header MetaHeader
MetaHeader m_currMetaHeader
const std::enable_if<(storageType==ST_FILE||storageType==ST_MEM), version_t >::type getMinimumLatestPersistedVersion(const std::type_index &subgroup_type, uint32_t subgroup_index, uint32_t shard_num)
get the minmum latest persisted version for a Replicated<T> identified by
int64_t binarySearch(const KeyGetter &keyGetter, const TKey &key, const int64_t &logHead, const int64_t &logTail) noexcept(false)
binary search through the log, return the maximum index of the entries whose key <= ...
const uint64_t m_iMaxDataSize
auto bytes_size(const T &)
Just calls sizeof(T)
std::string getPersFilePath()
const std::string m_sDataPath
#define LOG_ENTRY_AT(idx)
#define NEXT_LOG_ENTRY_PERS
MetaHeader m_persMetaHeader
#define dbg_default_trace(...)
int64_t binarySearch(const KeyGetter &, const TKey &, const int64_t &, const int64_t &)
void trim(const TKey &key, const KeyGetter &keyGetter) noexcept(false)
const std::string m_sDataFile
std::enable_if_t< std::is_pod< BR >::value > post_object(const F &f, const BR &br, Args &&... args)
In-place serialization is also sometimes possible.
const std::string m_sLogFile
std::size_t to_bytes(const ByteRepresentable &b, char *v)
calls b.to_bytes(v) when b is a ByteRepresentable; calls std::memcpy() when b is POD.
const uint64_t m_iMaxLogEntry
pthread_mutex_t m_perslock