diff --git a/contrib/tmakatos_emitter.cc b/contrib/tmakatos_emitter.cc index 4699077..32ad397 100644 --- a/contrib/tmakatos_emitter.cc +++ b/contrib/tmakatos_emitter.cc @@ -1,4 +1,5 @@ #include "thin-provisioning/emitter.h" +#include "contrib/tmakatos_emitter.h" #include #include @@ -8,7 +9,7 @@ using namespace thin_provisioning; //---------------------------------------------------------------- -namespace { +namespace tmakatos_emitter { template std::ostream &operator << (ostream &out, boost::optional const &maybe) { if (maybe) @@ -20,131 +21,108 @@ namespace { //------------------------------------------------ // binary generator //------------------------------------------------ - class binary_emitter : public emitter { - public: - binary_emitter(ostream &out) - : out_(out) { - } + binary_emitter::binary_emitter(ostream &out): out_(out) { + } - void begin_superblock(string const &uuid, - uint64_t time, - uint64_t trans_id, - boost::optional flags, - boost::optional version, - uint32_t data_block_size, - uint64_t nr_data_blocks, - boost::optional metadata_snap) { - } + void binary_emitter::begin_superblock(string const &uuid, + uint64_t time, + uint64_t trans_id, + boost::optional flags, + boost::optional version, + uint32_t data_block_size, + uint64_t nr_data_blocks, + boost::optional metadata_snap) { + } - void end_superblock() { - } + void binary_emitter::end_superblock() { + } - void begin_device(uint32_t dev_id, - uint64_t mapped_blocks, - uint64_t trans_id, - uint64_t creation_time, - uint64_t snap_time) { - cur = 0; - bitmap = 0; - } + void binary_emitter::begin_device(uint32_t dev_id, + uint64_t mapped_blocks, + uint64_t trans_id, + uint64_t creation_time, + uint64_t snap_time) { + cur = 0; + bitmap = 0; + } - void end_device() { - emit_bmp(true); - } + void binary_emitter::end_device() { + emit_bmp(true); + } - void begin_named_mapping(string const &name) { } + void binary_emitter::begin_named_mapping(string const &name) { } - void end_named_mapping() { } + void binary_emitter::end_named_mapping() { } - void identifier(string const &name) { } - void range_map(uint64_t origin_begin, uint64_t, uint32_t, - uint64_t len) { + void binary_emitter::identifier(string const &name) { } - uint64_t n = origin_begin / unit; - uint64_t i; + void binary_emitter::range_map(uint64_t origin_begin, uint64_t, uint32_t, + uint64_t len) { - assert(n >= cur); - assert(len > 0); + uint64_t n = origin_begin / unit; + uint64_t i; - /* - * Cover the gap between the last emitted unit and the current one. - */ - if (n > cur) - do { emit_bmp(); } while (cur < n); - - /* - * Emit partial unit. - */ - if (origin_begin & (unit - 1)) { - const uint64_t j = min(len, - (origin_begin & ~(unit - 1)) + unit - origin_begin); - for (i = origin_begin; i < origin_begin + j; i++) - bitmap |= 1ULL << (i & (unit - 1)); - if (j == len) - return; - - emit_bmp(); - - len -= j; - origin_begin = i; - } - - /* - * Emit full units until end. - */ - n = (origin_begin + len) / unit; - while (cur < n) { - bitmap = ~0; - emit_bmp(); - len -= unit; - } - origin_begin = cur * unit; - - /* - * Emit final unit. - */ - for (i = origin_begin; i < origin_begin + len; i++) - bitmap |= 1ULL << (i & (unit - 1)); - } - - void single_map(uint64_t origin_block, uint64_t, uint32_t) { - range_map(origin_block, 0, 0, 1); - } - - private: - ostream &out_; - - /** - * The entire virtual block allocation bitmap is segmented into 64-bit - * sub-bitmaps (units). - */ - uint64_t bitmap; + assert(n >= cur); + assert(len > 0); /* - * Pointer to the current sub-bitmap (unit) that has not yet been - * emitted. + * Cover the gap between the last emitted unit and the current one. */ - uint64_t cur; + if (n > cur) + do { emit_bmp(); } while (cur < n); - /** - * Unit (sub-bitmap) size. Must be a power of 2. + /* + * Emit partial unit. */ - static const size_t unit = sizeof bitmap * CHAR_BIT; + if (origin_begin & (unit - 1)) { + const uint64_t j = min(len, + (origin_begin & ~(unit - 1)) + unit - origin_begin); + for (i = origin_begin; i < origin_begin + j; i++) + bitmap |= 1ULL << (i & (unit - 1)); + if (j == len) + return; - void emit_bmp(bool omit_if_zero = false) { - if (!bitmap && omit_if_zero) - out_.write((const char*)&bitmap, sizeof bitmap); - bitmap = 0; - cur++; + emit_bmp(); + + len -= j; + origin_begin = i; } - }; + + /* + * Emit full units until end. + */ + n = (origin_begin + len) / unit; + while (cur < n) { + bitmap = ~0; + emit_bmp(); + len -= unit; + } + origin_begin = cur * unit; + + /* + * Emit final unit. + */ + for (i = origin_begin; i < origin_begin + len; i++) + bitmap |= 1ULL << (i & (unit - 1)); + } + + void binary_emitter::single_map(uint64_t origin_block, uint64_t, uint32_t) { + range_map(origin_block, 0, 0, 1); + } + + void binary_emitter::emit_bmp(bool omit_if_zero) { + if (!(!bitmap && omit_if_zero)) + out_.write((const char*)&bitmap, sizeof bitmap); + bitmap = 0; + cur++; + } } //---------------------------------------------------------------- extern "C" { emitter::ptr create_emitter(ostream &out) { - return emitter::ptr(new binary_emitter(out)); + return emitter::ptr(new tmakatos_emitter::binary_emitter(out)); } } diff --git a/contrib/tmakatos_emitter.h b/contrib/tmakatos_emitter.h new file mode 100644 index 0000000..51919b8 --- /dev/null +++ b/contrib/tmakatos_emitter.h @@ -0,0 +1,69 @@ +#ifndef _TMAKATOS_EMITTER_H_ +#define _TMAKATOS_EMITTER_H_ + +#include "thin-provisioning/emitter.h" +#include + +using namespace std; +using namespace thin_provisioning; + +namespace tmakatos_emitter { + class binary_emitter : public emitter { + public: + binary_emitter(ostream &out); + + void begin_superblock(string const &uuid, + uint64_t time, + uint64_t trans_id, + boost::optional flags, + boost::optional version, + uint32_t data_block_size, + uint64_t nr_data_blocks, + boost::optional metadata_snap); + + void end_superblock(); + + void begin_device(uint32_t dev_id, + uint64_t mapped_blocks, + uint64_t trans_id, + uint64_t creation_time, + uint64_t snap_time); + + void end_device(); + + void begin_named_mapping(string const &name); + + void end_named_mapping(); + + void identifier(string const &name); + + void range_map(uint64_t origin_begin, uint64_t, uint32_t, + uint64_t len); + + void single_map(uint64_t origin_block, uint64_t, uint32_t); + + private: + ostream &out_; + + /** + * The entire virtual block allocation bitmap is segmented into 64-bit + * sub-bitmaps (units). + */ + uint64_t bitmap; + + /* + * Pointer to the current sub-bitmap (unit) that has not yet been + * emitted. + */ + uint64_t cur; + + /** + * Unit (sub-bitmap) size. Must be a power of 2. + */ + static const size_t unit = sizeof bitmap * CHAR_BIT; + + void emit_bmp(bool omit_if_zero = false); + }; +} + +#endif /* _TMAKATOS_EMITTER_H_ */