[thin_show_duplicates] start factoring out a chunk_stream abstraction
This commit is contained in:
parent
d954f230fa
commit
c8d3ce6af5
@ -12,6 +12,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
|
||||||
@ -112,6 +113,44 @@ namespace bcache {
|
|||||||
validator::ptr v_;
|
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,
|
block_cache(int fd, sector_t block_size,
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include <boost/uuid/sha1.hpp>
|
#include <boost/uuid/sha1.hpp>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
#include <deque>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using namespace base;
|
using namespace base;
|
||||||
@ -54,6 +55,15 @@ namespace {
|
|||||||
return (n % f) == 0;
|
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
|
block_manager<>::ptr
|
||||||
open_bm(string const &path) {
|
open_bm(string const &path) {
|
||||||
block_address nr_blocks = get_nr_blocks(path);
|
block_address nr_blocks = get_nr_blocks(path);
|
||||||
@ -84,9 +94,97 @@ namespace {
|
|||||||
|
|
||||||
//--------------------------------
|
//--------------------------------
|
||||||
|
|
||||||
struct data_block {
|
// Once we start using variable sized blocks we will find we want
|
||||||
block_address begin, end;
|
// to examine data that crosses cache block boundaries. So a block
|
||||||
void *data;
|
// 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;
|
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
|
// FIXME: introduce abstraction for a stream of segments
|
||||||
|
|
||||||
using namespace mapping_tree_detail;
|
using namespace mapping_tree_detail;
|
||||||
@ -217,6 +305,10 @@ namespace {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{
|
||||||
|
cache_stream(fs.data_dev, block_size, fs.cache_mem);
|
||||||
|
}
|
||||||
|
|
||||||
cerr << "path = " << fs.data_dev << "\n";
|
cerr << "path = " << fs.data_dev << "\n";
|
||||||
cerr << "block size = " << block_size << "\n";
|
cerr << "block size = " << block_size << "\n";
|
||||||
block_address nr_blocks = get_nr_blocks(fs.data_dev, block_size);
|
block_address nr_blocks = get_nr_blocks(fs.data_dev, block_size);
|
||||||
|
Loading…
Reference in New Issue
Block a user