[thin_show_dups] variable_chunk_stream
This commit is contained in:
152
thin-provisioning/variable_chunk_stream.cc
Normal file
152
thin-provisioning/variable_chunk_stream.cc
Normal file
@@ -0,0 +1,152 @@
|
||||
#include "thin-provisioning/variable_chunk_stream.h"
|
||||
|
||||
using namespace boost;
|
||||
using namespace std;
|
||||
using namespace thin_provisioning;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
variable_chunk_stream::variable_chunk_stream(chunk_stream &stream, unsigned window_size)
|
||||
: index_(0),
|
||||
h_(window_size),
|
||||
stream_(stream),
|
||||
big_chunk_(0) {
|
||||
next_big_chunk();
|
||||
}
|
||||
|
||||
variable_chunk_stream::~variable_chunk_stream()
|
||||
{
|
||||
put_big_chunk();
|
||||
}
|
||||
|
||||
void
|
||||
variable_chunk_stream::rewind()
|
||||
{
|
||||
// FIXME: not complete
|
||||
index_ = 0;
|
||||
stream_.rewind();
|
||||
h_.reset();
|
||||
}
|
||||
|
||||
bool
|
||||
variable_chunk_stream::next(bcache::block_address count)
|
||||
{
|
||||
while (count--) {
|
||||
index_++;
|
||||
advance_one();
|
||||
}
|
||||
|
||||
return !eof();
|
||||
}
|
||||
|
||||
bool
|
||||
variable_chunk_stream::eof() const
|
||||
{
|
||||
return stream_.eof();
|
||||
}
|
||||
|
||||
bcache::block_address
|
||||
variable_chunk_stream::index() const
|
||||
{
|
||||
return index_;
|
||||
}
|
||||
|
||||
chunk const &
|
||||
variable_chunk_stream::get()
|
||||
{
|
||||
assert(big_chunk_);
|
||||
|
||||
little_chunk_.len_ = little_e_ - little_b_;
|
||||
little_chunk_.offset_ = big_chunk_->offset_ + little_chunk_.len_;
|
||||
|
||||
little_chunk_.mem_.clear();
|
||||
little_chunk_.mem_.push_back(mem(little_b_, little_e_));
|
||||
|
||||
return little_chunk_;
|
||||
}
|
||||
|
||||
void
|
||||
variable_chunk_stream::put(chunk const &c)
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
bool
|
||||
variable_chunk_stream::next_big_chunk()
|
||||
{
|
||||
put_big_chunk();
|
||||
|
||||
if (!stream_.next())
|
||||
return false;
|
||||
|
||||
big_chunk_ = &stream_.get();
|
||||
little_b_ = little_e_ = big_chunk_->mem_.front().begin;
|
||||
h_.reset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
variable_chunk_stream::advance_one()
|
||||
{
|
||||
uint8_t *big_e;
|
||||
|
||||
assert(big_chunk_);
|
||||
|
||||
big_e = big_chunk_->mem_.front().end;
|
||||
little_b_ = little_e_;
|
||||
|
||||
if (little_b_ == big_e) {
|
||||
if (next_big_chunk())
|
||||
big_e = big_chunk_->mem_.front().end;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(little_e_ >= big_chunk_->mem_.front().begin);
|
||||
assert(little_b_ >= big_chunk_->mem_.front().begin);
|
||||
#if 1
|
||||
if (little_e_ > big_e) {
|
||||
cerr << "before -- little_e_: " << (void *) little_e_ << ", big_e: " << (void *) big_e << "\n";
|
||||
}
|
||||
#endif
|
||||
assert(little_e_ <= big_e);
|
||||
assert(little_b_ <= big_e);
|
||||
|
||||
|
||||
while (little_e_ != big_e) {
|
||||
optional<unsigned> maybe_break = h_.step(*little_e_);
|
||||
|
||||
if (maybe_break) {
|
||||
// The break is not neccessarily at the current
|
||||
// byte.
|
||||
little_e_ = little_b_ + *maybe_break;
|
||||
break;
|
||||
}
|
||||
|
||||
little_e_++;
|
||||
}
|
||||
|
||||
assert(little_e_ >= big_chunk_->mem_.front().begin);
|
||||
assert(little_b_ >= big_chunk_->mem_.front().begin);
|
||||
#if 1
|
||||
if (little_e_ > big_e) {
|
||||
cerr << "after -- little_e_: " << (void *) little_e_ << ", big_e: " << (void *) big_e << "\n";
|
||||
}
|
||||
#endif
|
||||
assert(little_e_ <= big_e);
|
||||
assert(little_b_ <= big_e);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
variable_chunk_stream::put_big_chunk()
|
||||
{
|
||||
if (big_chunk_)
|
||||
stream_.put(*big_chunk_);
|
||||
|
||||
big_chunk_ = 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
Reference in New Issue
Block a user