duplicate_detector.h 2.3 KB

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