1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
5 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
6 // Use of this source code is governed by a BSD-style license that can be
7 // found in the LICENSE file. See the AUTHORS file for names of contributors.
9 // A WriteBatchWithIndex with a binary searchable index built for all the keys
19 #include "rocksdb/comparator.h"
20 #include "rocksdb/iterator.h"
21 #include "rocksdb/slice.h"
22 #include "rocksdb/status.h"
23 #include "rocksdb/write_batch.h"
24 #include "rocksdb/write_batch_base.h"
26 namespace ROCKSDB_NAMESPACE
{
28 class ColumnFamilyHandle
;
46 // an entry for Put, Merge, Delete, or SingleDelete entry for write batches.
47 // Used in WBWIIterator.
49 WriteType type
= kUnknownRecord
;
54 // Iterator of one column family out of a WriteBatchWithIndex.
57 virtual ~WBWIIterator() {}
59 virtual bool Valid() const = 0;
61 virtual void SeekToFirst() = 0;
63 virtual void SeekToLast() = 0;
65 virtual void Seek(const Slice
& key
) = 0;
67 virtual void SeekForPrev(const Slice
& key
) = 0;
69 virtual void Next() = 0;
71 virtual void Prev() = 0;
73 // the return WriteEntry is only valid until the next mutation of
74 // WriteBatchWithIndex
75 virtual WriteEntry
Entry() const = 0;
77 virtual Status
status() const = 0;
80 // A WriteBatchWithIndex with a binary searchable index built for all the keys
82 // In Put(), Merge() Delete(), or SingleDelete(), the same function of the
83 // wrapped will be called. At the same time, indexes will be built.
84 // By calling GetWriteBatch(), a user will get the WriteBatch for the data
85 // they inserted, which can be used for DB::Write().
86 // A user can call NewIterator() to create an iterator.
87 class WriteBatchWithIndex
: public WriteBatchBase
{
89 // backup_index_comparator: the backup comparator used to compare keys
90 // within the same column family, if column family is not given in the
91 // interface, or we can't find a column family from the column family handle
92 // passed in, backup_index_comparator will be used for the column family.
93 // reserved_bytes: reserved bytes in underlying WriteBatch
94 // max_bytes: maximum size of underlying WriteBatch in bytes
95 // overwrite_key: if true, overwrite the key in the index when inserting
96 // the same key as previously, so iterator will never
97 // show two entries with the same key.
98 explicit WriteBatchWithIndex(
99 const Comparator
* backup_index_comparator
= BytewiseComparator(),
100 size_t reserved_bytes
= 0, bool overwrite_key
= false,
101 size_t max_bytes
= 0, size_t protection_bytes_per_key
= 0);
103 ~WriteBatchWithIndex() override
;
104 WriteBatchWithIndex(WriteBatchWithIndex
&&);
105 WriteBatchWithIndex
& operator=(WriteBatchWithIndex
&&);
107 using WriteBatchBase::Put
;
108 Status
Put(ColumnFamilyHandle
* column_family
, const Slice
& key
,
109 const Slice
& value
) override
;
111 Status
Put(const Slice
& key
, const Slice
& value
) override
;
113 Status
Put(ColumnFamilyHandle
* column_family
, const Slice
& key
,
114 const Slice
& ts
, const Slice
& value
) override
;
116 Status
PutEntity(ColumnFamilyHandle
* column_family
, const Slice
& /* key */,
117 const WideColumns
& /* columns */) override
{
118 if (!column_family
) {
119 return Status::InvalidArgument(
120 "Cannot call this method without a column family handle");
123 return Status::NotSupported(
124 "PutEntity not supported by WriteBatchWithIndex");
127 using WriteBatchBase::Merge
;
128 Status
Merge(ColumnFamilyHandle
* column_family
, const Slice
& key
,
129 const Slice
& value
) override
;
131 Status
Merge(const Slice
& key
, const Slice
& value
) override
;
132 Status
Merge(ColumnFamilyHandle
* /*column_family*/, const Slice
& /*key*/,
133 const Slice
& /*ts*/, const Slice
& /*value*/) override
{
134 return Status::NotSupported(
135 "Merge does not support user-defined timestamp");
138 using WriteBatchBase::Delete
;
139 Status
Delete(ColumnFamilyHandle
* column_family
, const Slice
& key
) override
;
140 Status
Delete(const Slice
& key
) override
;
141 Status
Delete(ColumnFamilyHandle
* column_family
, const Slice
& key
,
142 const Slice
& ts
) override
;
144 using WriteBatchBase::SingleDelete
;
145 Status
SingleDelete(ColumnFamilyHandle
* column_family
,
146 const Slice
& key
) override
;
147 Status
SingleDelete(const Slice
& key
) override
;
148 Status
SingleDelete(ColumnFamilyHandle
* column_family
, const Slice
& key
,
149 const Slice
& ts
) override
;
151 using WriteBatchBase::DeleteRange
;
152 Status
DeleteRange(ColumnFamilyHandle
* /* column_family */,
153 const Slice
& /* begin_key */,
154 const Slice
& /* end_key */) override
{
155 return Status::NotSupported(
156 "DeleteRange unsupported in WriteBatchWithIndex");
158 Status
DeleteRange(const Slice
& /* begin_key */,
159 const Slice
& /* end_key */) override
{
160 return Status::NotSupported(
161 "DeleteRange unsupported in WriteBatchWithIndex");
163 Status
DeleteRange(ColumnFamilyHandle
* /*column_family*/,
164 const Slice
& /*begin_key*/, const Slice
& /*end_key*/,
165 const Slice
& /*ts*/) override
{
166 return Status::NotSupported(
167 "DeleteRange unsupported in WriteBatchWithIndex");
170 using WriteBatchBase::PutLogData
;
171 Status
PutLogData(const Slice
& blob
) override
;
173 using WriteBatchBase::Clear
;
174 void Clear() override
;
176 using WriteBatchBase::GetWriteBatch
;
177 WriteBatch
* GetWriteBatch() override
;
179 // Create an iterator of a column family. User can call iterator.Seek() to
180 // search to the next entry of or after a key. Keys will be iterated in the
181 // order given by index_comparator. For multiple updates on the same key,
182 // each update will be returned as a separate entry, in the order of update
185 // The returned iterator should be deleted by the caller.
186 WBWIIterator
* NewIterator(ColumnFamilyHandle
* column_family
);
187 // Create an iterator of the default column family.
188 WBWIIterator
* NewIterator();
190 // Will create a new Iterator that will use WBWIIterator as a delta and
191 // base_iterator as base.
193 // This function is only supported if the WriteBatchWithIndex was
194 // constructed with overwrite_key=true.
196 // The returned iterator should be deleted by the caller.
197 // The base_iterator is now 'owned' by the returned iterator. Deleting the
198 // returned iterator will also delete the base_iterator.
200 // Updating write batch with the current key of the iterator is not safe.
201 // We strongly recommend users not to do it. It will invalidate the current
202 // key() and value() of the iterator. This invalidation happens even before
203 // the write batch update finishes. The state may recover after Next() is
205 Iterator
* NewIteratorWithBase(ColumnFamilyHandle
* column_family
,
206 Iterator
* base_iterator
,
207 const ReadOptions
* opts
= nullptr);
208 // default column family
209 Iterator
* NewIteratorWithBase(Iterator
* base_iterator
);
211 // Similar to DB::Get() but will only read the key from this batch.
212 // If the batch does not have enough data to resolve Merge operations,
213 // MergeInProgress status may be returned.
214 Status
GetFromBatch(ColumnFamilyHandle
* column_family
,
215 const DBOptions
& options
, const Slice
& key
,
218 // Similar to previous function but does not require a column_family.
219 // Note: An InvalidArgument status will be returned if there are any Merge
220 // operators for this key. Use previous method instead.
221 Status
GetFromBatch(const DBOptions
& options
, const Slice
& key
,
222 std::string
* value
) {
223 return GetFromBatch(nullptr, options
, key
, value
);
226 // Similar to DB::Get() but will also read writes from this batch.
228 // This function will query both this batch and the DB and then merge
229 // the results using the DB's merge operator (if the batch contains any
232 // Setting read_options.snapshot will affect what is read from the DB
233 // but will NOT change which keys are read from the batch (the keys in
234 // this batch do not yet belong to any snapshot and will be fetched
236 Status
GetFromBatchAndDB(DB
* db
, const ReadOptions
& read_options
,
237 const Slice
& key
, std::string
* value
);
239 // An overload of the above method that receives a PinnableSlice
240 Status
GetFromBatchAndDB(DB
* db
, const ReadOptions
& read_options
,
241 const Slice
& key
, PinnableSlice
* value
);
243 Status
GetFromBatchAndDB(DB
* db
, const ReadOptions
& read_options
,
244 ColumnFamilyHandle
* column_family
, const Slice
& key
,
247 // An overload of the above method that receives a PinnableSlice
248 Status
GetFromBatchAndDB(DB
* db
, const ReadOptions
& read_options
,
249 ColumnFamilyHandle
* column_family
, const Slice
& key
,
250 PinnableSlice
* value
);
252 void MultiGetFromBatchAndDB(DB
* db
, const ReadOptions
& read_options
,
253 ColumnFamilyHandle
* column_family
,
254 const size_t num_keys
, const Slice
* keys
,
255 PinnableSlice
* values
, Status
* statuses
,
258 // Records the state of the batch for future calls to RollbackToSavePoint().
259 // May be called multiple times to set multiple save points.
260 void SetSavePoint() override
;
262 // Remove all entries in this batch (Put, Merge, Delete, SingleDelete,
263 // PutLogData) since the most recent call to SetSavePoint() and removes the
264 // most recent save point.
265 // If there is no previous call to SetSavePoint(), behaves the same as
268 // Calling RollbackToSavePoint invalidates any open iterators on this batch.
270 // Returns Status::OK() on success,
271 // Status::NotFound() if no previous call to SetSavePoint(),
272 // or other Status on corruption.
273 Status
RollbackToSavePoint() override
;
275 // Pop the most recent save point.
276 // If there is no previous call to SetSavePoint(), Status::NotFound()
278 // Otherwise returns Status::OK().
279 Status
PopSavePoint() override
;
281 void SetMaxBytes(size_t max_bytes
) override
;
282 size_t GetDataSize() const;
285 friend class PessimisticTransactionDB
;
286 friend class WritePreparedTxn
;
287 friend class WriteUnpreparedTxn
;
288 friend class WriteBatchWithIndex_SubBatchCnt_Test
;
289 friend class WriteBatchWithIndexInternal
;
290 // Returns the number of sub-batches inside the write batch. A sub-batch
291 // starts right before inserting a key that is a duplicate of a key in the
293 size_t SubBatchCnt();
295 Status
GetFromBatchAndDB(DB
* db
, const ReadOptions
& read_options
,
296 ColumnFamilyHandle
* column_family
, const Slice
& key
,
297 PinnableSlice
* value
, ReadCallback
* callback
);
298 void MultiGetFromBatchAndDB(DB
* db
, const ReadOptions
& read_options
,
299 ColumnFamilyHandle
* column_family
,
300 const size_t num_keys
, const Slice
* keys
,
301 PinnableSlice
* values
, Status
* statuses
,
302 bool sorted_input
, ReadCallback
* callback
);
304 std::unique_ptr
<Rep
> rep
;
307 } // namespace ROCKSDB_NAMESPACE
309 #endif // !ROCKSDB_LITE