log_writer.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. //
  6. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  7. // Use of this source code is governed by a BSD-style license that can be
  8. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  9. #pragma once
  10. #include <stdint.h>
  11. #include <memory>
  12. #include "db/log_format.h"
  13. #include "rocksdb/slice.h"
  14. #include "rocksdb/status.h"
  15. namespace ROCKSDB_NAMESPACE {
  16. class WritableFileWriter;
  17. namespace log {
  18. /**
  19. * Writer is a general purpose log stream writer. It provides an append-only
  20. * abstraction for writing data. The details of the how the data is written is
  21. * handled by the WriteableFile sub-class implementation.
  22. *
  23. * File format:
  24. *
  25. * File is broken down into variable sized records. The format of each record
  26. * is described below.
  27. * +-----+-------------+--+----+----------+------+-- ... ----+
  28. * File | r0 | r1 |P | r2 | r3 | r4 | |
  29. * +-----+-------------+--+----+----------+------+-- ... ----+
  30. * <--- kBlockSize ------>|<-- kBlockSize ------>|
  31. * rn = variable size records
  32. * P = Padding
  33. *
  34. * Data is written out in kBlockSize chunks. If next record does not fit
  35. * into the space left, the leftover space will be padded with \0.
  36. *
  37. * Legacy record format:
  38. *
  39. * +---------+-----------+-----------+--- ... ---+
  40. * |CRC (4B) | Size (2B) | Type (1B) | Payload |
  41. * +---------+-----------+-----------+--- ... ---+
  42. *
  43. * CRC = 32bit hash computed over the record type and payload using CRC
  44. * Size = Length of the payload data
  45. * Type = Type of record
  46. * (kZeroType, kFullType, kFirstType, kLastType, kMiddleType )
  47. * The type is used to group a bunch of records together to represent
  48. * blocks that are larger than kBlockSize
  49. * Payload = Byte stream as long as specified by the payload size
  50. *
  51. * Recyclable record format:
  52. *
  53. * +---------+-----------+-----------+----------------+--- ... ---+
  54. * |CRC (4B) | Size (2B) | Type (1B) | Log number (4B)| Payload |
  55. * +---------+-----------+-----------+----------------+--- ... ---+
  56. *
  57. * Same as above, with the addition of
  58. * Log number = 32bit log file number, so that we can distinguish between
  59. * records written by the most recent log writer vs a previous one.
  60. */
  61. class Writer {
  62. public:
  63. // Create a writer that will append data to "*dest".
  64. // "*dest" must be initially empty.
  65. // "*dest" must remain live while this Writer is in use.
  66. explicit Writer(std::unique_ptr<WritableFileWriter>&& dest,
  67. uint64_t log_number, bool recycle_log_files,
  68. bool manual_flush = false);
  69. // No copying allowed
  70. Writer(const Writer&) = delete;
  71. void operator=(const Writer&) = delete;
  72. ~Writer();
  73. Status AddRecord(const Slice& slice);
  74. WritableFileWriter* file() { return dest_.get(); }
  75. const WritableFileWriter* file() const { return dest_.get(); }
  76. uint64_t get_log_number() const { return log_number_; }
  77. Status WriteBuffer();
  78. Status Close();
  79. bool TEST_BufferIsEmpty();
  80. private:
  81. std::unique_ptr<WritableFileWriter> dest_;
  82. size_t block_offset_; // Current offset in block
  83. uint64_t log_number_;
  84. bool recycle_log_files_;
  85. // crc32c values for all supported record types. These are
  86. // pre-computed to reduce the overhead of computing the crc of the
  87. // record type stored in the header.
  88. uint32_t type_crc_[kMaxRecordType + 1];
  89. Status EmitPhysicalRecord(RecordType type, const char* ptr, size_t length);
  90. // If true, it does not flush after each write. Instead it relies on the upper
  91. // layer to manually does the flush by calling ::WriteBuffer()
  92. bool manual_flush_;
  93. };
  94. } // namespace log
  95. } // namespace ROCKSDB_NAMESPACE