From 35cfc3b90a8ece7e7d99b96f9eddf2fe428c255e Mon Sep 17 00:00:00 2001 From: Thanos Makatos Date: Wed, 6 Apr 2016 14:13:21 +0300 Subject: [PATCH] introduce header file for the tmakatos (a binary) emitter This is necessary because the emitter's symbols need to be resolved at compile time. Only the tamakatos emitter header file is introduced, as it is trivial to do so for the other emitters. --- contrib/tmakatos_emitter.cc | 184 ++++++++++++++++-------------------- contrib/tmakatos_emitter.h | 69 ++++++++++++++ 2 files changed, 150 insertions(+), 103 deletions(-) create mode 100644 contrib/tmakatos_emitter.h 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_ */