Summary: Adds three new WriteBatch data types: Prepare(xid), Commit(xid), Rollback(xid). Prepare(xid) should precede the (single) operation to which is applies. There can obviously be multiple Prepare(xid) markers. There should only be one Rollback(xid) or Commit(xid) marker yet not both. None of this logic is currently enforced and will most likely be implemented further up such as in the memtableinserter. All three markers are similar to PutLogData in that they are writebatch meta-data, ie stored but not counted. All three markers differ from PutLogData in that they will actually be written to disk. As for WriteBatchWithIndex, Prepare, Commit, Rollback are all implemented just as PutLogData and none are tested just as PutLogData. Test Plan: single unit test in write_batch_test. Reviewers: hermanlee4, sdong, anthony Subscribers: andrewkr, vasilep, dhruba, leveldb Differential Revision: https://reviews.facebook.net/D54093
114 lines
4.2 KiB
C++
114 lines
4.2 KiB
C++
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
|
// This source code is licensed under the BSD-style license found in the
|
|
// LICENSE file in the root directory of this source tree. An additional grant
|
|
// of patent rights can be found in the PATENTS file in the same directory.
|
|
#pragma once
|
|
|
|
#ifndef ROCKSDB_LITE
|
|
|
|
#include <limits>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "rocksdb/comparator.h"
|
|
#include "rocksdb/iterator.h"
|
|
#include "rocksdb/slice.h"
|
|
#include "rocksdb/status.h"
|
|
#include "rocksdb/utilities/write_batch_with_index.h"
|
|
#include "port/port.h"
|
|
|
|
namespace rocksdb {
|
|
|
|
class MergeContext;
|
|
struct Options;
|
|
|
|
// Key used by skip list, as the binary searchable index of WriteBatchWithIndex.
|
|
struct WriteBatchIndexEntry {
|
|
WriteBatchIndexEntry(size_t o, uint32_t c, size_t ko, size_t ksz)
|
|
: offset(o),
|
|
column_family(c),
|
|
key_offset(ko),
|
|
key_size(ksz),
|
|
search_key(nullptr) {}
|
|
WriteBatchIndexEntry(const Slice* sk, uint32_t c)
|
|
: offset(0),
|
|
column_family(c),
|
|
key_offset(0),
|
|
key_size(0),
|
|
search_key(sk) {}
|
|
|
|
// If this flag appears in the offset, it indicates a key that is smaller
|
|
// than any other entry for the same column family
|
|
static const size_t kFlagMin = port::kMaxSizet;
|
|
|
|
size_t offset; // offset of an entry in write batch's string buffer.
|
|
uint32_t column_family; // column family of the entry.
|
|
size_t key_offset; // offset of the key in write batch's string buffer.
|
|
size_t key_size; // size of the key.
|
|
|
|
const Slice* search_key; // if not null, instead of reading keys from
|
|
// write batch, use it to compare. This is used
|
|
// for lookup key.
|
|
};
|
|
|
|
class ReadableWriteBatch : public WriteBatch {
|
|
public:
|
|
explicit ReadableWriteBatch(size_t reserved_bytes = 0)
|
|
: WriteBatch(reserved_bytes) {}
|
|
// Retrieve some information from a write entry in the write batch, given
|
|
// the start offset of the write entry.
|
|
Status GetEntryFromDataOffset(size_t data_offset, WriteType* type, Slice* Key,
|
|
Slice* value, Slice* blob, Slice* xid) const;
|
|
};
|
|
|
|
class WriteBatchEntryComparator {
|
|
public:
|
|
WriteBatchEntryComparator(const Comparator* _default_comparator,
|
|
const ReadableWriteBatch* write_batch)
|
|
: default_comparator_(_default_comparator), write_batch_(write_batch) {}
|
|
// Compare a and b. Return a negative value if a is less than b, 0 if they
|
|
// are equal, and a positive value if a is greater than b
|
|
int operator()(const WriteBatchIndexEntry* entry1,
|
|
const WriteBatchIndexEntry* entry2) const;
|
|
|
|
int CompareKey(uint32_t column_family, const Slice& key1,
|
|
const Slice& key2) const;
|
|
|
|
void SetComparatorForCF(uint32_t column_family_id,
|
|
const Comparator* comparator) {
|
|
if (column_family_id >= cf_comparators_.size()) {
|
|
cf_comparators_.resize(column_family_id + 1, nullptr);
|
|
}
|
|
cf_comparators_[column_family_id] = comparator;
|
|
}
|
|
|
|
const Comparator* default_comparator() { return default_comparator_; }
|
|
|
|
private:
|
|
const Comparator* default_comparator_;
|
|
std::vector<const Comparator*> cf_comparators_;
|
|
const ReadableWriteBatch* write_batch_;
|
|
};
|
|
|
|
class WriteBatchWithIndexInternal {
|
|
public:
|
|
enum Result { kFound, kDeleted, kNotFound, kMergeInProgress, kError };
|
|
|
|
// If batch contains a value for key, store it in *value and return kFound.
|
|
// If batch contains a deletion for key, return Deleted.
|
|
// If batch contains Merge operations as the most recent entry for a key,
|
|
// and the merge process does not stop (not reaching a value or delete),
|
|
// prepend the current merge operands to *operands,
|
|
// and return kMergeInProgress
|
|
// If batch does not contain this key, return kNotFound
|
|
// Else, return kError on error with error Status stored in *s.
|
|
static WriteBatchWithIndexInternal::Result GetFromBatch(
|
|
const DBOptions& options, WriteBatchWithIndex* batch,
|
|
ColumnFamilyHandle* column_family, const Slice& key,
|
|
MergeContext* merge_context, WriteBatchEntryComparator* cmp,
|
|
std::string* value, bool overwrite_key, Status* s);
|
|
};
|
|
|
|
} // namespace rocksdb
|
|
#endif // !ROCKSDB_LITE
|