Add IsAppendOnly flag to file and if true, disable parallel writes

PiperOrigin-RevId: 788805810
This commit is contained in:
Jan Wassenberg 2025-07-30 01:51:08 -07:00 committed by Copybara-Service
parent d22ba2ac96
commit 2141d4788d
4 changed files with 22 additions and 10 deletions

View File

@ -411,15 +411,17 @@ void BlobWriter::WriteAll(hwy::ThreadPool& pool, const Path& filename) {
std::unique_ptr<File> file = OpenFileOrNull(filename, "w+"); std::unique_ptr<File> file = OpenFileOrNull(filename, "w+");
if (!file) HWY_ABORT("Failed to open for writing %s", filename.path.c_str()); if (!file) HWY_ABORT("Failed to open for writing %s", filename.path.c_str());
pool.Run(0, writes.size(), hwy::ThreadPool null_pool(0);
[this, &file, &writes](uint64_t i, size_t /*thread*/) { hwy::ThreadPool& pool_or_serial = file->IsAppendOnly() ? null_pool : pool;
pool_or_serial.Run(
0, writes.size(), [this, &file, &writes](uint64_t i, size_t /*thread*/) {
const BlobRange& range = writes[i].range; const BlobRange& range = writes[i].range;
if (!file->Write(writes[i].data, range.bytes, range.offset)) { if (!file->Write(writes[i].data, range.bytes, range.offset)) {
const std::string& key = StringFromKey(keys_[range.key_idx]); const std::string& key = StringFromKey(keys_[range.key_idx]);
HWY_ABORT("Write failed for %s from %zu, %zu bytes to %p.", HWY_ABORT("Write failed for %s from %zu, %zu bytes to %p.",
key.c_str(), static_cast<size_t>(range.offset), key.c_str(), static_cast<size_t>(range.offset), range.bytes,
range.bytes, writes[i].data); writes[i].data);
} }
}); });
} }

View File

@ -88,6 +88,9 @@ class FilePosix : public File {
} }
} }
// pwrite is thread-safe and allows arbitrary offsets.
bool IsAppendOnly() const override { return false; }
uint64_t FileSize() const override { uint64_t FileSize() const override {
static_assert(sizeof(off_t) == 8, "64-bit off_t required"); static_assert(sizeof(off_t) == 8, "64-bit off_t required");
const off_t size = lseek(fd_, 0, SEEK_END); const off_t size = lseek(fd_, 0, SEEK_END);

View File

@ -46,6 +46,10 @@ class File {
File(const File& other) = delete; File(const File& other) = delete;
const File& operator=(const File& other) = delete; const File& operator=(const File& other) = delete;
// If true, Write() should only be called with `offset` equal to the number
// of bytes already written to the file, which rules out parallel writes.
virtual bool IsAppendOnly() const = 0;
// Returns size in bytes or 0. // Returns size in bytes or 0.
virtual uint64_t FileSize() const = 0; virtual uint64_t FileSize() const = 0;

View File

@ -47,6 +47,9 @@ class FileWin : public File {
} }
} }
// WriteFile is thread-safe and allows arbitrary offsets.
bool IsAppendOnly() const override { return false; }
uint64_t FileSize() const override { uint64_t FileSize() const override {
DWORD hi; DWORD hi;
const DWORD lo = GetFileSize(hFile_, &hi); const DWORD lo = GetFileSize(hFile_, &hi);