[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/cache_stream.cc \
|
||||||
thin-provisioning/chunk_stream.cc \
|
thin-provisioning/chunk_stream.cc \
|
||||||
thin-provisioning/device_tree.cc \
|
thin-provisioning/device_tree.cc \
|
||||||
|
thin-provisioning/fixed_chunk_stream.cc \
|
||||||
thin-provisioning/human_readable_format.cc \
|
thin-provisioning/human_readable_format.cc \
|
||||||
thin-provisioning/mapping_tree.cc \
|
thin-provisioning/mapping_tree.cc \
|
||||||
thin-provisioning/metadata.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/core.h"
|
||||||
#include "persistent-data/space-maps/disk.h"
|
#include "persistent-data/space-maps/disk.h"
|
||||||
#include "thin-provisioning/cache_stream.h"
|
#include "thin-provisioning/cache_stream.h"
|
||||||
|
#include "thin-provisioning/fixed_chunk_stream.h"
|
||||||
#include "thin-provisioning/pool_stream.h"
|
#include "thin-provisioning/pool_stream.h"
|
||||||
#include "thin-provisioning/commands.h"
|
#include "thin-provisioning/commands.h"
|
||||||
#include "thin-provisioning/device_tree.h"
|
#include "thin-provisioning/device_tree.h"
|
||||||
@ -54,7 +55,6 @@ using namespace thin_provisioning;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
bool factor_of(block_address f, block_address n) {
|
bool factor_of(block_address f, block_address n) {
|
||||||
cerr << n << " % " << f << "\n";
|
|
||||||
return (n % f) == 0;
|
return (n % f) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,6 +145,21 @@ namespace {
|
|||||||
|
|
||||||
class duplicate_detector {
|
class duplicate_detector {
|
||||||
public:
|
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) {
|
void scan(chunk_stream &stream) {
|
||||||
block_address total_seen(0);
|
block_address total_seen(0);
|
||||||
auto_ptr<progress_monitor> pbar = create_progress_bar("Examining data");
|
auto_ptr<progress_monitor> pbar = create_progress_bar("Examining data");
|
||||||
@ -164,17 +179,6 @@ namespace {
|
|||||||
results_.display_results(stream);
|
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) {
|
void examine(chunk const &c) {
|
||||||
if (all_zeroes(c))
|
if (all_zeroes(c))
|
||||||
results_.add_zero_duplicate(c.len_);
|
results_.add_zero_duplicate(c.len_);
|
||||||
@ -230,8 +234,16 @@ namespace {
|
|||||||
|
|
||||||
if (fs.content_based_chunks)
|
if (fs.content_based_chunks)
|
||||||
detector.scan_with_variable_sized_chunks(pstream);
|
detector.scan_with_variable_sized_chunks(pstream);
|
||||||
else
|
else {
|
||||||
detector.scan(pstream);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -254,7 +266,7 @@ namespace {
|
|||||||
if (fs.content_based_chunks)
|
if (fs.content_based_chunks)
|
||||||
dd.scan_with_variable_sized_chunks(stream);
|
dd.scan_with_variable_sized_chunks(stream);
|
||||||
else
|
else
|
||||||
dd.scan(stream);
|
dd.scan_with_fixed_sized_chunks(stream, block_size);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user