[thin_show_duplicates] start factoring out a chunk_stream abstraction

This commit is contained in:
Joe Thornber 2015-08-24 11:18:31 +01:00
parent d954f230fa
commit c8d3ce6af5
2 changed files with 144 additions and 13 deletions

View File

@ -12,6 +12,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <vector>
#include <iostream>
//----------------------------------------------------------------
@ -112,6 +113,44 @@ namespace bcache {
validator::ptr v_;
};
class auto_block {
public:
auto_block()
: b_(0) {
}
auto_block(block &b)
: b_(&b) {
}
~auto_block() {
put();
}
auto_block &operator =(block &b) {
put();
b_ = &b;
return *this;
}
void *get_data() const {
if (b_)
return b_->get_data();
throw std::runtime_error("auto_block not set");
}
private:
void put() {
if (b_) {
b_->put();
b_ = 0;
}
}
block *b_;
};
//--------------------------------
block_cache(int fd, sector_t block_size,

View File

@ -38,6 +38,7 @@
#include <boost/uuid/sha1.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/optional.hpp>
#include <deque>
#include <vector>
using namespace base;
@ -54,6 +55,15 @@ namespace {
return (n % f) == 0;
}
int open_file(string const &path) {
int fd = ::open(path.c_str(), O_RDONLY | O_DIRECT | O_EXCL, 0666);
if (fd < 0)
syscall_failed("open",
"Note: you cannot run this tool with these options on live metadata.");
return fd;
}
block_manager<>::ptr
open_bm(string const &path) {
block_address nr_blocks = get_nr_blocks(path);
@ -84,9 +94,97 @@ namespace {
//--------------------------------
struct data_block {
block_address begin, end;
void *data;
// Once we start using variable sized blocks we will find we want
// to examine data that crosses cache block boundaries. So a block
// to be examined can be composed of multiple chunks of memory.
struct mem {
mem(void *b, void *e)
: begin(b),
end(e) {
}
void *begin, *end;
};
struct chunk {
sector_t offset_sectors_;
deque<mem> mem_;
};
class chunk_stream {
public:
virtual ~chunk_stream() {}
virtual void rewind() = 0;
virtual bool advance() = 0;
virtual chunk const &get() const = 0;
};
class cache_stream : public chunk_stream {
public:
cache_stream(string const &path,
block_address block_size,
size_t cache_mem)
: block_size_(block_size),
nr_blocks_(get_nr_blocks(path, block_size)),
// hack because cache uses LRU rather than MRU
cache_blocks_((cache_mem / block_size) / 2u),
fd_(open_file(path)),
v_(new bcache::noop_validator()),
cache_(new block_cache(fd_, block_size / 512, nr_blocks_, cache_mem)),
current_index_(0) {
load(0);
}
virtual void rewind() {
load(0);
}
virtual bool advance() {
if (current_index_ >= nr_blocks_)
return false;
current_index_++;
load(current_index_);
return true;
}
virtual chunk const &get() const {
return current_chunk_;
}
private:
void load(block_address b) {
current_index_ = b;
current_block_ = cache_->get(current_index_, 0, v_);
current_chunk_.offset_sectors_ = (b * block_size_) / 512;
current_chunk_.mem_.clear();
current_chunk_.mem_.push_back(mem(current_block_.get_data(),
current_block_.get_data() + block_size_));
}
block_address block_size_;
block_address nr_blocks_;
block_address cache_blocks_;
int fd_;
validator::ptr v_;
auto_ptr<block_cache> cache_;
block_address current_index_;
block_cache::auto_block current_block_;
chunk current_chunk_;
};
class fixed_block_stream : public chunk_stream {
public:
};
class variable_size_stream : public chunk_stream {
};
//--------------------------------
@ -102,16 +200,6 @@ namespace {
unsigned cache_mem;
};
int open_file(string const &path) {
int fd = ::open(path.c_str(), O_RDONLY | O_DIRECT | O_EXCL, 0666);
if (fd < 0)
syscall_failed("open",
"Note: you cannot run this tool with these options on live metadata.");
return fd;
}
// FIXME: introduce abstraction for a stream of segments
using namespace mapping_tree_detail;
@ -217,6 +305,10 @@ namespace {
}
#endif
{
cache_stream(fs.data_dev, block_size, fs.cache_mem);
}
cerr << "path = " << fs.data_dev << "\n";
cerr << "block size = " << block_size << "\n";
block_address nr_blocks = get_nr_blocks(fs.data_dev, block_size);