c06c4c01c5
Summary: Annotate all of the logging functions to inform the compiler that these use printf-style formatting arguments. This allows the compiler to emit warnings if the format arguments are incorrect. This also fixes many problems reported now that format string checking is enabled. Many of these are simply mix-ups in the argument type (e.g, int vs uint64_t), but in several cases the wrong number of arguments were being passed in which can cause the code to crash. The primary motivation for this was to fix the log message in `DBImpl::SwitchMemtable()` which caused a segfault due to an extra %s format parameter with no argument supplied. Pull Request resolved: https://github.com/facebook/rocksdb/pull/5089 Differential Revision: D14574795 Pulled By: simpkins fbshipit-source-id: 0921b03f0743652bf4ae21e414ff54b3bb65422a
73 lines
2.3 KiB
C++
73 lines
2.3 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
|
|
|
|
#ifndef __STDC_FORMAT_MACROS
|
|
#define __STDC_FORMAT_MACROS
|
|
#endif
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include "util/set_comparator.h"
|
|
|
|
namespace rocksdb {
|
|
// During recovery if the memtable is flushed we cannot rely on its help on
|
|
// duplicate key detection and as key insert will not be attempted. This class
|
|
// will be used as a emulator of memtable to tell if insertion of a key/seq
|
|
// would have resulted in duplication.
|
|
class DuplicateDetector {
|
|
public:
|
|
explicit DuplicateDetector(DBImpl* db) : db_(db) {}
|
|
bool IsDuplicateKeySeq(uint32_t cf, const Slice& key, SequenceNumber seq) {
|
|
assert(seq >= batch_seq_);
|
|
if (batch_seq_ != seq) { // it is a new batch
|
|
keys_.clear();
|
|
}
|
|
batch_seq_ = seq;
|
|
CFKeys& cf_keys = keys_[cf];
|
|
if (cf_keys.size() == 0) { // just inserted
|
|
InitWithComp(cf);
|
|
}
|
|
auto it = cf_keys.insert(key);
|
|
if (it.second == false) { // second is false if a element already existed.
|
|
keys_.clear();
|
|
InitWithComp(cf);
|
|
keys_[cf].insert(key);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private:
|
|
SequenceNumber batch_seq_ = 0;
|
|
DBImpl* db_;
|
|
using CFKeys = std::set<Slice, SetComparator>;
|
|
std::map<uint32_t, CFKeys> keys_;
|
|
void InitWithComp(const uint32_t cf) {
|
|
auto h = db_->GetColumnFamilyHandle(cf);
|
|
if (!h) {
|
|
// TODO(myabandeh): This is not a concern in MyRocks as drop cf is not
|
|
// implemented yet. When it does, we should return proper error instead
|
|
// of throwing exception.
|
|
ROCKS_LOG_FATAL(
|
|
db_->immutable_db_options().info_log,
|
|
"Recovering an entry from the dropped column family %" PRIu32
|
|
". WAL must must have been emptied before dropping the column "
|
|
"family", cf);
|
|
#ifndef ROCKSDB_LITE
|
|
throw std::runtime_error(
|
|
"Recovering an entry from a dropped column family. "
|
|
"WAL must must have been flushed before dropping the column "
|
|
"family");
|
|
#endif
|
|
return;
|
|
}
|
|
auto cmp = h->GetComparator();
|
|
keys_[cf] = CFKeys(SetComparator(cmp));
|
|
}
|
|
};
|
|
} // namespace rocksdb
|