1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
3 * Copyright 2017 Couchbase, Inc
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
19 * This header file contains the abstract base class for the classes that hold
20 * ordered sequence of items in memory. This is not generic, holds only ordered
21 * seq of OrderedStoredValue's. (OrderedStoredValue is the in-memory
22 * representation of an
33 #include "memcached/engine_error.h"
34 #include "stored-value.h"
36 /* [EPHE TODO]: Check if uint64_t can be used instead */
37 using seqno_t = int64_t;
40 * SequenceList is the abstract base class for the classes that hold ordered
41 * sequence of items in memory. To store/retreive items sequencially in memory,
42 * in our multi-threaded, monotonically increasing seq model, we need these
43 * classes around basic data structures like Linkedlist or Skiplist.
45 * 'OrderedStoredValue' is the in-memory representation of an item that can be
46 * stored sequentially and SequenceList derivatives store a sequence of
47 * 'OrderedStoredValues'. Based on the implementation of SequenceList,
48 * OrderedStoredValue might have to carry an intrusive component that
49 * is necessary for the list.
51 * SequenceList expects the module that contains it, takes the responsibility
52 * of serializing the OrderedStoredValue. SequenceList only guarentees to hold
53 * the OrderedStoredValue in the order they are sent to it. For this it forces
54 * the write calls to pass the seq lock held by them
56 * Note: These classes only handle the position of the 'OrderedStoredValue' in
57 * the ordered sequence desired. They do not update a OrderedStoredValue.
59 * In the file 'item', 'OrderedStoredValue' are used interchangeably
61 * [EPHE TODO]: create a documentation (with diagrams) explaining write, update,
62 * rangeRead and Clean Up
67 * Indicates whether the updateListElem is successful or the list is
69 * only appends at the moment.
71 enum class UpdateStatus { Success, Append };
73 virtual ~SequenceList() {
77 * Add a new item at the end of the list.
79 * @param seqLock A sequence lock the calling module is expected to hold.
80 * @param v Ref to orderedStoredValue which will placed into the linked list
81 * Its intrusive list links will be updated.
83 virtual void appendToList(std::lock_guard<std::mutex>& seqLock,
84 OrderedStoredValue& v) = 0;
87 * If possible, update an existing element the list and move it to end.
88 * If there is a range read in the position of the element being updated
89 * we do not allow the update and indicate the caller to do an append.
91 * @param seqLock A sequence lock the calling module is expected to hold.
92 * @param v Ref to orderedStoredValue which will placed into the linked list
93 * Its intrusive list links will be updated.
95 * @return UpdateStatus::Success list element has been updated and moved to
97 * UpdateStatus::Append list element is *not* updated. Caller must
100 virtual SequenceList::UpdateStatus updateListElem(
101 std::lock_guard<std::mutex>& seqLock, OrderedStoredValue& v) = 0;
104 * Provides point-in-time snapshots which can be used for incremental
107 * Copies the StoredValues as a vector of ref counterd items starting from
108 * 'start + 1' seqno into 'items' as a snapshot.
110 * Since we use monotonically increasing point-in-time snapshots we cannot
111 * guarantee that the snapshot ends at the requested end seqno. Due to
112 * dedups we may have to send till a higher seqno in the snapshot.
114 * @param start requested start seqno
115 * @param end requested end seqno
117 * @return ENGINE_SUCCESS, items in the snapshot and adjusted endSeqNo
118 * ENGINE_ENOMEM on no memory to copy items
119 * ENGINE_ERANGE on incorrect start and end
121 virtual std::tuple<ENGINE_ERROR_CODE, std::vector<UniqueItemPtr>, seqno_t>
122 rangeRead(seqno_t start, seqno_t end) = 0;
125 * Updates the highSeqno in the list. Since seqno is generated and managed
126 * outside the list, the module managing it must update this after the seqno
127 * is generated for the item already put in the list.
128 * @param highSeqnoLock The lock protecting the high seqnos the caller is
130 * @param v Ref to orderedStoredValue
132 virtual void updateHighSeqno(std::lock_guard<std::mutex>& highSeqnoLock,
133 const OrderedStoredValue& v) = 0;
136 * Updates the highestDedupedSeqno in the list. Since seqno is generated and
137 * managed outside the list, the module managing it must update this after
138 * the seqno is generated for the item already put in the list.
139 * @param highSeqnoLock The lock protecting the high seqnos the caller is
141 * @param v Ref to orderedStoredValue
144 virtual void updateHighestDedupedSeqno(
145 std::lock_guard<std::mutex>& highSeqnoLock,
146 const OrderedStoredValue& v) = 0;
149 * Mark an OrderedStoredValue stale and assumes its ownership.
150 * Note: It is upto the sequential data structure implementation how it
151 * wants to own the OrderedStoredValue (as owned type vs non-owned
154 * @param ownedSv StoredValue whose ownership is passed to the sequential
157 virtual void markItemStale(StoredValue::UniquePtr ownedSv) = 0;
160 * Remove from sequence list and delete all OSVs which are purgable.
161 * OSVs which can be purged are items which are outside the ReadRange and
164 * @return The number of items purged from the sequence list (and hence
167 virtual size_t purgeTombstones() = 0;
170 * Updates the number of deleted items in the sequence list whenever
171 * an item is modified.
173 * @param oldDeleted Was the old item deleted?
174 * @param newDeleted Was the new item replacing it deleted?
176 virtual void updateNumDeletedItems(bool oldDeleted, bool newDeleted) = 0;
179 * Returns the number of stale items in the list.
181 * @return count of stale items
183 virtual uint64_t getNumStaleItems() const = 0;
186 * Return the count of bytes of the values of stale items in the list.
188 virtual size_t getStaleValueBytes() const = 0;
191 * Return the count of bytes of the metadata of stale items in the list.
193 virtual size_t getStaleMetadataBytes() const = 0;
196 * Returns the number of deleted items in the list.
198 * @return count of deleted items
200 virtual uint64_t getNumDeletedItems() const = 0;
203 * Returns the number of items in the list.
205 * @return count of items
207 virtual uint64_t getNumItems() const = 0;
210 * Returns the highSeqno in the list.
212 virtual uint64_t getHighSeqno() const = 0;
215 * Returns the highest de-duplicated sequence number in the list.
217 virtual uint64_t getHighestDedupedSeqno() const = 0;
220 * Returns the highest purged Deleted sequence number in the list.
222 virtual seqno_t getHighestPurgedDeletedSeqno() const = 0;
225 * Returns the current range read begin sequence number.
227 virtual uint64_t getRangeReadBegin() const = 0;
230 * Returns the current range read end sequence number.
232 virtual uint64_t getRangeReadEnd() const = 0;
235 * Returns the lock which must be held to modify the highSeqno or the
236 * highestDedupedSeqno
238 virtual std::mutex& getHighSeqnosLock() const = 0;
241 * Debug - prints a representation of the list to stderr.
243 virtual void dump() const = 0;