| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SRC_LIB_STORAGE_VFS_CPP_JOURNAL_DATA_STREAMER_H_ |
| #define SRC_LIB_STORAGE_VFS_CPP_JOURNAL_DATA_STREAMER_H_ |
| |
| #include <lib/fit/promise.h> |
| |
| #include <utility> |
| |
| #include <storage/operation/unbuffered_operation.h> |
| #include <storage/operation/unbuffered_operations_builder.h> |
| |
| #include "src/lib/storage/vfs/cpp/journal/journal.h" |
| |
| namespace fs { |
| |
| // A class which helps callers write streaming data operations to the underlying device. |
| // |
| // This class provides the following value over calling "Journal::WriteData" directly: |
| // |
| // Client-side coalescing. |
| // |
| // This class groups together contiguous operations, only transmitting them to the writeback |
| // subsystem once necessary. |
| // |
| // Avoids blocking for large operations. |
| // |
| // For operations which are larger than the underlying writeback buffer, caution must be taken to |
| // avoid blocking on "Journal::WriteData", which creates a reservation, but does not begin |
| // execution of the underlying data. To mitigate, this class begins execution of these data writes |
| // if they are larger than an internal threshold (which is smaller than the entire writeback |
| // buffer). |
| // |
| // Allows ordering control over "all data", but not between intermediate data writes. |
| // |
| // Typically, when data operations are issued, the caller cares that they all occur before a |
| // following action, but the order between those data operations themselves does not matter. This |
| // class enables callers to |Flush()| all prior data requests, without imposing an ordering on the |
| // data requests issued by |StreamData()|. |
| // |
| // This class is thread-compatible. |
| class DataStreamer { |
| public: |
| DataStreamer(fs::Journal* journal, size_t writeback_capacity) |
| : journal_(journal), writeback_capacity_(writeback_capacity) {} |
| |
| // Issues |operation| to the underlying writeback subsystem (eventually). |
| // |
| // May cache the operation locally, issuing it to the underlying writeback buffer and executor as |
| // necessary. To identify completion, refer to |Flush()|. |
| // |
| // Multiple invocations of |StreamData()| are not ordered with respect to each other. |
| // Promises generated by |StreamData()| are ordered before invocations of |Flush()|. |
| void StreamData(storage::UnbufferedOperation operation); |
| |
| // Ensures all operations sent to |StreamData| are issued to the executor, and returns a promise |
| // representing when all those writes have completed. |
| fs::Journal::Promise Flush(); |
| |
| // Issues locally buffered operations to the executor, and track the resulting promise in |
| // |promises_|. The completion of all issued operations can be achieved by invoking |Flush()|. |
| void IssueOperations(); |
| |
| private: |
| fs::Journal* journal_; |
| const size_t writeback_capacity_; |
| |
| // Operations which have been sent to |StreamData|, but which have not been sent to the executor. |
| storage::UnbufferedOperationsBuilder operations_; |
| |
| // Operations which have been sent to the executor. |
| std::vector<fit::promise<void, zx_status_t>> promises_; |
| }; |
| |
| } // namespace fs |
| |
| #endif // SRC_LIB_STORAGE_VFS_CPP_JOURNAL_DATA_STREAMER_H_ |