YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/rocksdb/table/iterator_wrapper.h
Line
Count
Source (jump to first uncovered line)
1
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2
//  This source code is licensed under the BSD-style license found in the
3
//  LICENSE file in the root directory of this source tree. An additional grant
4
//  of patent rights can be found in the PATENTS file in the same directory.
5
//
6
// The following only applies to changes made to this file as part of YugaByte development.
7
//
8
// Portions Copyright (c) YugaByte, Inc.
9
//
10
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
11
// in compliance with the License.  You may obtain a copy of the License at
12
//
13
// http://www.apache.org/licenses/LICENSE-2.0
14
//
15
// Unless required by applicable law or agreed to in writing, software distributed under the License
16
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
17
// or implied.  See the License for the specific language governing permissions and limitations
18
// under the License.
19
//
20
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
21
// Use of this source code is governed by a BSD-style license that can be
22
// found in the LICENSE file. See the AUTHORS file for names of contributors.
23
24
#pragma once
25
26
#include <set>
27
28
#include "yb/rocksdb/table/internal_iterator.h"
29
30
namespace rocksdb {
31
32
// A internal wrapper class with an interface similar to Iterator that
33
// caches the valid() and key() results for an underlying iterator.
34
// This can help avoid virtual function calls and also gives better
35
// cache locality.
36
class IteratorWrapper {
37
 public:
38
80.6M
  IteratorWrapper() : iter_(nullptr), iters_pinned_(false), valid_(false) {}
39
  explicit IteratorWrapper(InternalIterator* _iter)
40
9.89M
      : iter_(nullptr), iters_pinned_(false) {
41
9.89M
    Set(_iter);
42
9.89M
  }
43
45.3M
  ~IteratorWrapper() {}
44
389M
  InternalIterator* iter() const { return iter_; }
45
46
  // Takes the ownership of "_iter" and will delete it when destroyed.
47
  // Next call to Set() will destroy "_iter" except if PinData() was called.
48
33.3M
  void Set(InternalIterator* _iter) {
49
33.3M
    if (iters_pinned_ && iter_) {
50
      // keep old iterator until ReleasePinnedData() is called
51
508k
      pinned_iters_.insert(iter_);
52
32.8M
    } else {
53
32.8M
      delete iter_;
54
32.8M
    }
55
56
33.3M
    iter_ = _iter;
57
33.3M
    if (iter_ == nullptr) {
58
528k
      valid_ = false;
59
32.8M
    } else {
60
32.8M
      Update();
61
32.8M
      if (iters_pinned_) {
62
        // Pin new iterator
63
627k
        Status s = iter_->PinData();
64
627k
        assert(s.ok());
65
627k
      }
66
32.8M
    }
67
33.3M
  }
68
69
118k
  Status PinData() {
70
118k
    Status s;
71
118k
    if (iters_pinned_) {
72
0
      return s;
73
0
    }
74
75
118k
    if (iter_) {
76
39
      s = iter_->PinData();
77
39
    }
78
79
118k
    if (s.ok()) {
80
118k
      iters_pinned_ = true;
81
118k
    }
82
83
118k
    return s;
84
118k
  }
85
86
0
  Status ReleasePinnedData() {
87
0
    Status s;
88
0
    if (!iters_pinned_) {
89
0
      return s;
90
0
    }
91
0
92
0
    if (iter_) {
93
0
      s = iter_->ReleasePinnedData();
94
0
    }
95
0
96
0
    if (s.ok()) {
97
0
      iters_pinned_ = false;
98
0
      // No need to call ReleasePinnedData() for pinned_iters_
99
0
      // since we will delete them
100
0
      DeletePinnedIterators(false);
101
0
    }
102
0
103
0
    return s;
104
0
  }
105
106
250M
  bool IsKeyPinned() const {
107
250M
    assert(iter_);
108
250M
    return iters_pinned_ && iter_->IsKeyPinned();
109
250M
  }
110
111
21.2M
  void DeleteIter(bool is_arena_mode) {
112
21.2M
    if (iter_ && pinned_iters_.find(iter_) == pinned_iters_.end()) {
113
20.9M
      DestroyIterator(iter_, is_arena_mode);
114
20.9M
    }
115
21.2M
    DeletePinnedIterators(is_arena_mode);
116
21.2M
  }
117
118
  // Iterator interface methods
119
5.74G
  bool Valid() const        { return valid_; }
120
1.71G
  Slice key() const         { assert(Valid()); return key_; }
121
1.59G
  Slice value() const       { assert(Valid()); return iter_->value(); }
122
  // Methods below require iter() != nullptr
123
47.7M
  Status status() const     { assert(iter_); return iter_->status(); }
124
593M
  void Next()               { assert(iter_); iter_->Next();        Update(); }
125
4.90M
  void Prev()               { assert(iter_); iter_->Prev();        Update(); }
126
82.2M
  void Seek(const Slice& k) { assert(iter_); iter_->Seek(k);       Update(); }
127
3.32M
  void SeekToFirst()        { assert(iter_); iter_->SeekToFirst(); Update(); }
128
1.10M
  void SeekToLast()         { assert(iter_); iter_->SeekToLast();  Update(); }
129
130
 private:
131
715M
  void Update() {
132
715M
    valid_ = iter_->Valid();
133
715M
    if (valid_) {
134
676M
      key_ = iter_->key();
135
676M
    }
136
715M
  }
137
138
21.2M
  void DeletePinnedIterators(bool is_arena_mode) {
139
508k
    for (auto it : pinned_iters_) {
140
508k
      DestroyIterator(it, is_arena_mode);
141
508k
    }
142
21.2M
    pinned_iters_.clear();
143
21.2M
  }
144
145
21.4M
  inline void DestroyIterator(InternalIterator* it, bool is_arena_mode) {
146
21.4M
    if (!is_arena_mode) {
147
15.3M
      delete it;
148
6.11M
    } else {
149
6.11M
      it->~InternalIterator();
150
6.11M
    }
151
21.4M
  }
152
153
  InternalIterator* iter_;
154
  // If set to true, current and future iterators wont be deleted.
155
  bool iters_pinned_;
156
  // List of past iterators that are pinned and wont be deleted as long as
157
  // iters_pinned_ is true. When we are pinning iterators this set will contain
158
  // iterators of previous data blocks to keep them from being deleted.
159
  std::set<InternalIterator*> pinned_iters_;
160
  bool valid_;
161
  Slice key_;
162
};
163
164
class Arena;
165
// Return an empty iterator (yields nothing) allocated from arena.
166
extern InternalIterator* NewEmptyInternalIterator(Arena* arena);
167
168
// Return an empty iterator with the specified status, allocated arena.
169
extern InternalIterator* NewErrorInternalIterator(const Status& status,
170
                                                  Arena* arena);
171
172
}  // namespace rocksdb