4 #include <chainbase/generic_index.hpp>
8 #define LIFE_TIME_PERIOD std::numeric_limits<uint32_t>::max()
11 namespace common_statistics {
20 typedef typename chainbase::get_index_type<Bucket>::type
bucket_index;
26 flat_set<uint32_t> _tracked_buckets = { 60, 3600, 21600, 86400, 604800, 2592000,
LIFE_TIME_PERIOD };
28 uint32_t _maximum_history_per_bucket_size = 100;
54 auto& db = _self.database();
56 db.applied_block.connect([&](
const signed_block& b) { this->on_block(b); });
60 db.template add_plugin_index<bucket_index>();
65 auto& db = _self.database();
67 for (
auto bucket_id : _current_buckets)
69 const auto& bucket = db.get(bucket_id);
71 process_pre_operation(bucket, o);
79 auto& db = _self.database();
81 for (
auto bucket_id : _current_buckets)
83 const auto& bucket = db.get(bucket_id);
85 process_post_operation(bucket, o);
88 FC_CAPTURE_AND_RETHROW()
93 auto& db = _self.database();
95 _current_buckets.clear();
97 const auto& bucket_idx = db.template get_index<bucket_index, common_statistics::by_bucket>();
99 for (
const auto& bucket : _tracked_buckets)
101 auto open = fc::time_point_sec((db.head_block_time().sec_since_epoch() / bucket) * bucket);
103 auto itr = bucket_idx.find(boost::make_tuple(bucket, open));
104 if (itr != bucket_idx.end())
106 _current_buckets.insert(itr->id);
110 const auto& new_bucket_obj = db.template create<Bucket>([&](Bucket& bo) {
115 process_bucket_creation(new_bucket_obj);
117 _current_buckets.insert(new_bucket_obj.id);
120 if (_maximum_history_per_bucket_size > 0)
124 auto cutoff = fc::time_point_sec();
125 if (safe<uint64_t>(bucket) * safe<uint64_t>(_maximum_history_per_bucket_size)
128 cutoff = fc::time_point_sec(
129 (safe<uint32_t>(db.head_block_time().sec_since_epoch())
130 - safe<uint32_t>(bucket) * safe<uint32_t>(_maximum_history_per_bucket_size))
134 itr = bucket_idx.lower_bound(boost::make_tuple(bucket, fc::time_point_sec()));
136 while (itr->seconds == bucket && itr->open < cutoff)
143 catch (fc::overflow_exception& e)
146 catch (fc::underflow_exception& e)
152 process_block(*itr, block);
virtual ~common_statistics_plugin_impl()
virtual void process_post_operation(const Bucket &bucket, const operation_notification &o)
flat_set< typename Bucket::id_type > _current_buckets
virtual void process_block(const Bucket &bucket, const signed_block &b)
void pre_operation(const operation_notification &o)
void on_block(const signed_block &block)
common_statistics_plugin_impl base_plugin_impl
void post_operation(const operation_notification &o)
common_statistics_plugin_impl(Plugin &plugin)
virtual void process_pre_operation(const Bucket &bucket, const operation_notification &o)
virtual void process_bucket_creation(const Bucket &bucket)
shared_multi_index_container< bucket_object, indexed_by< ordered_unique< tag< by_id >, member< bucket_object, bucket_id_type, &bucket_object::id > >, ordered_unique< tag< common_statistics::by_bucket >, composite_key< bucket_object, member< common_statistics::base_bucket_object, uint32_t, &common_statistics::base_bucket_object::seconds >, member< common_statistics::base_bucket_object, fc::time_point_sec, &common_statistics::base_bucket_object::open > > > > > bucket_index