write_batch

// 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个字节的数量字段 count
	static 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格式,第一个字节为tag
			char 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_++;
			}
		};
	}  // namespace

	Status 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值