YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/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
196M
  IteratorWrapper() : iter_(nullptr), iters_pinned_(false), valid_(false) {}
39
  explicit IteratorWrapper(InternalIterator* _iter)
40
38.8M
      : iter_(nullptr), iters_pinned_(false) {
41
38.8M
    Set(_iter);
42
38.8M
  }
43
145M
  ~IteratorWrapper() {}
44
1.11G
  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
104M
  void Set(InternalIterator* _iter) {
49
104M
    if (iters_pinned_ && 
iter_712k
) {
50
      // keep old iterator until ReleasePinnedData() is called
51
588k
      pinned_iters_.insert(iter_);
52
103M
    } else {
53
103M
      delete iter_;
54
103M
    }
55
56
104M
    iter_ = _iter;
57
104M
    if (iter_ == nullptr) {
58
2.59M
      valid_ = false;
59
101M
    } else {
60
101M
      Update();
61
101M
      if (iters_pinned_) {
62
        // Pin new iterator
63
705k
        Status s = iter_->PinData();
64
705k
        assert(s.ok());
65
705k
      }
66
101M
    }
67
104M
  }
68
69
116k
  Status PinData() {
70
116k
    Status s;
71
116k
    if (iters_pinned_) {
72
0
      return s;
73
0
    }
74
75
116k
    if (iter_) {
76
43
      s = iter_->PinData();
77
43
    }
78
79
116k
    if (s.ok()) {
80
116k
      iters_pinned_ = true;
81
116k
    }
82
83
116k
    return s;
84
116k
  }
85
86
0
  Status ReleasePinnedData() {
87
0
    Status s;
88
0
    if (!iters_pinned_) {
89
0
      return s;
90
0
    }
91
92
0
    if (iter_) {
93
0
      s = iter_->ReleasePinnedData();
94
0
    }
95
96
0
    if (s.ok()) {
97
0
      iters_pinned_ = false;
98
      // No need to call ReleasePinnedData() for pinned_iters_
99
      // since we will delete them
100
0
      DeletePinnedIterators(false);
101
0
    }
102
103
0
    return s;
104
0
  }
105
106
792M
  bool IsKeyPinned() const {
107
792M
    assert(iter_);
108
792M
    return iters_pinned_ && 
iter_->IsKeyPinned()1.22M
;
109
792M
  }
110
111
75.0M
  void DeleteIter(bool is_arena_mode) {
112
75.0M
    if (iter_ && 
pinned_iters_.find(iter_) == pinned_iters_.end()74.6M
) {
113
74.6M
      DestroyIterator(iter_, is_arena_mode);
114
74.6M
    }
115
75.0M
    DeletePinnedIterators(is_arena_mode);
116
75.0M
  }
117
118
  // Iterator interface methods
119
16.5G
  bool Valid() const        { return valid_; }
120
4.97G
  Slice key() const         { assert(Valid()); return key_; }
121
4.75G
  Slice value() const       { assert(Valid()); return iter_->value(); }
122
  // Methods below require iter() != nullptr
123
150M
  Status status() const     { assert(iter_); return iter_->status(); }
124
1.55G
  void Next()               { assert(iter_); iter_->Next();        Update(); }
125
15.5M
  void Prev()               { assert(iter_); iter_->Prev();        Update(); }
126
414M
  void Seek(const Slice& k) { assert(iter_); iter_->Seek(k);       Update(); }
127
4.45M
  void SeekToFirst()        { assert(iter_); iter_->SeekToFirst(); Update(); }
128
6.94M
  void SeekToLast()         { assert(iter_); iter_->SeekToLast();  Update(); }
129
130
 private:
131
2.09G
  void Update() {
132
2.09G
    valid_ = iter_->Valid();
133
2.09G
    if (valid_) {
134
1.97G
      key_ = iter_->key();
135
1.97G
    }
136
2.09G
  }
137
138
75.0M
  void DeletePinnedIterators(bool is_arena_mode) {
139
75.0M
    for (auto it : pinned_iters_) {
140
588k
      DestroyIterator(it, is_arena_mode);
141
588k
    }
142
75.0M
    pinned_iters_.clear();
143
75.0M
  }
144
145
75.1M
  inline void DestroyIterator(InternalIterator* it, bool is_arena_mode) {
146
75.1M
    if (!is_arena_mode) {
147
50.9M
      delete it;
148
50.9M
    } else {
149
24.2M
      it->~InternalIterator();
150
24.2M
    }
151
75.1M
  }
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