pinned_iterators_manager.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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. #include <algorithm>
  8. #include <memory>
  9. #include <utility>
  10. #include <vector>
  11. #include "table/internal_iterator.h"
  12. namespace ROCKSDB_NAMESPACE {
  13. // PinnedIteratorsManager will be notified whenever we need to pin an Iterator
  14. // and it will be responsible for deleting pinned Iterators when they are
  15. // not needed anymore.
  16. class PinnedIteratorsManager : public Cleanable {
  17. public:
  18. PinnedIteratorsManager() : pinning_enabled(false) {}
  19. ~PinnedIteratorsManager() {
  20. if (pinning_enabled) {
  21. ReleasePinnedData();
  22. }
  23. }
  24. // Enable Iterators pinning
  25. void StartPinning() {
  26. assert(pinning_enabled == false);
  27. pinning_enabled = true;
  28. }
  29. // Is pinning enabled ?
  30. bool PinningEnabled() { return pinning_enabled; }
  31. // Take ownership of iter and delete it when ReleasePinnedData() is called
  32. void PinIterator(InternalIterator* iter, bool arena = false) {
  33. if (arena) {
  34. PinPtr(iter, &PinnedIteratorsManager::ReleaseArenaInternalIterator);
  35. } else {
  36. PinPtr(iter, &PinnedIteratorsManager::ReleaseInternalIterator);
  37. }
  38. }
  39. typedef void (*ReleaseFunction)(void* arg1);
  40. void PinPtr(void* ptr, ReleaseFunction release_func) {
  41. assert(pinning_enabled);
  42. if (ptr == nullptr) {
  43. return;
  44. }
  45. pinned_ptrs_.emplace_back(ptr, release_func);
  46. }
  47. // Release pinned Iterators
  48. inline void ReleasePinnedData() {
  49. assert(pinning_enabled == true);
  50. pinning_enabled = false;
  51. // Remove duplicate pointers
  52. std::sort(pinned_ptrs_.begin(), pinned_ptrs_.end());
  53. auto unique_end = std::unique(pinned_ptrs_.begin(), pinned_ptrs_.end());
  54. for (auto i = pinned_ptrs_.begin(); i != unique_end; ++i) {
  55. void* ptr = i->first;
  56. ReleaseFunction release_func = i->second;
  57. release_func(ptr);
  58. }
  59. pinned_ptrs_.clear();
  60. // Also do cleanups from the base Cleanable
  61. Cleanable::Reset();
  62. }
  63. private:
  64. static void ReleaseInternalIterator(void* ptr) {
  65. delete reinterpret_cast<InternalIterator*>(ptr);
  66. }
  67. static void ReleaseArenaInternalIterator(void* ptr) {
  68. reinterpret_cast<InternalIterator*>(ptr)->~InternalIterator();
  69. }
  70. bool pinning_enabled;
  71. std::vector<std::pair<void*, ReleaseFunction>> pinned_ptrs_;
  72. };
  73. } // namespace ROCKSDB_NAMESPACE