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