| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- // 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
- #include <algorithm>
- #include <memory>
- #include <utility>
- #include <vector>
- #include "table/internal_iterator.h"
- namespace ROCKSDB_NAMESPACE {
- // PinnedIteratorsManager will be notified whenever we need to pin an Iterator
- // and it will be responsible for deleting pinned Iterators when they are
- // not needed anymore.
- class PinnedIteratorsManager : public Cleanable {
- public:
- PinnedIteratorsManager() : pinning_enabled(false) {}
- ~PinnedIteratorsManager() {
- if (pinning_enabled) {
- ReleasePinnedData();
- }
- }
- // Enable Iterators pinning
- void StartPinning() {
- assert(pinning_enabled == false);
- pinning_enabled = true;
- }
- // Is pinning enabled ?
- bool PinningEnabled() { return pinning_enabled; }
- // Take ownership of iter and delete it when ReleasePinnedData() is called
- void PinIterator(InternalIterator* iter, bool arena = false) {
- if (arena) {
- PinPtr(iter, &PinnedIteratorsManager::ReleaseArenaInternalIterator);
- } else {
- PinPtr(iter, &PinnedIteratorsManager::ReleaseInternalIterator);
- }
- }
- typedef void (*ReleaseFunction)(void* arg1);
- void PinPtr(void* ptr, ReleaseFunction release_func) {
- assert(pinning_enabled);
- if (ptr == nullptr) {
- return;
- }
- pinned_ptrs_.emplace_back(ptr, release_func);
- }
- // Release pinned Iterators
- inline void ReleasePinnedData() {
- assert(pinning_enabled == true);
- pinning_enabled = false;
- // Remove duplicate pointers
- std::sort(pinned_ptrs_.begin(), pinned_ptrs_.end());
- auto unique_end = std::unique(pinned_ptrs_.begin(), pinned_ptrs_.end());
- for (auto i = pinned_ptrs_.begin(); i != unique_end; ++i) {
- void* ptr = i->first;
- ReleaseFunction release_func = i->second;
- release_func(ptr);
- }
- pinned_ptrs_.clear();
- // Also do cleanups from the base Cleanable
- Cleanable::Reset();
- }
- private:
- static void ReleaseInternalIterator(void* ptr) {
- delete reinterpret_cast<InternalIterator*>(ptr);
- }
- static void ReleaseArenaInternalIterator(void* ptr) {
- reinterpret_cast<InternalIterator*>(ptr)->~InternalIterator();
- }
- bool pinning_enabled;
- std::vector<std::pair<void*, ReleaseFunction>> pinned_ptrs_;
- };
- } // namespace ROCKSDB_NAMESPACE
|