diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2014-07-14 17:33:12 +1000 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2014-07-14 17:33:12 +1000 |
commit | 3842d5a653763bea4dc37e212d0bb755fd97d29a (patch) | |
tree | 6ee31972516fd874494baeabbfdc45bb41b9a9da /api | |
parent | 846822379ae9f54d5edbf9bf2e8139141f456676 (diff) | |
download | mongo-3842d5a653763bea4dc37e212d0bb755fd97d29a.tar.gz |
Split out the RocksDB write batch code into a separate file to avoid copyright ambiguity. Update the docs to mention Facebook copyright.
--HG--
rename : api/leveldb/db/write_batch.cc => api/leveldb/rocksdb/write_batch.cc
Diffstat (limited to 'api')
-rw-r--r-- | api/leveldb/Makefile.am | 5 | ||||
-rw-r--r-- | api/leveldb/db/write_batch.cc | 278 | ||||
-rw-r--r-- | api/leveldb/rocksdb/PATENTS | 23 | ||||
-rw-r--r-- | api/leveldb/rocksdb/write_batch.cc | 275 |
4 files changed, 301 insertions, 280 deletions
diff --git a/api/leveldb/Makefile.am b/api/leveldb/Makefile.am index b730da30e76..0d5b5040a95 100644 --- a/api/leveldb/Makefile.am +++ b/api/leveldb/Makefile.am @@ -41,7 +41,6 @@ libwiredtiger_leveldb_la_LDFLAGS = -release @VERSION@ libwiredtiger_leveldb_la_LIBADD = $(top_builddir)/libwiredtiger.la libwiredtiger_leveldb_la_SOURCES = \ leveldb_wt.cc \ - db/write_batch.cc \ util/coding.cc util/comparator.cc util/env.cc util/env_posix.cc \ util/logging.cc util/options.cc util/status.cc @@ -49,7 +48,9 @@ if HAVE_ELEVELDB libwiredtiger_leveldb_la_SOURCES += util/perf_count.cc endif if HAVE_ROCKSDB -libwiredtiger_leveldb_la_SOURCES += rocks_wt.cc +libwiredtiger_leveldb_la_SOURCES += rocks_wt.cc rocksdb/write_batch.cc +else +libwiredtiger_leveldb_la_SOURCES += db/write_batch.cc endif if HAVE_ROCKSDB diff --git a/api/leveldb/db/write_batch.cc b/api/leveldb/db/write_batch.cc index 3edb187f796..0a11cb10f33 100644 --- a/api/leveldb/db/write_batch.cc +++ b/api/leveldb/db/write_batch.cc @@ -17,8 +17,6 @@ #include "db/write_batch_internal.h" -#ifndef HAVE_ROCKSDB - namespace leveldb { // WriteBatch header has an 8-byte sequence number followed by a 4-byte count. @@ -110,279 +108,3 @@ void WriteBatchInternal::Append(WriteBatch* dst, const WriteBatch* src) { } } // namespace leveldb - -#else // HAVE_ROCKSDB - -// Copyright (c) 2013, 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. -// -// Copyright (c) 2011 The LevelDB Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. See the AUTHORS file for names of contributors. -// -// WriteBatch::rep_ := -// sequence: fixed64 -// count: fixed32 -// data: record[count] -// record := -// kTypeValue varstring varstring -// kTypeMerge varstring varstring -// kTypeDeletion varstring -// kTypeColumnFamilyValue varint32 varstring varstring -// kTypeColumnFamilyMerge varint32 varstring varstring -// kTypeColumnFamilyDeletion varint32 varstring varstring -// varstring := -// len: varint32 -// data: uint8[len] - -#include <stdexcept> - -namespace rocksdb { - -// WriteBatch header has an 8-byte sequence number followed by a 4-byte count. -static const size_t kHeader = 12; - -WriteBatch::WriteBatch(size_t reserved_bytes) { - rep_.reserve((reserved_bytes > kHeader) ? reserved_bytes : kHeader); - Clear(); -} - -WriteBatch::~WriteBatch() { } - -WriteBatch::Handler::~Handler() { } - -void WriteBatch::Handler::Put(const Slice& key, const Slice& value) { - // you need to either implement Put or PutCF - throw std::runtime_error("Handler::Put not implemented!"); -} - -#ifdef NOT_YET -void WriteBatch::Handler::Merge(const Slice& key, const Slice& value) { - throw std::runtime_error("Handler::Merge not implemented!"); -} -#endif - -void WriteBatch::Handler::Delete(const Slice& key) { - // you need to either implement Delete or DeleteCF - throw std::runtime_error("Handler::Delete not implemented!"); -} - -#ifdef NOT_YET -void WriteBatch::Handler::LogData(const Slice& blob) { - // If the user has not specified something to do with blobs, then we ignore - // them. -} -#endif - -bool WriteBatch::Handler::Continue() { - return true; -} - -void WriteBatch::Clear() { - rep_.clear(); - rep_.resize(kHeader); -} - -int WriteBatch::Count() const { - return WriteBatchInternal::Count(this); -} - -Status WriteBatch::Iterate(Handler* handler) const { - Slice input(rep_); - if (input.size() < kHeader) { - return Status::Corruption("malformed WriteBatch (too small)"); - } - - input.remove_prefix(kHeader); - Slice key, value, blob; - int found = 0; - Status s; - while (s.ok() && !input.empty() && handler->Continue()) { - char tag = input[0]; - input.remove_prefix(1); - uint32_t column_family = 0; // default - switch (tag) { - case kTypeColumnFamilyValue: - if (!GetVarint32(&input, &column_family)) { - return Status::Corruption("bad WriteBatch Put"); - } - // intentional fallthrough - case kTypeValue: - if (GetLengthPrefixedSlice(&input, &key) && - GetLengthPrefixedSlice(&input, &value)) { - s = handler->PutCF(column_family, key, value); - found++; - } else { - return Status::Corruption("bad WriteBatch Put"); - } - break; - case kTypeColumnFamilyDeletion: - if (!GetVarint32(&input, &column_family)) { - return Status::Corruption("bad WriteBatch Delete"); - } - // intentional fallthrough - case kTypeDeletion: - if (GetLengthPrefixedSlice(&input, &key)) { - s = handler->DeleteCF(column_family, key); - found++; - } else { - return Status::Corruption("bad WriteBatch Delete"); - } - break; - case kTypeColumnFamilyMerge: - if (!GetVarint32(&input, &column_family)) { - return Status::Corruption("bad WriteBatch Merge"); - } - // intentional fallthrough - case kTypeMerge: - if (GetLengthPrefixedSlice(&input, &key) && - GetLengthPrefixedSlice(&input, &value)) { - s = handler->MergeCF(column_family, key, value); - found++; - } else { - return Status::Corruption("bad WriteBatch Merge"); - } - break; - case kTypeLogData: - if (GetLengthPrefixedSlice(&input, &blob)) { - handler->LogData(blob); - } else { - return Status::Corruption("bad WriteBatch Blob"); - } - break; - default: - return Status::Corruption("unknown WriteBatch tag"); - } - } - if (!s.ok()) { - return s; - } - if (found != WriteBatchInternal::Count(this)) { - return Status::Corruption("WriteBatch has wrong count"); - } else { - return Status::OK(); - } -} - -int WriteBatchInternal::Count(const WriteBatch* b) { - return DecodeFixed32(b->rep_.data() + 8); -} - -void WriteBatchInternal::SetCount(WriteBatch* b, int n) { - EncodeFixed32(&b->rep_[8], n); -} - -#ifdef NOT_YET -SequenceNumber WriteBatchInternal::Sequence(const WriteBatch* b) { - return SequenceNumber(DecodeFixed64(b->rep_.data())); -} - -void WriteBatchInternal::SetSequence(WriteBatch* b, SequenceNumber seq) { - EncodeFixed64(&b->rep_[0], seq); -} -#endif - -void WriteBatchInternal::Put(WriteBatch* b, uint32_t column_family_id, - const Slice& key, const Slice& value) { - WriteBatchInternal::SetCount(b, WriteBatchInternal::Count(b) + 1); - if (column_family_id == 0) { - b->rep_.push_back(static_cast<char>(kTypeValue)); - } else { - b->rep_.push_back(static_cast<char>(kTypeColumnFamilyValue)); - PutVarint32(&b->rep_, column_family_id); - } - PutLengthPrefixedSlice(&b->rep_, key); - PutLengthPrefixedSlice(&b->rep_, value); -} - -namespace { -inline uint32_t GetColumnFamilyID(ColumnFamilyHandle* column_family) { - uint32_t column_family_id = 0; - if (column_family != NULL) { - ColumnFamilyHandleImpl *cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); - column_family_id = cfh->GetID(); - } - return column_family_id; -} -} // namespace - -void WriteBatch::Put(ColumnFamilyHandle* column_family, const Slice& key, - const Slice& value) { - WriteBatchInternal::Put(this, GetColumnFamilyID(column_family), key, value); -} - -void WriteBatchInternal::Put(WriteBatch* b, uint32_t column_family_id, - const SliceParts& key, const SliceParts& value) { - WriteBatchInternal::SetCount(b, WriteBatchInternal::Count(b) + 1); - if (column_family_id == 0) { - b->rep_.push_back(static_cast<char>(kTypeValue)); - } else { - b->rep_.push_back(static_cast<char>(kTypeColumnFamilyValue)); - PutVarint32(&b->rep_, column_family_id); - } - PutLengthPrefixedSliceParts(&b->rep_, key); - PutLengthPrefixedSliceParts(&b->rep_, value); -} - -void WriteBatch::Put(ColumnFamilyHandle* column_family, const SliceParts& key, - const SliceParts& value) { - WriteBatchInternal::Put(this, GetColumnFamilyID(column_family), key, value); -} - -void WriteBatchInternal::Delete(WriteBatch* b, uint32_t column_family_id, - const Slice& key) { - WriteBatchInternal::SetCount(b, WriteBatchInternal::Count(b) + 1); - if (column_family_id == 0) { - b->rep_.push_back(static_cast<char>(kTypeDeletion)); - } else { - b->rep_.push_back(static_cast<char>(kTypeColumnFamilyDeletion)); - PutVarint32(&b->rep_, column_family_id); - } - PutLengthPrefixedSlice(&b->rep_, key); -} - -void WriteBatch::Delete(ColumnFamilyHandle* column_family, const Slice& key) { - WriteBatchInternal::Delete(this, GetColumnFamilyID(column_family), key); -} - -#ifdef NOT_YET -void WriteBatchInternal::Merge(WriteBatch* b, uint32_t column_family_id, - const Slice& key, const Slice& value) { - WriteBatchInternal::SetCount(b, WriteBatchInternal::Count(b) + 1); - if (column_family_id == 0) { - b->rep_.push_back(static_cast<char>(kTypeMerge)); - } else { - b->rep_.push_back(static_cast<char>(kTypeColumnFamilyMerge)); - PutVarint32(&b->rep_, column_family_id); - } - PutLengthPrefixedSlice(&b->rep_, key); - PutLengthPrefixedSlice(&b->rep_, value); -} - -void WriteBatch::Merge(ColumnFamilyHandle* column_family, const Slice& key, - const Slice& value) { - WriteBatchInternal::Merge(this, GetColumnFamilyID(column_family), key, value); -} - -void WriteBatch::PutLogData(const Slice& blob) { - rep_.push_back(static_cast<char>(kTypeLogData)); - PutLengthPrefixedSlice(&rep_, blob); -} -#endif - -void WriteBatchInternal::SetContents(WriteBatch* b, const Slice& contents) { - assert(contents.size() >= kHeader); - b->rep_.assign(contents.data(), contents.size()); -} - -void WriteBatchInternal::Append(WriteBatch* dst, const WriteBatch* src) { - SetCount(dst, Count(dst) + Count(src)); - assert(src->rep_.size() >= kHeader); - dst->rep_.append(src->rep_.data() + kHeader, src->rep_.size() - kHeader); -} - -} // namespace rocksdb - -#endif diff --git a/api/leveldb/rocksdb/PATENTS b/api/leveldb/rocksdb/PATENTS new file mode 100644 index 00000000000..8a6fca4d2ba --- /dev/null +++ b/api/leveldb/rocksdb/PATENTS @@ -0,0 +1,23 @@ +Additional Grant of Patent Rights + +“Software” means the rocksdb software distributed by Facebook, Inc. + +Facebook hereby grants you a perpetual, worldwide, royalty-free, +non-exclusive, irrevocable (subject to the termination provision below) +license under any rights in any patent claims owned by Facebook, to make, +have made, use, sell, offer to sell, import, and otherwise transfer the +Software. For avoidance of doubt, no license is granted under Facebook’s +rights in any patent claims that are infringed by (i) modifications to the +Software made by you or a third party, or (ii) the Software in combination +with any software or other technology provided by you or a third party. + +The license granted hereunder will terminate, automatically and without +notice, for anyone that makes any claim (including by filing any lawsuit, +assertion or other action) alleging (a) direct, indirect, or contributory +infringement or inducement to infringe any patent: (i) by Facebook or any +of its subsidiaries or affiliates, whether or not such claim is related +to the Software, (ii) by any party if such claim arises in whole or in +part from any software, product or service of Facebook or any of its +subsidiaries or affiliates, whether or not such claim is related to the +Software, or (iii) by any party relating to the Software; or (b) that +any right in any patent claim of Facebook is invalid or unenforceable. diff --git a/api/leveldb/rocksdb/write_batch.cc b/api/leveldb/rocksdb/write_batch.cc new file mode 100644 index 00000000000..aa7a3d239f9 --- /dev/null +++ b/api/leveldb/rocksdb/write_batch.cc @@ -0,0 +1,275 @@ +// Copyright (c) 2013, 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. +// +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// WriteBatch::rep_ := +// sequence: fixed64 +// count: fixed32 +// data: record[count] +// record := +// kTypeValue varstring varstring +// kTypeMerge varstring varstring +// kTypeDeletion varstring +// kTypeColumnFamilyValue varint32 varstring varstring +// kTypeColumnFamilyMerge varint32 varstring varstring +// kTypeColumnFamilyDeletion varint32 varstring varstring +// varstring := +// len: varint32 +// data: uint8[len] + +#include "leveldb_wt.h" + +#include "db/write_batch_internal.h" + +#include <stdexcept> + +namespace rocksdb { + +// WriteBatch header has an 8-byte sequence number followed by a 4-byte count. +static const size_t kHeader = 12; + +WriteBatch::WriteBatch(size_t reserved_bytes) { + rep_.reserve((reserved_bytes > kHeader) ? reserved_bytes : kHeader); + Clear(); +} + +WriteBatch::~WriteBatch() { } + +WriteBatch::Handler::~Handler() { } + +void WriteBatch::Handler::Put(const Slice& key, const Slice& value) { + // you need to either implement Put or PutCF + throw std::runtime_error("Handler::Put not implemented!"); +} + +#ifdef NOT_YET +void WriteBatch::Handler::Merge(const Slice& key, const Slice& value) { + throw std::runtime_error("Handler::Merge not implemented!"); +} +#endif + +void WriteBatch::Handler::Delete(const Slice& key) { + // you need to either implement Delete or DeleteCF + throw std::runtime_error("Handler::Delete not implemented!"); +} + +#ifdef NOT_YET +void WriteBatch::Handler::LogData(const Slice& blob) { + // If the user has not specified something to do with blobs, then we ignore + // them. +} +#endif + +bool WriteBatch::Handler::Continue() { + return true; +} + +void WriteBatch::Clear() { + rep_.clear(); + rep_.resize(kHeader); +} + +int WriteBatch::Count() const { + return WriteBatchInternal::Count(this); +} + +Status WriteBatch::Iterate(Handler* handler) const { + Slice input(rep_); + if (input.size() < kHeader) { + return Status::Corruption("malformed WriteBatch (too small)"); + } + + input.remove_prefix(kHeader); + Slice key, value, blob; + int found = 0; + Status s; + while (s.ok() && !input.empty() && handler->Continue()) { + char tag = input[0]; + input.remove_prefix(1); + uint32_t column_family = 0; // default + switch (tag) { + case kTypeColumnFamilyValue: + if (!GetVarint32(&input, &column_family)) { + return Status::Corruption("bad WriteBatch Put"); + } + // intentional fallthrough + case kTypeValue: + if (GetLengthPrefixedSlice(&input, &key) && + GetLengthPrefixedSlice(&input, &value)) { + s = handler->PutCF(column_family, key, value); + found++; + } else { + return Status::Corruption("bad WriteBatch Put"); + } + break; + case kTypeColumnFamilyDeletion: + if (!GetVarint32(&input, &column_family)) { + return Status::Corruption("bad WriteBatch Delete"); + } + // intentional fallthrough + case kTypeDeletion: + if (GetLengthPrefixedSlice(&input, &key)) { + s = handler->DeleteCF(column_family, key); + found++; + } else { + return Status::Corruption("bad WriteBatch Delete"); + } + break; + case kTypeColumnFamilyMerge: + if (!GetVarint32(&input, &column_family)) { + return Status::Corruption("bad WriteBatch Merge"); + } + // intentional fallthrough + case kTypeMerge: + if (GetLengthPrefixedSlice(&input, &key) && + GetLengthPrefixedSlice(&input, &value)) { + s = handler->MergeCF(column_family, key, value); + found++; + } else { + return Status::Corruption("bad WriteBatch Merge"); + } + break; + case kTypeLogData: + if (GetLengthPrefixedSlice(&input, &blob)) { + handler->LogData(blob); + } else { + return Status::Corruption("bad WriteBatch Blob"); + } + break; + default: + return Status::Corruption("unknown WriteBatch tag"); + } + } + if (!s.ok()) { + return s; + } + if (found != WriteBatchInternal::Count(this)) { + return Status::Corruption("WriteBatch has wrong count"); + } else { + return Status::OK(); + } +} + +int WriteBatchInternal::Count(const WriteBatch* b) { + return DecodeFixed32(b->rep_.data() + 8); +} + +void WriteBatchInternal::SetCount(WriteBatch* b, int n) { + EncodeFixed32(&b->rep_[8], n); +} + +#ifdef NOT_YET +SequenceNumber WriteBatchInternal::Sequence(const WriteBatch* b) { + return SequenceNumber(DecodeFixed64(b->rep_.data())); +} + +void WriteBatchInternal::SetSequence(WriteBatch* b, SequenceNumber seq) { + EncodeFixed64(&b->rep_[0], seq); +} +#endif + +void WriteBatchInternal::Put(WriteBatch* b, uint32_t column_family_id, + const Slice& key, const Slice& value) { + WriteBatchInternal::SetCount(b, WriteBatchInternal::Count(b) + 1); + if (column_family_id == 0) { + b->rep_.push_back(static_cast<char>(kTypeValue)); + } else { + b->rep_.push_back(static_cast<char>(kTypeColumnFamilyValue)); + PutVarint32(&b->rep_, column_family_id); + } + PutLengthPrefixedSlice(&b->rep_, key); + PutLengthPrefixedSlice(&b->rep_, value); +} + +namespace { +inline uint32_t GetColumnFamilyID(ColumnFamilyHandle* column_family) { + uint32_t column_family_id = 0; + if (column_family != NULL) { + ColumnFamilyHandleImpl *cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family); + column_family_id = cfh->GetID(); + } + return column_family_id; +} +} // namespace + +void WriteBatch::Put(ColumnFamilyHandle* column_family, const Slice& key, + const Slice& value) { + WriteBatchInternal::Put(this, GetColumnFamilyID(column_family), key, value); +} + +void WriteBatchInternal::Put(WriteBatch* b, uint32_t column_family_id, + const SliceParts& key, const SliceParts& value) { + WriteBatchInternal::SetCount(b, WriteBatchInternal::Count(b) + 1); + if (column_family_id == 0) { + b->rep_.push_back(static_cast<char>(kTypeValue)); + } else { + b->rep_.push_back(static_cast<char>(kTypeColumnFamilyValue)); + PutVarint32(&b->rep_, column_family_id); + } + PutLengthPrefixedSliceParts(&b->rep_, key); + PutLengthPrefixedSliceParts(&b->rep_, value); +} + +void WriteBatch::Put(ColumnFamilyHandle* column_family, const SliceParts& key, + const SliceParts& value) { + WriteBatchInternal::Put(this, GetColumnFamilyID(column_family), key, value); +} + +void WriteBatchInternal::Delete(WriteBatch* b, uint32_t column_family_id, + const Slice& key) { + WriteBatchInternal::SetCount(b, WriteBatchInternal::Count(b) + 1); + if (column_family_id == 0) { + b->rep_.push_back(static_cast<char>(kTypeDeletion)); + } else { + b->rep_.push_back(static_cast<char>(kTypeColumnFamilyDeletion)); + PutVarint32(&b->rep_, column_family_id); + } + PutLengthPrefixedSlice(&b->rep_, key); +} + +void WriteBatch::Delete(ColumnFamilyHandle* column_family, const Slice& key) { + WriteBatchInternal::Delete(this, GetColumnFamilyID(column_family), key); +} + +#ifdef NOT_YET +void WriteBatchInternal::Merge(WriteBatch* b, uint32_t column_family_id, + const Slice& key, const Slice& value) { + WriteBatchInternal::SetCount(b, WriteBatchInternal::Count(b) + 1); + if (column_family_id == 0) { + b->rep_.push_back(static_cast<char>(kTypeMerge)); + } else { + b->rep_.push_back(static_cast<char>(kTypeColumnFamilyMerge)); + PutVarint32(&b->rep_, column_family_id); + } + PutLengthPrefixedSlice(&b->rep_, key); + PutLengthPrefixedSlice(&b->rep_, value); +} + +void WriteBatch::Merge(ColumnFamilyHandle* column_family, const Slice& key, + const Slice& value) { + WriteBatchInternal::Merge(this, GetColumnFamilyID(column_family), key, value); +} + +void WriteBatch::PutLogData(const Slice& blob) { + rep_.push_back(static_cast<char>(kTypeLogData)); + PutLengthPrefixedSlice(&rep_, blob); +} +#endif + +void WriteBatchInternal::SetContents(WriteBatch* b, const Slice& contents) { + assert(contents.size() >= kHeader); + b->rep_.assign(contents.data(), contents.size()); +} + +void WriteBatchInternal::Append(WriteBatch* dst, const WriteBatch* src) { + SetCount(dst, Count(dst) + Count(src)); + assert(src->rep_.size() >= kHeader); + dst->rep_.append(src->rep_.data() + kHeader, src->rep_.size() - kHeader); +} + +} // namespace rocksdb |