Skip to content

Commit

Permalink
ignore partially written record at the end
Browse files Browse the repository at this point in the history
  • Loading branch information
artpaul committed Sep 19, 2024
1 parent 136dcff commit f7704ae
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 4 deletions.
10 changes: 9 additions & 1 deletion include/bitcask/bitcask.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ class Database {
std::mutex fd_mutex;
/// File descriptor.
int fd{-1};
/// The file may have partially written record at the end.
const bool may_have_uncommitted;

/// Total size of the file.
/// The size is only updated on writing or set on loading.
Expand All @@ -131,7 +133,8 @@ class Database {
std::atomic_uint64_t tombstones{0};

public:
FileInfo(std::filesystem::path p, uint64_t s) noexcept : path(std::move(p)), size(s) {}
FileInfo(std::filesystem::path p, uint64_t s, bool uncommitted) noexcept
: path(std::move(p)), may_have_uncommitted(uncommitted), size(s) {}

#ifndef NDEBUG
~FileInfo() {
Expand Down Expand Up @@ -251,6 +254,11 @@ class Database {
std::error_code EnumerateIndex(const std::shared_ptr<FileInfo>& file, const FileSections::Range& range,
const std::function<std::error_code(const Record&, const bool, std::string_view)>& cb) const;

/**
* Enumerates all entries in a file.
*
* @param file a file to enumerate.
*/
std::error_code EnumerateEntries(const std::shared_ptr<FileInfo>& file, const FileSections::Range& range,
const std::function<std::error_code(const Record&, const bool, std::string_view, std::string_view)>&
cb) const;
Expand Down
26 changes: 23 additions & 3 deletions src/bitcask.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,15 @@ std::error_code LoadFromFile(int fd, void* buf, size_t len, size_t& off) noexcep
return {};
}

/// Reads full content of an entry.
/**
* Reads full content of an entry.
*
* @param fd
* @param offset beginning of the entry.
* @param check_crc check consistency of read data.
*
* @returns bytes read or an error code.
*/
std::pair<size_t, std::error_code> ReadEntryImpl(const int fd, const size_t offset, const bool check_crc,
format::Entry& entry, std::string& key, std::string& value) {
size_t current_offset = offset;
Expand Down Expand Up @@ -633,7 +641,7 @@ std::error_code Database::Initialize() {
continue;
}

auto file = std::make_shared<FileInfo>(entry.path(), entry.file_size());
auto file = std::make_shared<FileInfo>(entry.path(), entry.file_size(), index.value() == 0);
// Open file for reading.
if (auto ec = file->EnsureReadable()) {
return ec;
Expand All @@ -644,6 +652,12 @@ std::error_code Database::Initialize() {
if (IsNotFound(ec)) {
continue;
}
// A former active file may have a partially written record at the end in case of unexpected shutdown.
// Ignore it.
if (IsUnexpectedEndOfFile(ec) && file->may_have_uncommitted) {
continue;
}

return ec;
}

Expand Down Expand Up @@ -761,6 +775,12 @@ std::error_code Database::PackFiles(
}
// Enumerate all records in the source file.
if (auto ec = EnumerateEntriesNoLock(file, cb)) {
// A former active file may have a partially written record at the end in case of unexpected shutdown.
// Ignore it.
if (IsUnexpectedEndOfFile(ec) && file->may_have_uncommitted) {
continue;
}

read_lock.unlock();
// TODO: finalize.
return ec;
Expand Down Expand Up @@ -978,7 +998,7 @@ Database::FileInfoStatus Database::MakeWritableFile(const std::string& name, boo
return {{}, std::make_error_code(static_cast<std::errc>(err))};
}
}
auto file = std::make_shared<FileInfo>(std::move(path), sizeof(format::Header));
auto file = std::make_shared<FileInfo>(std::move(path), sizeof(format::Header), name.starts_with("0-"));
file->fd = fd;
return {file, {}};
}
Expand Down

0 comments on commit f7704ae

Please sign in to comment.