[thin_show_dups] Support fractions of a pool block size
This commit is contained in:
parent
c58c15e788
commit
664841ad03
@ -75,6 +75,7 @@ SOURCE=\
|
||||
thin-provisioning/cache_stream.cc \
|
||||
thin-provisioning/chunk_stream.cc \
|
||||
thin-provisioning/device_tree.cc \
|
||||
thin-provisioning/fixed_chunk_stream.cc \
|
||||
thin-provisioning/human_readable_format.cc \
|
||||
thin-provisioning/mapping_tree.cc \
|
||||
thin-provisioning/metadata.cc \
|
||||
|
113
thin-provisioning/fixed_chunk_stream.cc
Normal file
113
thin-provisioning/fixed_chunk_stream.cc
Normal file
@ -0,0 +1,113 @@
|
||||
#include "thin-provisioning/fixed_chunk_stream.h"
|
||||
|
||||
using namespace thin_provisioning;
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
fixed_chunk_stream::fixed_chunk_stream(chunk_stream &stream, unsigned chunk_size)
|
||||
: index_(0),
|
||||
stream_(stream),
|
||||
chunk_size_(chunk_size),
|
||||
big_chunk_(0) {
|
||||
next_big_chunk();
|
||||
}
|
||||
|
||||
fixed_chunk_stream::~fixed_chunk_stream()
|
||||
{
|
||||
put_big_chunk();
|
||||
}
|
||||
|
||||
bcache::block_address
|
||||
fixed_chunk_stream::size() const
|
||||
{
|
||||
return stream_.size();
|
||||
}
|
||||
|
||||
void
|
||||
fixed_chunk_stream::rewind()
|
||||
{
|
||||
// FIXME: not complete
|
||||
index_ = 0;
|
||||
stream_.rewind();
|
||||
}
|
||||
|
||||
bool
|
||||
fixed_chunk_stream::next(bcache::block_address count)
|
||||
{
|
||||
while (count--) {
|
||||
index_++;
|
||||
advance_one();
|
||||
}
|
||||
|
||||
return !eof();
|
||||
}
|
||||
|
||||
bool
|
||||
fixed_chunk_stream::eof() const
|
||||
{
|
||||
return stream_.eof();
|
||||
}
|
||||
|
||||
chunk const &
|
||||
fixed_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_.begin = little_b_;
|
||||
little_chunk_.mem_.end = little_e_;
|
||||
|
||||
return little_chunk_;
|
||||
}
|
||||
|
||||
void
|
||||
fixed_chunk_stream::put(chunk const &c)
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
bool
|
||||
fixed_chunk_stream::next_big_chunk()
|
||||
{
|
||||
put_big_chunk();
|
||||
|
||||
if (!stream_.next())
|
||||
return false;
|
||||
|
||||
big_chunk_ = &stream_.get();
|
||||
little_b_ = little_e_ = last_hashed_ = big_chunk_->mem_.begin;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
fixed_chunk_stream::advance_one()
|
||||
{
|
||||
uint8_t *big_e;
|
||||
|
||||
big_e = big_chunk_->mem_.end;
|
||||
little_b_ = little_e_;
|
||||
|
||||
if (little_b_ >= big_e) {
|
||||
if (next_big_chunk())
|
||||
big_e = big_chunk_->mem_.end;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
little_e_ += chunk_size_;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
fixed_chunk_stream::put_big_chunk()
|
||||
{
|
||||
if (big_chunk_)
|
||||
stream_.put(*big_chunk_);
|
||||
|
||||
big_chunk_ = 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
39
thin-provisioning/fixed_chunk_stream.h
Normal file
39
thin-provisioning/fixed_chunk_stream.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef THIN_PROVISIONING_FIXED_CHUNK_STREAM_H
|
||||
#define THIN_PROVISIONING_FIXED_CHUNK_STREAM_H
|
||||
|
||||
#include "thin-provisioning/chunk_stream.h"
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
namespace thin_provisioning {
|
||||
class fixed_chunk_stream : public chunk_stream {
|
||||
public:
|
||||
fixed_chunk_stream(chunk_stream &stream, unsigned chunk_size);
|
||||
~fixed_chunk_stream();
|
||||
|
||||
virtual bcache::block_address size() const;
|
||||
virtual void rewind();
|
||||
virtual bool next(bcache::block_address count = 1ull);
|
||||
virtual bool eof() const;
|
||||
virtual chunk const &get();
|
||||
virtual void put(chunk const &c);
|
||||
|
||||
private:
|
||||
bool next_big_chunk();
|
||||
bool advance_one();
|
||||
void put_big_chunk();
|
||||
|
||||
bcache::block_address index_;
|
||||
|
||||
chunk_stream &stream_;
|
||||
unsigned chunk_size_;
|
||||
chunk const *big_chunk_;
|
||||
|
||||
uint8_t *little_b_, *little_e_, *last_hashed_;
|
||||
chunk little_chunk_;
|
||||
};
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
||||
#endif
|
@ -30,6 +30,7 @@
|
||||
#include "persistent-data/space-maps/core.h"
|
||||
#include "persistent-data/space-maps/disk.h"
|
||||
#include "thin-provisioning/cache_stream.h"
|
||||
#include "thin-provisioning/fixed_chunk_stream.h"
|
||||
#include "thin-provisioning/pool_stream.h"
|
||||
#include "thin-provisioning/commands.h"
|
||||
#include "thin-provisioning/device_tree.h"
|
||||
@ -54,7 +55,6 @@ using namespace thin_provisioning;
|
||||
|
||||
namespace {
|
||||
bool factor_of(block_address f, block_address n) {
|
||||
cerr << n << " % " << f << "\n";
|
||||
return (n % f) == 0;
|
||||
}
|
||||
|
||||
@ -145,6 +145,21 @@ namespace {
|
||||
|
||||
class duplicate_detector {
|
||||
public:
|
||||
void scan_with_variable_sized_chunks(chunk_stream &stream) {
|
||||
variable_chunk_stream vstream(stream, 4096);
|
||||
scan(vstream);
|
||||
}
|
||||
|
||||
void scan_with_fixed_sized_chunks(chunk_stream &stream, block_address chunk_size) {
|
||||
fixed_chunk_stream fstream(stream, chunk_size);
|
||||
scan(fstream);
|
||||
}
|
||||
|
||||
duplicate_counter const &get_results() const {
|
||||
return results_;
|
||||
}
|
||||
|
||||
private:
|
||||
void scan(chunk_stream &stream) {
|
||||
block_address total_seen(0);
|
||||
auto_ptr<progress_monitor> pbar = create_progress_bar("Examining data");
|
||||
@ -164,17 +179,6 @@ namespace {
|
||||
results_.display_results(stream);
|
||||
}
|
||||
|
||||
|
||||
void scan_with_variable_sized_chunks(chunk_stream &stream) {
|
||||
variable_chunk_stream vstream(stream, 4096);
|
||||
scan(vstream);
|
||||
}
|
||||
|
||||
duplicate_counter const &get_results() const {
|
||||
return results_;
|
||||
}
|
||||
|
||||
private:
|
||||
void examine(chunk const &c) {
|
||||
if (all_zeroes(c))
|
||||
results_.add_zero_duplicate(c.len_);
|
||||
@ -230,8 +234,16 @@ namespace {
|
||||
|
||||
if (fs.content_based_chunks)
|
||||
detector.scan_with_variable_sized_chunks(pstream);
|
||||
else
|
||||
detector.scan(pstream);
|
||||
else {
|
||||
if (*fs.block_size) {
|
||||
if (factor_of(*fs.block_size, block_size))
|
||||
block_size = *fs.block_size;
|
||||
else
|
||||
throw runtime_error("specified block size is not a factor of the pool chunk size\n");
|
||||
}
|
||||
|
||||
detector.scan_with_fixed_sized_chunks(pstream, block_size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -254,7 +266,7 @@ namespace {
|
||||
if (fs.content_based_chunks)
|
||||
dd.scan_with_variable_sized_chunks(stream);
|
||||
else
|
||||
dd.scan(stream);
|
||||
dd.scan_with_fixed_sized_chunks(stream, block_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user