log_writer.h 5.2 KB
Newer Older
1
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
S
Siying Dong 已提交
2 3 4
//  This source code is licensed under both the GPLv2 (found in the
//  COPYING file in the root directory) and Apache 2.0 License
//  (found in the LICENSE.Apache file in the root directory).
5
//
J
jorlow@chromium.org 已提交
6 7 8
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
9
#pragma once
10

11
#include <cstdint>
12
#include <memory>
13 14
#include <unordered_map>
#include <vector>
15

J
jorlow@chromium.org 已提交
16
#include "db/log_format.h"
17
#include "rocksdb/compression_type.h"
18
#include "rocksdb/env.h"
19
#include "rocksdb/io_status.h"
20 21
#include "rocksdb/slice.h"
#include "rocksdb/status.h"
22
#include "util/compression.h"
23
#include "util/hash_containers.h"
J
jorlow@chromium.org 已提交
24

25
namespace ROCKSDB_NAMESPACE {
J
jorlow@chromium.org 已提交
26

27
class WritableFileWriter;
J
jorlow@chromium.org 已提交
28 29 30

namespace log {

K
krad 已提交
31 32 33
/**
 * Writer is a general purpose log stream writer. It provides an append-only
 * abstraction for writing data. The details of the how the data is written is
B
Bo Wang 已提交
34
 * handled by the WritableFile sub-class implementation.
K
krad 已提交
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
 *
 * File format:
 *
 * File is broken down into variable sized records. The format of each record
 * is described below.
 *       +-----+-------------+--+----+----------+------+-- ... ----+
 * File  | r0  |        r1   |P | r2 |    r3    |  r4  |           |
 *       +-----+-------------+--+----+----------+------+-- ... ----+
 *       <--- kBlockSize ------>|<-- kBlockSize ------>|
 *  rn = variable size records
 *  P = Padding
 *
 * Data is written out in kBlockSize chunks. If next record does not fit
 * into the space left, the leftover space will be padded with \0.
 *
50
 * Legacy record format:
K
krad 已提交
51 52 53 54 55
 *
 * +---------+-----------+-----------+--- ... ---+
 * |CRC (4B) | Size (2B) | Type (1B) | Payload   |
 * +---------+-----------+-----------+--- ... ---+
 *
56
 * CRC = 32bit hash computed over the record type and payload using CRC
K
krad 已提交
57 58 59 60 61 62 63
 * Size = Length of the payload data
 * Type = Type of record
 *        (kZeroType, kFullType, kFirstType, kLastType, kMiddleType )
 *        The type is used to group a bunch of records together to represent
 *        blocks that are larger than kBlockSize
 * Payload = Byte stream as long as specified by the payload size
 *
64 65 66 67 68 69 70 71 72
 * Recyclable record format:
 *
 * +---------+-----------+-----------+----------------+--- ... ---+
 * |CRC (4B) | Size (2B) | Type (1B) | Log number (4B)| Payload   |
 * +---------+-----------+-----------+----------------+--- ... ---+
 *
 * Same as above, with the addition of
 * Log number = 32bit log file number, so that we can distinguish between
 * records written by the most recent log writer vs a previous one.
K
krad 已提交
73
 */
J
jorlow@chromium.org 已提交
74 75 76 77 78
class Writer {
 public:
  // Create a writer that will append data to "*dest".
  // "*dest" must be initially empty.
  // "*dest" must remain live while this Writer is in use.
79 80
  explicit Writer(std::unique_ptr<WritableFileWriter>&& dest,
                  uint64_t log_number, bool recycle_log_files,
81 82
                  bool manual_flush = false,
                  CompressionType compressionType = kNoCompression);
83 84 85 86
  // No copying allowed
  Writer(const Writer&) = delete;
  void operator=(const Writer&) = delete;

J
jorlow@chromium.org 已提交
87 88
  ~Writer();

89 90
  IOStatus AddRecord(const Slice& slice,
                     Env::IOPriority rate_limiter_priority = Env::IO_TOTAL);
91
  IOStatus AddCompressionTypeRecord();
J
jorlow@chromium.org 已提交
92

93 94 95 96 97 98
  // If there are column families in `cf_to_ts_sz` not included in
  // `recorded_cf_to_ts_sz_` and its user-defined timestamp size is non-zero,
  // adds a record of type kUserDefinedTimestampSizeType or
  // kRecyclableUserDefinedTimestampSizeType for these column families.
  // This timestamp size record applies to all subsequent records.
  IOStatus MaybeAddUserDefinedTimestampSizeRecord(
99
      const UnorderedMap<uint32_t, size_t>& cf_to_ts_sz,
100 101
      Env::IOPriority rate_limiter_priority = Env::IO_TOTAL);

102 103
  WritableFileWriter* file() { return dest_.get(); }
  const WritableFileWriter* file() const { return dest_.get(); }
104

105 106
  uint64_t get_log_number() const { return log_number_; }

107
  IOStatus WriteBuffer();
108

109
  IOStatus Close();
110

111
  bool BufferIsEmpty();
112

J
jorlow@chromium.org 已提交
113
 private:
114
  std::unique_ptr<WritableFileWriter> dest_;
115
  size_t block_offset_;  // Current offset in block
116 117
  uint64_t log_number_;
  bool recycle_log_files_;
J
jorlow@chromium.org 已提交
118 119 120 121 122 123

  // crc32c values for all supported record types.  These are
  // pre-computed to reduce the overhead of computing the crc of the
  // record type stored in the header.
  uint32_t type_crc_[kMaxRecordType + 1];

124 125 126
  IOStatus EmitPhysicalRecord(
      RecordType type, const char* ptr, size_t length,
      Env::IOPriority rate_limiter_priority = Env::IO_TOTAL);
J
jorlow@chromium.org 已提交
127

128 129 130
  // If true, it does not flush after each write. Instead it relies on the upper
  // layer to manually does the flush by calling ::WriteBuffer()
  bool manual_flush_;
131 132 133

  // Compression Type
  CompressionType compression_type_;
134 135 136
  StreamingCompress* compress_;
  // Reusable compressed output buffer
  std::unique_ptr<char[]> compressed_buffer_;
137 138 139 140

  // The recorded user-defined timestamp size that have been written so far.
  // Since the user-defined timestamp size cannot be changed while the DB is
  // running, existing entry in this map cannot be updated.
141
  UnorderedMap<uint32_t, size_t> recorded_cf_to_ts_sz_;
J
jorlow@chromium.org 已提交
142 143
};

H
Hans Wennborg 已提交
144
}  // namespace log
145
}  // namespace ROCKSDB_NAMESPACE