YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/rocksdb/db/snapshot_impl.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 <vector>
27
28
#include "yb/rocksdb/db.h"
29
#include "yb/rocksdb/db/dbformat.h"
30
#include "yb/rocksdb/snapshot.h"
31
32
namespace rocksdb {
33
34
class SnapshotList;
35
36
// Snapshots are kept in a doubly-linked list in the DB.
37
// Each SnapshotImpl corresponds to a particular sequence number.
38
class SnapshotImpl : public Snapshot {
39
 public:
40
  SequenceNumber number_;  // const after creation
41
42
238
  virtual SequenceNumber GetSequenceNumber() const override { return number_; }
43
44
 private:
45
  friend class SnapshotList;
46
47
  // SnapshotImpl is kept in a doubly-linked circular list
48
  SnapshotImpl* prev_;
49
  SnapshotImpl* next_;
50
51
  SnapshotList* list_;                 // just for sanity checks
52
53
  int64_t unix_time_;
54
55
  // Will this snapshot be used by a Transaction to do write-conflict checking?
56
  bool is_write_conflict_boundary_;
57
};
58
59
class SnapshotList {
60
 public:
61
435k
  SnapshotList() {
62
435k
    list_.prev_ = &list_;
63
435k
    list_.next_ = &list_;
64
435k
    list_.number_ = 0xFFFFFFFFL;      // placeholder marker, for debugging
65
435k
    count_ = 0;
66
435k
  }
67
68
84.9k
  bool empty() const { return list_.next_ == &list_; }
69
150
  SnapshotImpl* oldest() const { assert(!empty()); return list_.next_; }
70
0
  SnapshotImpl* newest() const { assert(!empty()); return list_.prev_; }
71
72
  const SnapshotImpl* New(SnapshotImpl* s, SequenceNumber seq,
73
3.27k
                          uint64_t unix_time, bool is_write_conflict_boundary) {
74
3.27k
    s->number_ = seq;
75
3.27k
    s->unix_time_ = unix_time;
76
3.27k
    s->is_write_conflict_boundary_ = is_write_conflict_boundary;
77
3.27k
    s->list_ = this;
78
3.27k
    s->next_ = &list_;
79
3.27k
    s->prev_ = list_.prev_;
80
3.27k
    s->prev_->next_ = s;
81
3.27k
    s->next_->prev_ = s;
82
3.27k
    count_++;
83
3.27k
    return s;
84
3.27k
  }
85
86
  // Do not responsible to free the object.
87
3.27k
  void Delete(const SnapshotImpl* s) {
88
3.27k
    assert(s->list_ == this);
89
0
    s->prev_->next_ = s->next_;
90
3.27k
    s->next_->prev_ = s->prev_;
91
3.27k
    count_--;
92
3.27k
  }
93
94
  // retrieve all snapshot numbers. They are sorted in ascending order.
95
  std::vector<SequenceNumber> GetAll(
96
74.7k
      SequenceNumber* oldest_write_conflict_snapshot = nullptr) {
97
74.7k
    std::vector<SequenceNumber> ret;
98
99
74.7k
    if (oldest_write_conflict_snapshot != nullptr) {
100
74.7k
      *oldest_write_conflict_snapshot = kMaxSequenceNumber;
101
74.7k
    }
102
103
74.7k
    if (empty()) {
104
74.0k
      return ret;
105
74.0k
    }
106
750
    SnapshotImpl* s = &list_;
107
1.55k
    while (s->next_ != &list_) {
108
805
      ret.push_back(s->next_->number_);
109
110
805
      if (oldest_write_conflict_snapshot != nullptr &&
111
805
          *oldest_write_conflict_snapshot == kMaxSequenceNumber &&
112
805
          s->next_->is_write_conflict_boundary_) {
113
        // If this is the first write-conflict boundary snapshot in the list,
114
        // it is the oldest
115
18
        *oldest_write_conflict_snapshot = s->next_->number_;
116
18
      }
117
118
805
      s = s->next_;
119
805
    }
120
750
    return ret;
121
74.7k
  }
122
123
  // get the sequence number of the most recent snapshot
124
0
  SequenceNumber GetNewest() {
125
0
    if (empty()) {
126
0
      return 0;
127
0
    }
128
0
    return newest()->number_;
129
0
  }
130
131
150
  int64_t GetOldestSnapshotTime() const {
132
150
    if (empty()) {
133
0
      return 0;
134
150
    } else {
135
150
      return oldest()->unix_time_;
136
150
    }
137
150
  }
138
139
180
  uint64_t count() const { return count_; }
140
141
 private:
142
  // Dummy head of doubly-linked list of snapshots
143
  SnapshotImpl list_;
144
  uint64_t count_;
145
};
146
147
}  // namespace rocksdb