Add support in log writer and reader for a user-defined timestamp size record (#11433)
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: b770c8f45bb7b9383b14aac9f22af781304fb41doxigraph-8.3.2
parent
8827cd0618
commit
47235dda9e
@ -0,0 +1,77 @@ |
|||||||
|
// 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
|
Loading…
Reference in new issue