}
);
+ /**
+ * read_transactions_successful
+ */
+ stats.read_transactions_successful = 0;
+ metrics.add_group(
+ "cache",
+ {
+ sm::make_counter(
+ "read_trans_successful",
+ stats.read_transactions_successful,
+ sm::description("total number of successful read transactions"),
+ {}
+ ),
+ }
+ );
+
/*
* cache_query: cache_access and cache_hit
*/
} // effort_name
} // src
} // category
+
+ /**
+ * read_effort_successful
+ */
+ stats.read_effort_successful = {};
+ auto register_read_effort_successful =
+ [this, &labels_by_counter]
+ (const char* counter_name, uint64_t& value) {
+ std::ostringstream oss_desc;
+ oss_desc << "total successful read transactional effort labeled by counter";
+ metrics.add_group(
+ "cache",
+ {
+ sm::make_counter(
+ "read_effort_successful",
+ value,
+ sm::description(oss_desc.str()),
+ {labels_by_counter.find(counter_name)->second}
+ ),
+ }
+ );
+ };
+ for (auto& counter_name : {"EXTENTS", "BYTES"}) {
+ auto& value = stats.read_effort_successful.get_by_name(counter_name);
+ register_read_effort_successful(counter_name, value);
+ }
}
}
*/
}
+void Cache::on_transaction_destruct(Transaction& t)
+{
+ LOG_PREFIX(Cache::on_transaction_destruct);
+ if (t.get_src() == Transaction::src_t::READ &&
+ t.conflicted == false &&
+ !t.is_weak()) {
+ DEBUGT("read is successful", t);
+ ++stats.read_transactions_successful;
+
+ assert(t.retired_set.empty());
+ assert(t.fresh_block_list.empty());
+ assert(t.mutated_block_list.empty());
+ stats.read_effort_successful.extents += t.read_set.size();
+ for (auto &i: t.read_set) {
+ stats.read_effort_successful.bytes += i.ref->get_length();
+ }
+ }
+}
+
CachedExtentRef Cache::alloc_new_extent_by_type(
Transaction &t, ///< [in, out] current transaction
extent_types_t type, ///< [in] type tag
get_dummy_ordering_handle(),
false,
src,
- last_commit
+ last_commit,
+ [this](Transaction& t) {
+ return on_transaction_destruct(t);
+ }
);
retired_extent_gate.add_token(ret->retired_gate_token);
DEBUGT("created source={}", *ret, src);
get_dummy_ordering_handle(),
true,
src,
- last_commit
+ last_commit,
+ [this](Transaction& t) {
+ return on_transaction_destruct(t);
+ }
);
retired_extent_gate.add_token(ret->retired_gate_token);
DEBUGT("created source={}", *ret, src);
std::array<trans_efforts_t, Transaction::SRC_MAX> invalidated_efforts_by_src;
std::unordered_map<src_ext_t, query_counters_t,
boost::hash<src_ext_t>> cache_query;
+ uint64_t read_transactions_successful;
+ effort_t read_effort_successful;
} stats;
template <typename CounterT>
/// Measure efforts of a submitting/invalidating transaction
void measure_efforts(Transaction& t, trans_efforts_t& efforts);
+ /// Introspect transaction when it is being destructed
+ void on_transaction_destruct(Transaction& t);
+
template <typename T>
get_extent_ret<T> read_extent(
TCachedExtentRef<T>&& extent
class Transaction {
public:
using Ref = std::unique_ptr<Transaction>;
+ using on_destruct_func_t = std::function<void(Transaction&)>;
enum class get_extent_ret {
PRESENT,
ABSENT,
OrderingHandle &&handle,
bool weak,
src_t src,
- journal_seq_t initiated_after
+ journal_seq_t initiated_after,
+ on_destruct_func_t&& f
) : weak(weak),
retired_gate_token(initiated_after),
handle(std::move(handle)),
+ on_destruct(std::move(f)),
src(src)
{}
~Transaction() {
+ on_destruct(*this);
for (auto i = write_set.begin();
i != write_set.end();) {
i->state = CachedExtent::extent_state_t::INVALID;
OrderingHandle handle;
+ on_destruct_func_t on_destruct;
+
const src_t src;
};
using TransactionRef = Transaction::Ref;
get_dummy_ordering_handle(),
false,
Transaction::src_t::MUTATE,
- journal_seq_t{}
+ journal_seq_t{},
+ [](Transaction&) {}
);
}