Coverage Report

Created: 2025-07-23 07:17

/src/rocksdb/util/duplicate_detector.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2
//  This source code is licensed under both the GPLv2 (found in the
3
//  COPYING file in the root directory) and Apache 2.0 License
4
//  (found in the LICENSE.Apache file in the root directory).
5
6
#pragma once
7
8
#include <cstdint>
9
10
#include "db/db_impl/db_impl.h"
11
#include "logging/logging.h"
12
#include "util/set_comparator.h"
13
14
namespace ROCKSDB_NAMESPACE {
15
// During recovery if the memtable is flushed we cannot rely on its help on
16
// duplicate key detection and as key insert will not be attempted. This class
17
// will be used as a emulator of memtable to tell if insertion of a key/seq
18
// would have resulted in duplication.
19
class DuplicateDetector {
20
 public:
21
0
  explicit DuplicateDetector(DBImpl* db) : db_(db) {}
22
0
  bool IsDuplicateKeySeq(uint32_t cf, const Slice& key, SequenceNumber seq) {
23
0
    assert(seq >= batch_seq_);
24
0
    if (batch_seq_ != seq) {  // it is a new batch
25
0
      keys_.clear();
26
0
    }
27
0
    batch_seq_ = seq;
28
0
    CFKeys& cf_keys = keys_[cf];
29
0
    if (cf_keys.size() == 0) {  // just inserted
30
0
      InitWithComp(cf);
31
0
    }
32
0
    auto it = cf_keys.insert(key);
33
0
    if (it.second == false) {  // second is false if a element already existed.
34
0
      keys_.clear();
35
0
      InitWithComp(cf);
36
0
      keys_[cf].insert(key);
37
0
      return true;
38
0
    }
39
0
    return false;
40
0
  }
41
42
 private:
43
  SequenceNumber batch_seq_ = 0;
44
  DBImpl* db_;
45
  using CFKeys = std::set<Slice, SetComparator>;
46
  std::map<uint32_t, CFKeys> keys_;
47
0
  void InitWithComp(const uint32_t cf) {
48
0
    auto h = db_->GetColumnFamilyHandle(cf);
49
0
    if (!h) {
50
      // TODO(myabandeh): This is not a concern in MyRocks as drop cf is not
51
      // implemented yet. When it does, we should return proper error instead
52
      // of throwing exception.
53
0
      ROCKS_LOG_FATAL(
54
0
          db_->immutable_db_options().info_log,
55
0
          "Recovering an entry from the dropped column family %" PRIu32
56
0
          ". WAL must must have been emptied before dropping the column "
57
0
          "family",
58
0
          cf);
59
0
      throw std::runtime_error(
60
0
          "Recovering an entry from a dropped column family. "
61
0
          "WAL must must have been flushed before dropping the column "
62
0
          "family");
63
0
      return;
64
0
    }
65
0
    auto cmp = h->GetComparator();
66
0
    keys_[cf] = CFKeys(SetComparator(cmp));
67
0
  }
68
};
69
}  // namespace ROCKSDB_NAMESPACE