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).
12 #include "table/internal_iterator.h"
14 namespace ROCKSDB_NAMESPACE
{
16 // PinnedIteratorsManager will be notified whenever we need to pin an Iterator
17 // and it will be responsible for deleting pinned Iterators when they are
18 // not needed anymore.
19 class PinnedIteratorsManager
: public Cleanable
{
21 PinnedIteratorsManager() : pinning_enabled(false) {}
22 ~PinnedIteratorsManager() {
23 if (pinning_enabled
) {
28 // Move constructor and move assignment is allowed.
29 PinnedIteratorsManager(PinnedIteratorsManager
&& other
) noexcept
= default;
30 PinnedIteratorsManager
& operator=(PinnedIteratorsManager
&& other
) noexcept
=
33 // Enable Iterators pinning
35 assert(pinning_enabled
== false);
36 pinning_enabled
= true;
39 // Is pinning enabled ?
40 bool PinningEnabled() { return pinning_enabled
; }
42 // Take ownership of iter and delete it when ReleasePinnedData() is called
43 void PinIterator(InternalIterator
* iter
, bool arena
= false) {
45 PinPtr(iter
, &PinnedIteratorsManager::ReleaseArenaInternalIterator
);
47 PinPtr(iter
, &PinnedIteratorsManager::ReleaseInternalIterator
);
51 using ReleaseFunction
= void (*)(void* arg1
);
52 void PinPtr(void* ptr
, ReleaseFunction release_func
) {
53 assert(pinning_enabled
);
57 pinned_ptrs_
.emplace_back(ptr
, release_func
);
60 // Release pinned Iterators
61 inline void ReleasePinnedData() {
62 assert(pinning_enabled
== true);
63 pinning_enabled
= false;
65 // Remove duplicate pointers
66 std::sort(pinned_ptrs_
.begin(), pinned_ptrs_
.end());
67 auto unique_end
= std::unique(pinned_ptrs_
.begin(), pinned_ptrs_
.end());
69 for (auto i
= pinned_ptrs_
.begin(); i
!= unique_end
; ++i
) {
71 ReleaseFunction release_func
= i
->second
;
75 // Also do cleanups from the base Cleanable
80 static void ReleaseInternalIterator(void* ptr
) {
81 delete reinterpret_cast<InternalIterator
*>(ptr
);
84 static void ReleaseArenaInternalIterator(void* ptr
) {
85 reinterpret_cast<InternalIterator
*>(ptr
)->~InternalIterator();
89 std::vector
<std::pair
<void*, ReleaseFunction
>> pinned_ptrs_
;
92 } // namespace ROCKSDB_NAMESPACE