1#include "duckdb/common/serializer/buffered_file_writer.hpp"
2#include "duckdb/common/exception.hpp"
3
4#include <cstring>
5
6using namespace duckdb;
7using namespace std;
8
9BufferedFileWriter::BufferedFileWriter(FileSystem &fs, const char *path, bool append)
10 : fs(fs), data(unique_ptr<data_t[]>(new data_t[FILE_BUFFER_SIZE])), offset(0) {
11 uint8_t flags = FileFlags::WRITE | FileFlags::CREATE;
12 if (append) {
13 flags |= FileFlags::APPEND;
14 }
15 handle = fs.OpenFile(path, flags, FileLockType::WRITE_LOCK);
16}
17
18int64_t BufferedFileWriter::GetFileSize() {
19 return fs.GetFileSize(*handle);
20}
21
22void BufferedFileWriter::WriteData(const_data_ptr_t buffer, uint64_t write_size) {
23 // first copy anything we can from the buffer
24 const_data_ptr_t end_ptr = buffer + write_size;
25 while (buffer < end_ptr) {
26 idx_t to_write = std::min((idx_t)(end_ptr - buffer), FILE_BUFFER_SIZE - offset);
27 assert(to_write > 0);
28 memcpy(data.get() + offset, buffer, to_write);
29 offset += to_write;
30 buffer += to_write;
31 if (offset == FILE_BUFFER_SIZE) {
32 Flush();
33 }
34 }
35}
36
37void BufferedFileWriter::Flush() {
38 if (offset == 0) {
39 return;
40 }
41 fs.Write(*handle, data.get(), offset);
42 offset = 0;
43}
44
45void BufferedFileWriter::Sync() {
46 Flush();
47 handle->Sync();
48}
49
50void BufferedFileWriter::Truncate(int64_t size) {
51 // truncate the physical file on disk
52 handle->Truncate(size);
53 // reset anything written in the buffer
54 offset = 0;
55}
56