metadata_v2: clean up inode_manager

This commit is contained in:
Marcus Holland-Moritz 2020-11-28 01:40:29 +01:00
parent 18eb2e83c5
commit 5858c1c53d
5 changed files with 20 additions and 127 deletions

View File

@ -132,71 +132,6 @@ struct directory {
} u; } u;
}; };
struct meta_config {
uint8_t block_size_bits;
dir_entry_type de_type;
uint16_t unused;
uint32_t inode_count;
uint64_t orig_fs_size;
uint32_t chunk_index_offset;
uint32_t inode_index_offset;
};
using chunk_type = uint64_t;
template <unsigned BlockSizeBits>
struct chunk_access {
static_assert(BlockSizeBits < 32, "invalid value for BlockSizeBits");
static const unsigned block_bits = 64 - 2 * BlockSizeBits;
static const unsigned block_shift = 64 - block_bits;
static const chunk_type block_mask =
(static_cast<chunk_type>(1) << block_bits) - 1;
static const unsigned offset_shift = BlockSizeBits;
static const chunk_type offset_mask =
(static_cast<chunk_type>(1) << BlockSizeBits) - 1;
static const unsigned size_shift = 0;
static const chunk_type size_mask =
(static_cast<chunk_type>(1) << BlockSizeBits) - 1;
static const chunk_type max_size = size_mask + 1;
static void set(chunk_type& chunk, size_t block, size_t offset, size_t size) {
if (block > block_mask) {
std::cerr << "block out of range: " << block << " > " << block_mask
<< " [" << block_bits << "]";
throw std::runtime_error("block out of range");
}
if (offset > offset_mask) {
std::cerr << "offset out of range: " << offset << " > " << offset_mask
<< " [" << block_bits << "]";
throw std::runtime_error("offset out of range");
}
if (size > max_size or size == 0) {
std::cerr << "size out of range: " << size << " > " << size_mask << " ["
<< block_bits << "]";
throw std::runtime_error("size out of range");
}
chunk = (static_cast<chunk_type>(block) << block_shift) |
(static_cast<chunk_type>(offset) << offset_shift) |
(static_cast<chunk_type>(size - 1) << size_shift);
}
static size_t block(chunk_type chunk) {
return (chunk >> block_shift) & block_mask;
};
static size_t offset(chunk_type chunk) {
return (chunk >> offset_shift) & offset_mask;
};
static size_t size(chunk_type chunk) {
return ((chunk >> size_shift) & size_mask) + 1;
};
};
std::string get_compression_name(compression_type type); std::string get_compression_name(compression_type type);
std::string get_section_name(section_type type); std::string get_section_name(section_type type);

View File

@ -41,8 +41,7 @@ class inode : public file_interface {
virtual uint32_t similarity_hash() const = 0; virtual uint32_t similarity_hash() const = 0;
virtual const file_interface* any() const = 0; // TODO virtual const file_interface* any() const = 0; // TODO
virtual void add_chunk(size_t block, size_t offset, size_t size) = 0; virtual void add_chunk(size_t block, size_t offset, size_t size) = 0;
virtual const std::vector<chunk_type>& chunks() const = 0;
virtual void virtual void
append_chunks(std::vector<thrift::metadata::chunk>& vec) const = 0; append_chunks_to(std::vector<thrift::metadata::chunk>& vec) const = 0;
}; };
} // namespace dwarfs } // namespace dwarfs

View File

@ -34,23 +34,16 @@ class script;
class inode_manager { class inode_manager {
public: public:
static std::shared_ptr<inode_manager> create(unsigned block_size_bits); static std::unique_ptr<inode_manager> create();
virtual ~inode_manager() = default; virtual ~inode_manager() = default;
virtual std::shared_ptr<inode> create() = 0; virtual std::shared_ptr<inode> create_inode() = 0;
virtual size_t count() const = 0; virtual size_t count() const = 0;
virtual size_t block_size() const = 0;
virtual unsigned block_size_bits() const = 0;
virtual size_t chunk_size() const = 0;
virtual void order_inodes() = 0; virtual void order_inodes() = 0;
virtual void order_inodes(std::shared_ptr<script> scr) = 0; virtual void order_inodes(std::shared_ptr<script> scr) = 0;
virtual void order_inodes_by_similarity() = 0; virtual void order_inodes_by_similarity() = 0;
virtual void number_inodes(size_t first_no) = 0; virtual void number_inodes(size_t first_no) = 0;
virtual void for_each_inode( virtual void for_each_inode(
std::function<void(std::shared_ptr<inode> const&)> const& fn) const = 0; std::function<void(std::shared_ptr<inode> const&)> const& fn) const = 0;
private:
template <unsigned BlockSizeBits>
static std::shared_ptr<inode_manager> create_(unsigned block_size_bits);
}; };
} // namespace dwarfs } // namespace dwarfs

View File

@ -32,12 +32,11 @@
namespace dwarfs { namespace dwarfs {
template <unsigned BlockSizeBits = 24>
class inode_manager_ : public inode_manager { class inode_manager_ : public inode_manager {
private: private:
class inode_ : public inode { class inode_ : public inode {
public: public:
using access = chunk_access<BlockSizeBits>; using chunk_type = thrift::metadata::chunk;
void set_num(uint32_t num) override { num_ = num; } void set_num(uint32_t num) override { num_ = num; }
uint32_t num() const override { return num_; } uint32_t num() const override { return num_; }
@ -59,7 +58,9 @@ class inode_manager_ : public inode_manager {
void add_chunk(size_t block, size_t offset, size_t size) override { void add_chunk(size_t block, size_t offset, size_t size) override {
chunk_type c; chunk_type c;
access::set(c, block, offset, size); c.block = block;
c.offset = offset;
c.size = size;
chunks_.push_back(c); chunks_.push_back(c);
} }
@ -76,17 +77,9 @@ class inode_manager_ : public inode_manager {
return file_; return file_;
} }
const std::vector<chunk_type>& chunks() const override { return chunks_; }
void void
append_chunks(std::vector<thrift::metadata::chunk>& vec) const override { append_chunks_to(std::vector<chunk_type>& vec) const override {
for (auto c : chunks_) { vec.insert(vec.end(), chunks_.begin(), chunks_.end());
thrift::metadata::chunk chnk;
chnk.block = access::block(c);
chnk.offset = access::offset(c);
chnk.size = access::size(c);
vec.push_back(chnk);
}
} }
private: private:
@ -96,7 +89,7 @@ class inode_manager_ : public inode_manager {
}; };
public: public:
std::shared_ptr<inode> create() override { std::shared_ptr<inode> create_inode() override {
auto ino = std::make_shared<inode_>(); auto ino = std::make_shared<inode_>();
inodes_.push_back(ino); inodes_.push_back(ino);
return ino; return ino;
@ -104,17 +97,6 @@ class inode_manager_ : public inode_manager {
size_t count() const override { return inodes_.size(); } size_t count() const override { return inodes_.size(); }
size_t block_size() const override {
return static_cast<size_t>(1) << BlockSizeBits;
}
unsigned block_size_bits() const override { return BlockSizeBits; }
size_t chunk_size() const override {
// TODO: not needed
return sizeof(chunk_type);
}
void order_inodes(std::shared_ptr<script> scr) override { void order_inodes(std::shared_ptr<script> scr) override {
scr->order(inodes_); scr->order(inodes_);
} }
@ -175,23 +157,7 @@ class inode_manager_ : public inode_manager {
std::vector<std::shared_ptr<inode>> inodes_; std::vector<std::shared_ptr<inode>> inodes_;
}; };
template <unsigned BlockSizeBits> std::unique_ptr<inode_manager> inode_manager::create() {
std::shared_ptr<inode_manager> return std::make_unique<inode_manager_>();
inode_manager::create_(unsigned block_size_bits) {
if (block_size_bits == BlockSizeBits) {
return std::make_shared<inode_manager_<BlockSizeBits>>();
}
return create_<BlockSizeBits - 1>(block_size_bits);
}
template <>
std::shared_ptr<inode_manager>
inode_manager::create_<MIN_BLOCK_BITS_SIZE - 1>(unsigned) {
throw std::runtime_error("unsupported block_size_bits");
}
std::shared_ptr<inode_manager> inode_manager::create(unsigned block_size_bits) {
return create_<MAX_BLOCK_BITS_SIZE>(block_size_bits);
} }
} // namespace dwarfs } // namespace dwarfs

View File

@ -299,7 +299,7 @@ void scanner_<LoggerPolicy>::scan(filesystem_writer& fsw,
link_set_inode_visitor lsiv(first_file_inode); link_set_inode_visitor lsiv(first_file_inode);
root->accept(lsiv, true); root->accept(lsiv, true);
auto im = inode_manager::create(cfg_.block_size_bits); auto im = inode_manager::create();
for (auto& p : file_hash) { for (auto& p : file_hash) {
if (p.second.size() > 1) { if (p.second.size() > 1) {
@ -310,7 +310,7 @@ void scanner_<LoggerPolicy>::scan(filesystem_writer& fsw,
auto first = p.second.front(); auto first = p.second.front();
{ {
auto inode = im->create(); auto inode = im->create_inode();
first->set_inode(inode); first->set_inode(inode);
inode->set_file(first); inode->set_file(first);
} }
@ -395,13 +395,13 @@ void scanner_<LoggerPolicy>::scan(filesystem_writer& fsw,
prog.inodes_written++; prog.inodes_written++;
}); });
prog.sync([&] { prog.current.store(nullptr); }); log_.info() << "waiting for block compression to finish...";
log_.debug() << "waiting for block compression to finish...";
bm.finish_blocks(); bm.finish_blocks();
wg_.wait(); wg_.wait();
prog.sync([&] { prog.current.store(nullptr); });
// TODO: check this, doesn't seem to come out right in debug output // TODO: check this, doesn't seem to come out right in debug output
// seems to be out-of-line with block compression?? // seems to be out-of-line with block compression??
log_.debug() << "compressed " << size_with_unit(bm.total_size()) << " in " log_.debug() << "compressed " << size_with_unit(bm.total_size()) << " in "
@ -425,7 +425,7 @@ void scanner_<LoggerPolicy>::scan(filesystem_writer& fsw,
// submitted for compression // submitted for compression
im->for_each_inode([&](std::shared_ptr<inode> const& ino) { im->for_each_inode([&](std::shared_ptr<inode> const& ino) {
mv2.chunk_index.at(ino->num() - first_file_inode) = mv2.chunks.size(); mv2.chunk_index.at(ino->num() - first_file_inode) = mv2.chunks.size();
ino->append_chunks(mv2.chunks); ino->append_chunks_to(mv2.chunks);
}); });
// insert dummy inode to help determine number of chunks per inode // insert dummy inode to help determine number of chunks per inode
@ -455,7 +455,7 @@ void scanner_<LoggerPolicy>::scan(filesystem_writer& fsw,
mv2.links = ge_data.get_links(); mv2.links = ge_data.get_links();
mv2.timestamp_base = ge_data.timestamp_base; mv2.timestamp_base = ge_data.timestamp_base;
mv2.chunk_index_offset = first_file_inode; mv2.chunk_index_offset = first_file_inode;
mv2.block_size = im->block_size(); mv2.block_size = UINT32_C(1) << cfg_.block_size_bits;
mv2.total_fs_size = prog.original_size; mv2.total_fs_size = prog.original_size;
auto [schema, data] = metadata_v2::freeze(mv2); auto [schema, data] = metadata_v2::freeze(mv2);
@ -463,7 +463,7 @@ void scanner_<LoggerPolicy>::scan(filesystem_writer& fsw,
fsw.write_metadata_v2_schema(std::move(schema)); fsw.write_metadata_v2_schema(std::move(schema));
fsw.write_metadata_v2(std::move(data)); fsw.write_metadata_v2(std::move(data));
log_.info() << "waiting for compression tasks to finish..."; log_.info() << "waiting for compression to finish...";
fsw.flush(); fsw.flush();