// 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 #include #include #include #include "table/internal_iterator.h" namespace rocksdb { // 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(ptr); } static void ReleaseArenaInternalIterator(void* ptr) { reinterpret_cast(ptr)->~InternalIterator(); } bool pinning_enabled; std::vector> pinned_ptrs_; }; } // namespace rocksdb