19 #include "../../Shared/File.h" 31 const size_t pageSize,
34 : fileMgr(fileMgr), fileId(fileId), f(f), pageSize(pageSize), numPages(numPages) {
51 int32_t headerSize = 0;
52 int8_t* headerSizePtr = (int8_t*)(&headerSize);
53 for (
size_t pageId = 0; pageId <
numPages; ++pageId) {
72 const int32_t fileMgrEpoch) {
78 int32_t oldPageId = -99;
79 int32_t oldVersionEpoch = -99;
81 for (
size_t pageNum = 0; pageNum <
numPages; ++pageNum) {
84 constexpr
size_t MAX_INTS_TO_READ{10};
85 int32_t ints[MAX_INTS_TO_READ];
87 CHECK_EQ(fread(ints,
sizeof(int32_t), MAX_INTS_TO_READ,
f), MAX_INTS_TO_READ);
90 const bool should_delete_deleted =
92 const bool should_delete_rolled_off =
94 if (should_delete_deleted || should_delete_rolled_off) {
100 if (headerSize != 0) {
103 size_t numHeaderElems = headerSize /
sizeof(int32_t);
104 CHECK_GE(numHeaderElems,
size_t(2));
109 ChunkKey chunkKey(&ints[1], &ints[1 + numHeaderElems - 2]);
115 pageNum * pageSize +
sizeof(int32_t),
117 (int8_t*)&chunkKey[0]);
122 int32_t pageId = ints[1 + numHeaderElems - 2];
123 int32_t versionEpoch = ints[1 + numHeaderElems - 1];
124 if (chunkKey != oldChunkKey || oldPageId != pageId - (1 + skipped)) {
126 VLOG(4) <<
"FId.PSz: " <<
fileId <<
"." << pageSize
128 <<
" Page id from : " << oldPageId <<
" to : " << oldPageId + skipped
129 <<
" Epoch: " << oldVersionEpoch;
130 }
else if (oldPageId != -99) {
131 VLOG(4) <<
"FId.PSz: " <<
fileId <<
"." << pageSize
133 <<
" Page id: " << oldPageId <<
" Epoch: " << oldVersionEpoch;
136 oldVersionEpoch = versionEpoch;
137 oldChunkKey = chunkKey;
149 if (versionEpoch > fileMgrEpoch) {
154 f, pageNum * pageSize,
sizeof(int32_t), (int8_t*)&headerSize);
158 <<
" Page id: " << pageId <<
" Epoch: " << versionEpoch
159 <<
" FileMgrEpoch " << fileMgrEpoch << endl;
163 headerVec.emplace_back(chunkKey, pageId, versionEpoch, page);
170 if (oldPageId != -99) {
174 <<
" Page id from : " << oldPageId <<
" to : " << oldPageId + skipped
175 <<
" Epoch: " << oldVersionEpoch;
178 <<
" Chunk key: " <<
show_chunk(oldChunkKey) <<
" Page id: " << oldPageId
179 <<
" Epoch: " << oldVersionEpoch;
189 #ifdef ENABLE_CRASH_CORRUPTION_TEST 190 #warning "!!!!! DB corruption crash test is enabled !!!!!" 192 static bool goto_crash;
193 static void sighandler(
int sig) {
194 if (getenv(
"ENABLE_CRASH_CORRUPTION_TEST"))
201 #define RESILIENT_PAGE_HEADER 202 #ifdef RESILIENT_PAGE_HEADER 208 pageId *
pageSize +
sizeof(int32_t),
209 sizeof(epoch_freed_page),
210 (int8_t*)epoch_freed_page);
214 int8_t* zeroAddr =
reinterpret_cast<int8_t*
>(&zeroVal);
218 #endif // RESILIENT_PAGE_HEADER 221 #ifdef ENABLE_CRASH_CORRUPTION_TEST 222 signal(SIGUSR2, sighandler);
224 CHECK(pageId % 8 != 4);
235 int32_t pageNum = *pageIt;
241 std::cout <<
"File: " <<
fileId << std::endl;
242 std::cout <<
"Size: " <<
size() << std::endl;
243 std::cout <<
"Used: " <<
used() << std::endl;
244 std::cout <<
"Free: " <<
available() << std::endl;
252 if (fflush(
f) != 0) {
253 LOG(
FATAL) <<
"Error trying to flush changes to disk, the error was: " 254 << std::strerror(errno);
257 const int32_t sync_result = fcntl(fileno(
f), 51);
261 if (sync_result == 0) {
A logical page (Page) belongs to a file on disk.
std::mutex readWriteMutex_
const std::pair< const int32_t, const int32_t > get_fileMgrKey() const
size_t size() const
Returns the number of bytes used by the file.
size_t write(const size_t offset, const size_t size, int8_t *buf)
std::set< size_t > freePages
size_t pageSize
file stream object for the represented file
size_t read(FILE *f, const size_t offset, const size_t size, int8_t *buf)
Reads the specified number of bytes from the offset position in file f into buf.
constexpr int32_t DELETE_CONTINGENT
A FileInfo type has a file pointer and metadata about a file.
void init(LogOptions const &log_opts)
void initNewFile()
Adds all pages to freePages and zeroes first four bytes of header.
std::mutex freePagesMutex_
set of page numbers of free pages
void freePage(int32_t pageId, const bool isRolloff)
constexpr int32_t ROLLOFF_CONTINGENT
void openExistingFile(std::vector< HeaderInfo > &headerVec, const int32_t fileMgrEpoch)
std::string show_chunk(const ChunkKey &key)
size_t read(const size_t offset, const size_t size, int8_t *buf)
int32_t epoch()
Returns current value of epoch - should be one greater than recorded at last checkpoint.
void free_page(std::pair< FileInfo *, int32_t > &&page)
FILE * f
unique file identifier (i.e., used for a file name)
size_t write(FILE *f, const size_t offset, const size_t size, int8_t *buf)
Writes the specified number of bytes to the offset position in file f from buf.
std::vector< int > ChunkKey
void close(FILE *f)
Closes the file pointed to by the FILE pointer.
void freePageDeferred(int32_t pageId)
size_t used()
Returns the amount of used bytes; size() - available()
void print(bool pagesummary)
Prints a summary of the file to stdout.
size_t numPages
the fixed size of each page in the file
bool isDirty
the number of pages in the file
size_t available()
Returns the number of free bytes available.