duplicate_detector.h 2.3 KB

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