Implement buffered file writer with concurrency support
You are provided with an existing FileWriter class that directly writes data to disk:
class FileWriter {
public:
// Append `data` to the file on disk immediately (no buffering).
// May be relatively slow because it calls the OS for each write.
void write(const std::string& data);
// Flush any OS-level buffers to disk.
void flush();
};
This class is already implemented for you.
Task 1: Implement a BufferedFileWriter
Implement a BufferedFileWriter class that uses an internal memory buffer to reduce the number of calls to the underlying FileWriter.
Requirements:
-
BufferedFileWritershould have the following public interface (composition is preferred over inheritance):class BufferedFileWriter { public: BufferedFileWriter(FileWriter& underlying, size_t buffer_capacity); // Append `data` to an in-memory buffer. // Only when certain conditions are met (e.g., the buffer is full), // data should be flushed to the underlying FileWriter. void write(const std::string& data); // Force all currently buffered data to be written to the // underlying FileWriter and then flush it to disk. void flush(); }; -
The constructor receives a reference to an existing
FileWriterinstance and abuffer_capacityin bytes. -
writeshould:- Append
datato an internal memory buffer. - If after appending, the buffer size is greater than or equal to
buffer_capacity, it should write the buffered data to the underlyingFileWriterand clear the internal buffer.
- Append
-
flushshould:- Write any remaining data in the internal buffer to the underlying
FileWriter(if the buffer is not empty). - Then call
flush()on the underlyingFileWriter.
- Write any remaining data in the internal buffer to the underlying
-
You may assume:
- All input strings are reasonably small compared to
buffer_capacity. - Memory allocation does not fail.
- All input strings are reasonably small compared to
-
Write a few unit tests (or describe them) to validate the behavior, including:
- Writing data smaller than
buffer_capacityand then callingflush(). - Writing multiple chunks that together exceed
buffer_capacityand ensuring data is flushed at the right times. - Ensuring that multiple
flush()calls with an empty buffer are safe.
- Writing data smaller than
You do not need to implement the real file I/O of FileWriter; only show the code for BufferedFileWriter using the given interface.
Follow-up: Make BufferedFileWriter Thread-Safe
Now assume that BufferedFileWriter may be used from multiple threads concurrently. Different threads may call write() and flush() at the same time.
- Extend your design so that
BufferedFileWriteris thread-safe. - Define what thread-safety guarantees you provide. For example, it should appear as if calls to
write()andflush()from all threads are executed in some serial order, and data is not corrupted or lost. - Provide pseudocode (language of your choice) that shows:
- How you protect shared state (the internal buffer and any other shared fields).
- How
write()andflush()coordinate with each other. - How you avoid data races and inconsistent writes.
Assume you may use standard synchronization primitives such as mutexes/locks and condition variables if needed.
AI interview prep
Core dilemma
Balancing the performance benefits of buffering (reducing expensive I/O calls) with the need for data consistency, freshness, and correctness, especially under concurrent access.
3 tradeoffs and 3 stress tests locked
Interview prep
Unlock the interviewer X-Ray rubric, tradeoff matrix, stress tests, clarifying questions, and key concepts.
Implement buffered file writer with concurrency support
You are provided with an existing FileWriter class that directly writes data to disk:
class FileWriter {
public:
// Append `data` to the file on disk immediately (no buffering).
// May be relatively slow because it calls the OS for each write.
void write(const std::string& data);
// Flush any OS-level buffers to disk.
void flush();
};
This class is already implemented for you.
Task 1: Implement a BufferedFileWriter
Implement a BufferedFileWriter class that uses an internal memory buffer to reduce the number of calls to the underlying FileWriter.
Requirements:
-
BufferedFileWritershould have the following public interface (composition is preferred over inheritance):class BufferedFileWriter { public: BufferedFileWriter(FileWriter& underlying, size_t buffer_capacity); // Append `data` to an in-memory buffer. // Only when certain conditions are met (e.g., the buffer is full), // data should be flushed to the underlying FileWriter. void write(const std::string& data); // Force all currently buffered data to be written to the // underlying FileWriter and then flush it to disk. void flush(); }; -
The constructor receives a reference to an existing
FileWriterinstance and abuffer_capacityin bytes. -
writeshould:- Append
datato an internal memory buffer. - If after appending, the buffer size is greater than or equal to
buffer_capacity, it should write the buffered data to the underlyingFileWriterand clear the internal buffer.
- Append
-
flushshould:- Write any remaining data in the internal buffer to the underlying
FileWriter(if the buffer is not empty). - Then call
flush()on the underlyingFileWriter.
- Write any remaining data in the internal buffer to the underlying
-
You may assume:
- All input strings are reasonably small compared to
buffer_capacity. - Memory allocation does not fail.
- All input strings are reasonably small compared to
-
Write a few unit tests (or describe them) to validate the behavior, including:
- Writing data smaller than
buffer_capacityand then callingflush(). - Writing multiple chunks that together exceed
buffer_capacityand ensuring data is flushed at the right times. - Ensuring that multiple
flush()calls with an empty buffer are safe.
- Writing data smaller than
You do not need to implement the real file I/O of FileWriter; only show the code for BufferedFileWriter using the given interface.
Follow-up: Make BufferedFileWriter Thread-Safe
Now assume that BufferedFileWriter may be used from multiple threads concurrently. Different threads may call write() and flush() at the same time.
- Extend your design so that
BufferedFileWriteris thread-safe. - Define what thread-safety guarantees you provide. For example, it should appear as if calls to
write()andflush()from all threads are executed in some serial order, and data is not corrupted or lost. - Provide pseudocode (language of your choice) that shows:
- How you protect shared state (the internal buffer and any other shared fields).
- How
write()andflush()coordinate with each other. - How you avoid data races and inconsistent writes.
Assume you may use standard synchronization primitives such as mutexes/locks and condition variables if needed.