Branch data Line data Source code
1 : : // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2 : : // Use of this source code is governed by a BSD-style license that can be
3 : : // found in the LICENSE file. See the AUTHORS file for names of contributors.
4 : :
5 : : #ifndef STORAGE_LEVELDB_DB_SNAPSHOT_H_
6 : : #define STORAGE_LEVELDB_DB_SNAPSHOT_H_
7 : :
8 : : #include "db/dbformat.h"
9 : : #include "leveldb/db.h"
10 : :
11 : : namespace leveldb {
12 : :
13 : : class SnapshotList;
14 : :
15 : : // Snapshots are kept in a doubly-linked list in the DB.
16 : : // Each SnapshotImpl corresponds to a particular sequence number.
17 : 978 : class SnapshotImpl : public Snapshot {
18 : : public:
19 : 489 : SnapshotImpl(SequenceNumber sequence_number)
20 : 489 : : sequence_number_(sequence_number) {}
21 : :
22 : 0 : SequenceNumber sequence_number() const { return sequence_number_; }
23 : :
24 : : private:
25 : : friend class SnapshotList;
26 : :
27 : : // SnapshotImpl is kept in a doubly-linked circular list. The SnapshotList
28 : : // implementation operates on the next/previous fields directly.
29 : : SnapshotImpl* prev_;
30 : : SnapshotImpl* next_;
31 : :
32 : : const SequenceNumber sequence_number_;
33 : :
34 : : #if !defined(NDEBUG)
35 : : SnapshotList* list_ = nullptr;
36 : : #endif // !defined(NDEBUG)
37 : : };
38 : :
39 : 489 : class SnapshotList {
40 : : public:
41 [ + - ]: 489 : SnapshotList() : head_(0) {
42 : 489 : head_.prev_ = &head_;
43 [ + - ]: 489 : head_.next_ = &head_;
44 : : }
45 : :
46 [ + - ]: 12 : bool empty() const { return head_.next_ == &head_; }
47 : 0 : SnapshotImpl* oldest() const {
48 [ # # ]: 0 : assert(!empty());
49 : 0 : return head_.next_;
50 : : }
51 : 0 : SnapshotImpl* newest() const {
52 [ # # ]: 0 : assert(!empty());
53 : 0 : return head_.prev_;
54 : : }
55 : :
56 : : // Creates a SnapshotImpl and appends it to the end of the list.
57 : 0 : SnapshotImpl* New(SequenceNumber sequence_number) {
58 [ # # # # ]: 0 : assert(empty() || newest()->sequence_number_ <= sequence_number);
59 : :
60 : 0 : SnapshotImpl* snapshot = new SnapshotImpl(sequence_number);
61 : :
62 : : #if !defined(NDEBUG)
63 : 0 : snapshot->list_ = this;
64 : : #endif // !defined(NDEBUG)
65 : 0 : snapshot->next_ = &head_;
66 : 0 : snapshot->prev_ = head_.prev_;
67 : 0 : snapshot->prev_->next_ = snapshot;
68 : 0 : snapshot->next_->prev_ = snapshot;
69 : 0 : return snapshot;
70 : : }
71 : :
72 : : // Removes a SnapshotImpl from this list.
73 : : //
74 : : // The snapshot must have been created by calling New() on this list.
75 : : //
76 : : // The snapshot pointer should not be const, because its memory is
77 : : // deallocated. However, that would force us to change DB::ReleaseSnapshot(),
78 : : // which is in the API, and currently takes a const Snapshot.
79 : 0 : void Delete(const SnapshotImpl* snapshot) {
80 : : #if !defined(NDEBUG)
81 [ # # ]: 0 : assert(snapshot->list_ == this);
82 : : #endif // !defined(NDEBUG)
83 : 0 : snapshot->prev_->next_ = snapshot->next_;
84 : 0 : snapshot->next_->prev_ = snapshot->prev_;
85 [ # # ]: 0 : delete snapshot;
86 : 0 : }
87 : :
88 : : private:
89 : : // Dummy head of doubly-linked list of snapshots
90 : : SnapshotImpl head_;
91 : : };
92 : :
93 : : } // namespace leveldb
94 : :
95 : : #endif // STORAGE_LEVELDB_DB_SNAPSHOT_H_
|