19 #include "../../Shared/File.h"
29 namespace File_Namespace {
34 const size_t pageSize,
36 const std::string& file_path,
43 , file_path(file_path) {
59 for (
size_t pageId = 0; pageId <
numPages; ++pageId) {
64 size_t FileInfo::write(
const size_t offset,
const size_t size,
const int8_t* buf) {
81 int32_t oldPageId = -99;
82 int32_t oldVersionEpoch = -99;
84 for (
size_t pageNum = 0; pageNum <
numPages; ++pageNum) {
88 constexpr
size_t MAX_INTS_TO_READ{10};
89 int32_t ints[MAX_INTS_TO_READ];
91 CHECK_EQ(fread(ints,
sizeof(int32_t), MAX_INTS_TO_READ,
f), MAX_INTS_TO_READ);
93 auto headerSize = ints[0];
94 if (headerSize == 0) {
102 size_t numHeaderElems = headerSize /
sizeof(int32_t);
103 CHECK_GE(numHeaderElems,
size_t(2));
106 ChunkKey chunkKey(&ints[1], &ints[1 + numHeaderElems - 2]);
112 int32_t pageId = ints[1 + numHeaderElems - 2];
113 int32_t versionEpoch = ints[1 + numHeaderElems - 1];
114 if (chunkKey != oldChunkKey || oldPageId != pageId - (1 + skipped)) {
116 VLOG(4) <<
"FId.PSz: " <<
fileId <<
"." << pageSize
118 <<
" Page id from : " << oldPageId <<
" to : " << oldPageId + skipped
119 <<
" Epoch: " << oldVersionEpoch;
120 }
else if (oldPageId != -99) {
121 VLOG(4) <<
"FId.PSz: " <<
fileId <<
"." << pageSize
122 <<
" Chunk key: " <<
show_chunk(oldChunkKey) <<
" Page id: " << oldPageId
123 <<
" Epoch: " << oldVersionEpoch;
126 oldVersionEpoch = versionEpoch;
127 oldChunkKey = chunkKey;
139 int32_t fileMgrEpoch =
141 if (versionEpoch > fileMgrEpoch) {
149 <<
" Page id: " << pageId <<
" Epoch: " << versionEpoch
150 <<
" FileMgrEpoch " << fileMgrEpoch << endl;
154 headerVec.emplace_back(chunkKey, pageId, versionEpoch, page);
158 if (oldPageId != -99) {
162 <<
" Page id from : " << oldPageId <<
" to : " << oldPageId + skipped
163 <<
" Epoch: " << oldVersionEpoch;
166 <<
" Chunk key: " <<
show_chunk(oldChunkKey) <<
" Page id: " << oldPageId
167 <<
" Epoch: " << oldVersionEpoch;
177 #ifdef ENABLE_CRASH_CORRUPTION_TEST
178 #warning "!!!!! DB corruption crash test is enabled !!!!!"
180 static bool goto_crash;
181 static void sighandler(
int sig) {
182 if (getenv(
"ENABLE_CRASH_CORRUPTION_TEST"))
193 sizeof(epoch_freed_page),
194 reinterpret_cast<const int8_t*>(epoch_freed_page));
197 #ifdef ENABLE_CRASH_CORRUPTION_TEST
198 signal(SIGUSR2, sighandler);
200 CHECK(pageId % 8 != 4);
211 int32_t pageNum = *pageIt;
217 std::stringstream ss;
218 ss <<
"File: " <<
fileId << std::endl;
219 ss <<
"Size: " <<
size() << std::endl;
220 ss <<
"Used: " <<
used() << std::endl;
221 ss <<
"Free: " <<
available() << std::endl;
228 if (fflush(
f) != 0) {
229 LOG(
FATAL) <<
"Error trying to flush changes to disk, the error was: "
230 << std::strerror(errno);
233 const int32_t sync_result = fcntl(fileno(
f), 51);
237 if (sync_result == 0) {
247 write(page_num *
pageSize,
sizeof(int32_t), reinterpret_cast<const int8_t*>(&zero));
256 reinterpret_cast<const int8_t*>(chunk_key.data()));
261 int32_t contingent) {
262 const bool delete_contingent =
265 if (delete_contingent && (table_epoch >= page_epoch)) {
273 int32_t contingent) {
274 const bool delete_contingent =
277 if (delete_contingent && (table_epoch < page_epoch)) {
virtual int32_t epoch(int32_t db_id, int32_t tb_id) const
Returns current value of epoch - should be one greater than recorded at last checkpoint. Because FileMgr only contains buffers from one table we can just return the FileMgr's epoch instead of finding a table-specific epoch.
std::vector< int > ChunkKey
size_t write(const size_t offset, const size_t size, const int8_t *buf)
bool is_page_deleted_without_checkpoint(int32_t table_epoch, int32_t page_epoch, int32_t contingent)
A logical page (Page) belongs to a file on disk.
std::mutex readWriteMutex_
void freePageImmediate(int32_t page_num)
This file includes the class specification for the FILE manager (FileMgr), and related data structure...
std::string print() const
Prints a summary of the file to stdout.
virtual bool updatePageIfDeleted(FileInfo *file_info, ChunkKey &chunk_key, int32_t contingent, int32_t page_epoch, int32_t page_num)
deletes or recovers a page based on last checkpointed epoch.
std::string file_path
set of page numbers of free pages
std::string show_chunk(const ChunkKey &key)
void freePage(int32_t pageId, const bool isRolloff, int32_t epoch)
std::set< size_t > freePages
size_t pageSize
file stream object for the represented file
constexpr int32_t DELETE_CONTINGENT
A FileInfo type has a file pointer and metadata about a file.
void init(LogOptions const &log_opts)
size_t used() const
Returns the amount of used bytes; size() - available()
void initNewFile()
Adds all pages to freePages and zeroes first four bytes of header.
size_t size() const
Returns the number of bytes used by the file.
#define CHUNK_KEY_TABLE_IDX
std::mutex freePagesMutex_
size_t read(FILE *f, const size_t offset, const size_t size, int8_t *buf, const std::string &file_path)
Reads the specified number of bytes from the offset position in file f into buf.
constexpr int32_t ROLLOFF_CONTINGENT
size_t read(const size_t offset, const size_t size, int8_t *buf)
bool is_page_deleted_with_checkpoint(int32_t table_epoch, int32_t page_epoch, int32_t contingent)
torch::Tensor f(torch::Tensor x, torch::Tensor W_target, torch::Tensor b_target)
virtual void free_page(std::pair< FileInfo *, int32_t > &&page)
FILE * f
unique file identifier (i.e., used for a file name)
This file contains the declaration and definition of a Page type and a MultiPage type.
void openExistingFile(std::vector< HeaderInfo > &headerVec)
void recoverPage(const ChunkKey &chunk_key, int32_t page_num)
void close(FILE *f)
Closes the file pointed to by the FILE pointer.
void freePageDeferred(int32_t pageId)
size_t available() const
Returns the number of free bytes available.
size_t writeFile(FILE *f, const size_t offset, const size_t size, const int8_t *buf) const
size_t numPages
the fixed size of each page in the file
bool isDirty
the number of pages in the file