mirror of
https://github.com/facebook/rocksdb.git
synced 2024-11-26 07:30:54 +00:00
47235dda9e
Summary: This patch adds support to write and read a user-defined timestamp size record in log writer and log reader. It will be used by WAL logs to persist the user-defined timestamp format for subsequent WriteBatch records. Reading and writing UDT sizes for WAL logs are not included in this patch. It will be in a follow up. The syntax for the record is: at write time, one such record is added when log writer encountered any non-zero UDT size it hasn't recorded so far. At read time, all such records read up to a point are accumulated and applicable to all subsequent WriteBatch records. Pull Request resolved: https://github.com/facebook/rocksdb/pull/11433 Test Plan: ``` make clean && make -j32 all ./log_test --gtest_filter="*WithTimestampSize*" ``` Reviewed By: ltamasi Differential Revision: D45678708 Pulled By: jowlyzhang fbshipit-source-id: b770c8f45bb7b9383b14aac9f22af781304fb41d
78 lines
2.4 KiB
C++
78 lines
2.4 KiB
C++
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
|
// 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).
|
|
|
|
#pragma once
|
|
#include <sstream>
|
|
#include <vector>
|
|
|
|
#include "rocksdb/slice.h"
|
|
#include "rocksdb/status.h"
|
|
#include "util/coding.h"
|
|
|
|
namespace ROCKSDB_NAMESPACE {
|
|
|
|
// Dummy record in WAL logs signaling user-defined timestamp sizes for
|
|
// subsequent records.
|
|
class UserDefinedTimestampSizeRecord {
|
|
public:
|
|
UserDefinedTimestampSizeRecord() {}
|
|
explicit UserDefinedTimestampSizeRecord(
|
|
std::vector<std::pair<uint32_t, size_t>>&& cf_to_ts_sz)
|
|
: cf_to_ts_sz_(std::move(cf_to_ts_sz)) {}
|
|
|
|
const std::vector<std::pair<uint32_t, size_t>>& GetUserDefinedTimestampSize()
|
|
const {
|
|
return cf_to_ts_sz_;
|
|
}
|
|
|
|
inline void EncodeTo(std::string* dst) const {
|
|
assert(dst != nullptr);
|
|
for (const auto& [cf_id, ts_sz] : cf_to_ts_sz_) {
|
|
assert(ts_sz != 0);
|
|
PutFixed32(dst, cf_id);
|
|
PutFixed16(dst, static_cast<uint16_t>(ts_sz));
|
|
}
|
|
}
|
|
|
|
inline Status DecodeFrom(Slice* src) {
|
|
const size_t total_size = src->size();
|
|
if ((total_size % kSizePerColumnFamily) != 0) {
|
|
std::ostringstream oss;
|
|
oss << "User-defined timestamp size record length: " << total_size
|
|
<< " is not a multiple of " << kSizePerColumnFamily << std::endl;
|
|
return Status::Corruption(oss.str());
|
|
}
|
|
int num_of_entries = static_cast<int>(total_size / kSizePerColumnFamily);
|
|
for (int i = 0; i < num_of_entries; i++) {
|
|
uint32_t cf_id = 0;
|
|
uint16_t ts_sz = 0;
|
|
if (!GetFixed32(src, &cf_id) || !GetFixed16(src, &ts_sz)) {
|
|
return Status::Corruption(
|
|
"Error decoding user-defined timestamp size record entry");
|
|
}
|
|
cf_to_ts_sz_.emplace_back(cf_id, static_cast<size_t>(ts_sz));
|
|
}
|
|
return Status::OK();
|
|
}
|
|
|
|
inline std::string DebugString() const {
|
|
std::ostringstream oss;
|
|
|
|
for (const auto& [cf_id, ts_sz] : cf_to_ts_sz_) {
|
|
oss << "Column family: " << cf_id
|
|
<< ", user-defined timestamp size: " << ts_sz << std::endl;
|
|
}
|
|
return oss.str();
|
|
}
|
|
|
|
private:
|
|
// 4 bytes for column family id, 2 bytes for user-defined timestamp size.
|
|
static constexpr size_t kSizePerColumnFamily = 4 + 2;
|
|
|
|
std::vector<std::pair<uint32_t, size_t>> cf_to_ts_sz_;
|
|
};
|
|
|
|
} // namespace ROCKSDB_NAMESPACE
|