write_batch

来源:互联网 发布:美国房地产市场数据 编辑:程序博客网 时间:2024/06/02 03:47
// 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 holds a collection of updates to apply atomically to a DB.//// The updates are applied in the order in which they are added// to the WriteBatch.  For example, the value of "key" will be "v3"// after the following batch is written:////    batch.Put("key", "v1");//    batch.Delete("key");//    batch.Put("key", "v2");//    batch.Put("key", "v3");//// Multiple threads can invoke const methods on a WriteBatch without// external synchronization, but if any of the threads may call a// non-const method, all threads accessing the same WriteBatch must use// external synchronization.#ifndef STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_#define STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_#include <string>#include "leveldb/status.h"namespace leveldb {class Slice;class WriteBatch{public:WriteBatch();~WriteBatch();// Store the mapping "key->value" in the database.void Put(const Slicekeyconst Slice& value);// If the database contains a mapping for "key", erase it.  Else do nothing.void Delete(const Slicekey);// Clear all updates buffered in this batch.void Clear();// Support for iterating over the contents of a batch.class Handler {public:virtual ~Handler();virtual void Put(const Slicekeyconst Slice& value) = 0;virtual void Delete(const Slicekey) = 0;};Status Iterate(Handler* handler) const;private:friend class WriteBatchInternal;std::string rep_;  // See comment in write_batch.cc for the format of rep_// Intentionally copyable};}  // namespace leveldb#endif  // STORAGE_LEVELDB_INCLUDE_WRITE_BATCH_H_
// 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         |//    kTypeDeletion varstring// varstring :=//    len: varint32//    data: uint8[len]#include "leveldb/write_batch.h"#include "leveldb/db.h"#include "db/dbformat.h"#include "db/memtable.h"#include "db/write_batch_internal.h"#include "util/coding.h"namespace leveldb {// WriteBatch header has an 8-byte sequence number followed by a 4-byte count.// 头8个字节为uint 64 位的sequence序列号,后面是4个字节的数量字段 countstatic const size_t kHeader = 12;WriteBatch::WriteBatch() {Clear();}WriteBatch::~WriteBatch() {}WriteBatch::Handler::~Handler(){ }void WriteBatch::Clear() {rep_.clear();rep_.resize( kHeader );}Status WriteBatch::IterateHandler* handler ) const {Slice input( rep_ );if ( input.size() < kHeader ) {return Status::Corruption("malformed WriteBatch (too small)");}input.remove_prefix( kHeader );Slice key, value;int found = 0;while ( !input.empty() ) {found++;// record格式,第一个字节为tagchar tag = input[0];input.remove_prefix(1);switch ( tag ){case kTypeValue:if ( GetLengthPrefixedSlice(&input, &key) &&GetLengthPrefixedSlice(&input, &value) ){handler->Putkey, value );}else{return Status::Corruption("bad WriteBatch Put");}break;case kTypeDeletion:if ( GetLengthPrefixedSlice( &input, &key ) ){handler->Deletekey );} else {return Status::Corruption("bad WriteBatch Delete");}break;default:return Status::Corruption("unknown WriteBatch tag");}}if ( found != WriteBatchInternal::Countthis ) ){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 );}SequenceNumber WriteBatchInternal::Sequenceconst WriteBatch* b ){return SequenceNumberDecodeFixed64(b->rep_.data()) );}void WriteBatchInternal::SetSequenceWriteBatch* b, SequenceNumber seq ) {EncodeFixed64(&b->rep_[0], seq);}void WriteBatch::Putconst Slicekeyconst Slice& value ) {WriteBatchInternal::SetCountthisWriteBatchInternal::Count(this) + 1 );rep_.push_back( static_cast<char>(kTypeValue) );PutLengthPrefixedSlice( &rep_, key );PutLengthPrefixedSlice( &rep_, value );}void WriteBatch::Deleteconst Slicekey ) {WriteBatchInternal::SetCountthisWriteBatchInternal::Count(this) + 1 );rep_.push_back( static_cast<char>(kTypeDeletion) );PutLengthPrefixedSlice( &rep_, key );}namespace{class MemTableInserter : public WriteBatch::Handler{public:SequenceNumber sequence_;MemTable* mem_;virtual void Putconst Slicekeyconst Slice& value ) {mem_->Add( sequence_, kTypeValuekey, value );sequence_++;}virtual void Delete(const Slicekey) {mem_->Add( sequence_, kTypeDeletionkeySlice() );sequence_++;}};}  // namespaceStatus WriteBatchInternal::InsertIntoconst WriteBatch* b,MemTable* memtable ){MemTableInserter inserter;inserter.sequence_ = WriteBatchInternal::Sequence(b);inserter.mem_ = memtable;return b->Iterate( &inserter );}void WriteBatchInternal::SetContentsWriteBatch* b, const Slice& contents ){assert( contents.size() >= kHeader );b->rep_.assign( contents.data(), contents.size() );}void WriteBatchInternal::AppendWriteBatch* 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 leveldb
原创粉丝点击