| 49 | }; |
| 50 | |
| 51 | class RecordWriter { |
| 52 | public: |
| 53 | // Format of a single record: |
| 54 | // uint64 length |
| 55 | // uint32 masked crc of length |
| 56 | // byte data[length] |
| 57 | // uint32 masked crc of data |
| 58 | static const size_t kHeaderSize = sizeof(uint64) + sizeof(uint32); |
| 59 | static const size_t kFooterSize = sizeof(uint32); |
| 60 | |
| 61 | // Create a writer that will append data to "*dest". |
| 62 | // "*dest" must be initially empty. |
| 63 | // "*dest" must remain live while this Writer is in use. |
| 64 | RecordWriter(WritableFile* dest, |
| 65 | const RecordWriterOptions& options = RecordWriterOptions()); |
| 66 | |
| 67 | // Calls Close() and logs if an error occurs. |
| 68 | // |
| 69 | // TODO(jhseu): Require that callers explicitly call Close() and remove the |
| 70 | // implicit Close() call in the destructor. |
| 71 | ~RecordWriter(); |
| 72 | |
| 73 | Status WriteRecord(StringPiece slice); |
| 74 | |
| 75 | #if defined(PLATFORM_GOOGLE) |
| 76 | Status WriteRecord(const absl::Cord& data); |
| 77 | #endif |
| 78 | |
| 79 | // Flushes any buffered data held by underlying containers of the |
| 80 | // RecordWriter to the WritableFile. Does *not* flush the |
| 81 | // WritableFile. |
| 82 | Status Flush(); |
| 83 | |
| 84 | // Writes all output to the file. Does *not* close the WritableFile. |
| 85 | // |
| 86 | // After calling Close(), any further calls to `WriteRecord()` or `Flush()` |
| 87 | // are invalid. |
| 88 | Status Close(); |
| 89 | |
| 90 | // Utility method to populate TFRecord headers. Populates record-header in |
| 91 | // "header[0,kHeaderSize-1]". The record-header is based on data[0, n-1]. |
| 92 | inline static void PopulateHeader(char* header, const char* data, size_t n); |
| 93 | |
| 94 | // Utility method to populate TFRecord footers. Populates record-footer in |
| 95 | // "footer[0,kFooterSize-1]". The record-footer is based on data[0, n-1]. |
| 96 | inline static void PopulateFooter(char* footer, const char* data, size_t n); |
| 97 | |
| 98 | #if defined(PLATFORM_GOOGLE) |
| 99 | inline static void PopulateHeader(char* header, const absl::Cord& data); |
| 100 | inline static void PopulateFooter(char* footer, const absl::Cord& data); |
| 101 | #endif |
| 102 | |
| 103 | private: |
| 104 | WritableFile* dest_; |
| 105 | RecordWriterOptions options_; |
| 106 | |
| 107 | inline static uint32 MaskedCrc(const char* data, size_t n) { |
| 108 | return crc32c::Mask(crc32c::Value(data, n)); |