5830c699f2
When we recycle log files, we need to mix the log number into the CRC for each record. Note that for logs that don't get recycled (like the manifest), we always pass a log_number of 0 and false. Signed-off-by: Sage Weil <sage@redhat.com>
95 lines
3.1 KiB
C++
95 lines
3.1 KiB
C++
// Copyright (c) 2013, Facebook, Inc. All rights reserved.
|
|
// This source code is licensed under the BSD-style license found in the
|
|
// LICENSE file in the root directory of this source tree. An additional grant
|
|
// of patent rights can be found in the PATENTS file in the same directory.
|
|
//
|
|
// 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.
|
|
#pragma once
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <memory>
|
|
|
|
#include "db/log_format.h"
|
|
#include "rocksdb/slice.h"
|
|
#include "rocksdb/status.h"
|
|
|
|
namespace rocksdb {
|
|
|
|
class WritableFileWriter;
|
|
|
|
using std::unique_ptr;
|
|
|
|
namespace log {
|
|
|
|
/**
|
|
* 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
|
|
* handled by the WriteableFile sub-class implementation.
|
|
*
|
|
* 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.
|
|
*
|
|
* Record format:
|
|
*
|
|
* +---------+-----------+-----------+--- ... ---+
|
|
* |CRC (4B) | Size (2B) | Type (1B) | Payload |
|
|
* +---------+-----------+-----------+--- ... ---+
|
|
*
|
|
* CRC = 32bit hash computed over the payload using CRC
|
|
* 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
|
|
*
|
|
*/
|
|
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.
|
|
explicit Writer(unique_ptr<WritableFileWriter>&& dest,
|
|
uint64_t log_number, bool recycle_log_files);
|
|
~Writer();
|
|
|
|
Status AddRecord(const Slice& slice);
|
|
|
|
WritableFileWriter* file() { return dest_.get(); }
|
|
const WritableFileWriter* file() const { return dest_.get(); }
|
|
|
|
private:
|
|
unique_ptr<WritableFileWriter> dest_;
|
|
int block_offset_; // Current offset in block
|
|
uint64_t log_number_;
|
|
bool recycle_log_files_;
|
|
|
|
// 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];
|
|
|
|
Status EmitPhysicalRecord(RecordType type, const char* ptr, size_t length);
|
|
|
|
// No copying allowed
|
|
Writer(const Writer&);
|
|
void operator=(const Writer&);
|
|
};
|
|
|
|
} // namespace log
|
|
} // namespace rocksdb
|