*/
#include "../fmt.hpp"
+#include "../utils.hpp"
#include "field_stats.hpp"
+#include <common/make-unique-wrapper.hpp>
+#include <common/make-unique.hpp>
+
#include <assert.h>
#include <babeltrace2/babeltrace.h>
+#include <cstdint>
#include <cstring>
+#include <iostream>
#include <stdio.h>
#include <stdlib.h>
-struct field_stats {
- bt_message_iterator *iterator;
- bt_value *stats_value;
- const bt_event_class *event_class;
-};
-
-bt_component_class_initialize_method_status
-field_stats_initialize(bt_self_component_sink *self_component_sink,
- bt_self_component_sink_configuration *,
- const bt_value *,
- void *)
-{
- bt_component_class_initialize_method_status status;
- struct field_stats *field_stats = nullptr;
-
- if (bt_self_component_sink_add_input_port(self_component_sink, "in", nullptr, nullptr) !=
- BT_SELF_COMPONENT_ADD_PORT_STATUS_OK) {
- BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
- bt_self_component_sink_as_self_component(self_component_sink),
- "Failed to add input port");
- status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
- goto error;
+class bad_alloc_with_msg : public std::bad_alloc {
+public:
+ explicit bad_alloc_with_msg(const std::string& msg) : _msg(msg)
+ {
}
- field_stats = (struct field_stats *) malloc(sizeof(*field_stats));
- if (field_stats == nullptr) {
- BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
- bt_self_component_sink_as_self_component(self_component_sink),
- "Failed to allocate memory for private data");
- status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
- goto error;
+ virtual const char *what() const noexcept override
+ {
+ return _msg.c_str();
}
- field_stats->iterator = nullptr;
- field_stats->stats_value = bt_value_map_create();
- field_stats->event_class = nullptr;
- if (field_stats->stats_value == nullptr) {
- BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
- bt_self_component_sink_as_self_component(self_component_sink),
- "Failed to allocate memory for field_stats.stats map");
- status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
- goto error;
+private:
+ std::string _msg;
+};
+
+struct field_stats {
+public:
+ field_stats() : stats_value{ lttng::bt2::make_value_ref(bt_value_map_create()) }
+ {
+ if (!stats_value) {
+ throw bad_alloc_with_msg(
+ "Failed to allocate memory for field_stats.stats map");
+ }
}
- bt_self_component_set_data(bt_self_component_sink_as_self_component(self_component_sink),
- field_stats);
- status = BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
- goto end;
-error:
- if (field_stats) {
- free(field_stats);
+ ~field_stats()
+ {
}
-end:
- return status;
-}
-static bt_value_map_foreach_entry_const_func_status
+ lttng::bt2::message_iterator_ref upstream_iterator;
+ lttng::bt2::event_class_const_ref event_class;
+ const lttng::bt2::value_ref stats_value;
+};
+
+namespace {
+bt_value_map_foreach_entry_const_func_status
stats_value_print_summary(const char *key, const bt_value *value, void *)
{
- assert(bt_value_is_map(value));
+ LTTNG_ASSERT(bt_value_is_map(value));
+
+ const auto *min = bt_value_map_borrow_entry_value_const(value, "min");
+ LTTNG_ASSERT(min != nullptr);
+ const auto *max = bt_value_map_borrow_entry_value_const(value, "max");
+ LTTNG_ASSERT(max != nullptr);
- const bt_value *min = bt_value_map_borrow_entry_value_const(value, "min");
- const bt_value *max = bt_value_map_borrow_entry_value_const(value, "max");
- const bt_value *display_base = bt_value_map_borrow_entry_value_const(value, "display_base");
- enum bt_field_class_integer_preferred_display_base display_base_value =
- BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
+ const auto *display_base = bt_value_map_borrow_entry_value_const(value, "display_base");
+ auto display_base_value = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL;
if (display_base != nullptr) {
display_base_value = (enum bt_field_class_integer_preferred_display_base)
bt_value_integer_unsigned_get(display_base);
}
- assert(min != nullptr);
- assert(max != nullptr);
- if (bt_value_is_string(min)) {
+ LTTNG_ASSERT(bt_value_get_type(min) == bt_value_get_type(max));
+
+ switch (bt_value_get_type(min)) {
+ case BT_VALUE_TYPE_STRING:
fmt::print("{} \"{}\" \"{}\"\n",
key,
bt_value_string_get(min),
bt_value_string_get(max));
- } else if (bt_value_is_unsigned_integer(min)) {
+ break;
+ case BT_VALUE_TYPE_UNSIGNED_INTEGER:
switch (display_base_value) {
case BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL:
- fmt::print("{} 0x{:X} 0x{:X}\n",
- key,
- bt_value_integer_unsigned_get(min),
- bt_value_integer_unsigned_get(max));
+ std::cout << lttng::format("{} 0x{:X} 0x{:X}\n",
+ key,
+ bt_value_integer_unsigned_get(min),
+ bt_value_integer_unsigned_get(max));
break;
default:
- fmt::print("{} {} {}\n",
- key,
- bt_value_integer_unsigned_get(min),
- bt_value_integer_unsigned_get(max));
+ std::cout << lttng::format("{} {} {}\n",
+ key,
+ bt_value_integer_unsigned_get(min),
+ bt_value_integer_unsigned_get(max));
break;
}
- } else if (bt_value_is_signed_integer(min)) {
+
+ break;
+ case BT_VALUE_TYPE_SIGNED_INTEGER:
switch (display_base_value) {
case BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL:
- fmt::print("{} 0x{:X} 0x{:X}\n",
- key,
- (uint64_t) bt_value_integer_signed_get(min),
- (uint64_t) bt_value_integer_signed_get(max));
+ std::cout << lttng::format("{} 0x{:X} 0x{:X}\n",
+ key,
+ std::uint64_t(bt_value_integer_signed_get(min)),
+ std::uint64_t(bt_value_integer_signed_get(max)));
break;
default:
- fmt::print("{} {} {}\n",
- key,
- bt_value_integer_signed_get(min),
- bt_value_integer_signed_get(max));
+ std::cout << lttng::format("{} {} {}\n",
+ key,
+ bt_value_integer_signed_get(min),
+ bt_value_integer_signed_get(max));
break;
}
- } else if (bt_value_is_real(min)) {
- fmt::print("{} {:0g} {:0g}\n", key, bt_value_real_get(min), bt_value_real_get(max));
- } else {
- assert(BT_FALSE);
- }
- return BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK;
-}
-void field_stats_finalize(bt_self_component_sink *self_component_sink)
-{
- struct field_stats *field_stats = (struct field_stats *) bt_self_component_get_data(
- bt_self_component_sink_as_self_component(self_component_sink));
- bt_value_put_ref(field_stats->stats_value);
- free(field_stats);
-}
-
-bt_component_class_sink_graph_is_configured_method_status
-field_stats_graph_is_configured(bt_self_component_sink *self_component_sink)
-{
- struct field_stats *field_stats = (struct field_stats *) bt_self_component_get_data(
- bt_self_component_sink_as_self_component(self_component_sink));
- bt_self_component_port_input *input_port =
- bt_self_component_sink_borrow_input_port_by_index(self_component_sink, 0);
- if (bt_message_iterator_create_from_sink_component(
- self_component_sink, input_port, &field_stats->iterator) !=
- BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK) {
- BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
- bt_self_component_sink_as_self_component(self_component_sink),
- "input port message iterator creation failed");
- return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_ERROR;
+ break;
+ case BT_VALUE_TYPE_REAL:
+ std::cout << lttng::format(
+ "{} {:0g} {:0g}\n", key, bt_value_real_get(min), bt_value_real_get(max));
+ break;
+ default:
+ abort();
}
- return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
+ return BT_VALUE_MAP_FOREACH_ENTRY_CONST_FUNC_STATUS_OK;
}
-static bt_component_class_sink_consume_method_status
-member_stats_set_min_max(bt_value *member_map,
- const bt_field_class_structure_member *member,
- const bt_field *member_field,
- const bt_field_class *member_class,
- const bt_field_class_type *member_class_type,
- bt_self_component_sink *self_component_sink)
+void member_stats_set_min_max(bt_value *member_map,
+ const bt_field_class_structure_member *member,
+ const bt_field *member_field,
+ const bt_field_class *member_class,
+ const bt_field_class_type *member_class_type)
{
- bt_value *min, *max, *display_base = bt_value_null;
+ lttng::bt2::value_ref min, max, display_base;
const char *name = bt_field_class_structure_member_get_name(member);
if (bt_field_class_type_is(*member_class_type, BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER)) {
- min = bt_value_integer_unsigned_create_init(
- bt_field_integer_unsigned_get_value(member_field));
- max = bt_value_integer_unsigned_create_init(
- bt_field_integer_unsigned_get_value(member_field));
- display_base = bt_value_integer_unsigned_create_init(
- bt_field_class_integer_get_preferred_display_base(member_class));
+ min = lttng::bt2::make_value_ref(bt_value_integer_unsigned_create_init(
+ bt_field_integer_unsigned_get_value(member_field)));
+ max = lttng::bt2::make_value_ref(bt_value_integer_unsigned_create_init(
+ bt_field_integer_unsigned_get_value(member_field)));
+ display_base = lttng::bt2::make_value_ref(bt_value_integer_unsigned_create_init(
+ bt_field_class_integer_get_preferred_display_base(member_class)));
} else if (bt_field_class_type_is(*member_class_type, BT_FIELD_CLASS_TYPE_SIGNED_INTEGER)) {
- min = bt_value_integer_signed_create_init(
- bt_field_integer_signed_get_value(member_field));
- max = bt_value_integer_signed_create_init(
- bt_field_integer_signed_get_value(member_field));
- display_base = bt_value_integer_unsigned_create_init(
- bt_field_class_integer_get_preferred_display_base(member_class));
+ min = lttng::bt2::make_value_ref(bt_value_integer_signed_create_init(
+ bt_field_integer_signed_get_value(member_field)));
+ max = lttng::bt2::make_value_ref(bt_value_integer_signed_create_init(
+ bt_field_integer_signed_get_value(member_field)));
+ display_base = lttng::bt2::make_value_ref(bt_value_integer_unsigned_create_init(
+ bt_field_class_integer_get_preferred_display_base(member_class)));
} else if (bt_field_class_type_is(*member_class_type, BT_FIELD_CLASS_TYPE_STRING)) {
- min = bt_value_string_create_init(bt_field_string_get_value(member_field));
- max = bt_value_string_create_init(bt_field_string_get_value(member_field));
+ min = lttng::bt2::make_value_ref(
+ bt_value_string_create_init(bt_field_string_get_value(member_field)));
+ max = lttng::bt2::make_value_ref(
+ bt_value_string_create_init(bt_field_string_get_value(member_field)));
} else if (bt_field_class_type_is(*member_class_type,
BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL)) {
- min = bt_value_real_create_init(
- bt_field_real_double_precision_get_value(member_field));
- max = bt_value_real_create_init(
- bt_field_real_double_precision_get_value(member_field));
+ min = lttng::bt2::make_value_ref(bt_value_real_create_init(
+ bt_field_real_double_precision_get_value(member_field)));
+ max = lttng::bt2::make_value_ref(bt_value_real_create_init(
+ bt_field_real_double_precision_get_value(member_field)));
} else if (bt_field_class_type_is(*member_class_type,
BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL)) {
- min = bt_value_real_create_init(
- bt_field_real_single_precision_get_value(member_field));
- max = bt_value_real_create_init(
- bt_field_real_single_precision_get_value(member_field));
+ min = lttng::bt2::make_value_ref(bt_value_real_create_init(
+ bt_field_real_single_precision_get_value(member_field)));
+ max = lttng::bt2::make_value_ref(bt_value_real_create_init(
+ bt_field_real_single_precision_get_value(member_field)));
} else if (bt_field_class_type_is(*member_class_type, BT_FIELD_CLASS_TYPE_BIT_ARRAY)) {
- min = bt_value_integer_unsigned_create_init(
- bt_field_bit_array_get_value_as_integer(member_field));
- max = bt_value_integer_unsigned_create_init(
- bt_field_bit_array_get_value_as_integer(member_field));
+ min = lttng::bt2::make_value_ref(bt_value_integer_unsigned_create_init(
+ bt_field_bit_array_get_value_as_integer(member_field)));
+ max = lttng::bt2::make_value_ref(bt_value_integer_unsigned_create_init(
+ bt_field_bit_array_get_value_as_integer(member_field)));
} else {
- const auto field_class_type_name = fmt::to_string(*member_class_type);
-
- fmt::print("Unsupported field type for '{}': {}\n", name, field_class_type_name);
- BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
- bt_self_component_sink_as_self_component(self_component_sink),
- "Unsupported field type '%s' for member '%s'",
- field_class_type_name.c_str(),
- name);
-
- return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
+ throw std::runtime_error(lttng::format(
+ "Unsupported field type '{}' for member '{}'", *member_class_type, name));
}
- if (min != nullptr) {
- bt_value_map_insert_entry(member_map, "min", min);
- bt_value_put_ref(min);
+ if (min) {
+ bt_value_map_insert_entry(member_map, "min", min.get());
} else {
- BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
- bt_self_component_sink_as_self_component(self_component_sink),
- "No minimum value for member '%s'",
- name);
- return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
+ throw std::runtime_error(lttng::format("No minimum value for member '{}'", name));
}
- if (max != nullptr) {
- bt_value_map_insert_entry(member_map, "max", max);
- bt_value_put_ref(max);
+
+ if (max) {
+ bt_value_map_insert_entry(member_map, "max", max.get());
} else {
- BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
- bt_self_component_sink_as_self_component(self_component_sink),
- "No maximum value for member '%s'",
- name);
- return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
+ throw std::runtime_error(lttng::format("No maximum value for member '{}'", name));
}
- if (display_base != bt_value_null) {
- bt_value_map_insert_entry(member_map, "display_base", display_base);
- bt_value_put_ref(display_base);
+
+ if (display_base) {
+ bt_value_map_insert_entry(member_map, "display_base", display_base.get());
}
- return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
}
-static bt_component_class_sink_consume_method_status
-member_stats_update_min_max(bt_value *member_map,
- const bt_field_class_structure_member *member,
- const bt_field *member_field,
- const bt_field_class_type *member_class_type,
- bt_self_component_sink *self_component_sink)
+void member_stats_update_min_max(bt_value *member_map,
+ const bt_field_class_structure_member *member,
+ const bt_field *member_field,
+ const bt_field_class_type *member_class_type)
{
const char *name = bt_field_class_structure_member_get_name(member);
bt_value *min = bt_value_map_borrow_entry_value(member_map, "min");
bt_value *max = bt_value_map_borrow_entry_value(member_map, "max");
if (min == nullptr || max == nullptr) {
- BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
- bt_self_component_sink_as_self_component(self_component_sink),
- "Missing min or max value for member '%s'",
- name);
- return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
+ throw std::runtime_error(
+ lttng::format("Missing min or max value for member '{}'", name));
}
if (bt_field_class_type_is(*member_class_type, BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER)) {
- bt_value *value = bt_value_integer_unsigned_create_init(
- bt_field_integer_unsigned_get_value(member_field));
- if (bt_value_integer_unsigned_get(value) < bt_value_integer_unsigned_get(min)) {
- bt_value_integer_unsigned_set(min, bt_value_integer_unsigned_get(value));
+ const auto value = bt_field_integer_unsigned_get_value(member_field);
+
+ if (value < bt_value_integer_unsigned_get(min)) {
+ bt_value_integer_unsigned_set(min, value);
}
- if (bt_value_integer_unsigned_get(value) > bt_value_integer_unsigned_get(max)) {
- bt_value_integer_unsigned_set(max, bt_value_integer_unsigned_get(value));
+
+ if (value > bt_value_integer_unsigned_get(max)) {
+ bt_value_integer_unsigned_set(max, value);
}
- bt_value_put_ref(value);
} else if (bt_field_class_type_is(*member_class_type, BT_FIELD_CLASS_TYPE_SIGNED_INTEGER)) {
- bt_value *value = bt_value_integer_signed_create_init(
- bt_field_integer_signed_get_value(member_field));
- if (bt_value_integer_signed_get(value) < bt_value_integer_signed_get(min)) {
- bt_value_integer_signed_set(min, bt_value_integer_signed_get(value));
+ const auto value = bt_field_integer_signed_get_value(member_field);
+
+ if (value < bt_value_integer_signed_get(min)) {
+ bt_value_integer_signed_set(min, value);
}
- if (bt_value_integer_signed_get(value) > bt_value_integer_signed_get(max)) {
- bt_value_integer_signed_set(max, bt_value_integer_signed_get(value));
+
+ if (value > bt_value_integer_signed_get(max)) {
+ bt_value_integer_signed_set(max, value);
}
- bt_value_put_ref(value);
} else if (bt_field_class_type_is(*member_class_type, BT_FIELD_CLASS_TYPE_STRING)) {
- bt_value *value =
- bt_value_string_create_init(bt_field_string_get_value(member_field));
- if (strcmp(bt_value_string_get(value), bt_value_string_get(min)) < 0) {
- bt_value_string_set(min, bt_value_string_get(value));
+ const auto value = bt_field_string_get_value(member_field);
+
+ if (strcmp(value, bt_value_string_get(min)) < 0) {
+ bt_value_string_set(min, value);
}
- if (strcmp(bt_value_string_get(value), bt_value_string_get(max)) > 0) {
- bt_value_string_set(max, bt_value_string_get(value));
+
+ if (strcmp(value, bt_value_string_get(max)) > 0) {
+ bt_value_string_set(max, value);
}
- bt_value_put_ref(value);
} else if (bt_field_class_type_is(*member_class_type,
BT_FIELD_CLASS_TYPE_DOUBLE_PRECISION_REAL)) {
- bt_value *value = bt_value_real_create_init(
- bt_field_real_double_precision_get_value(member_field));
- if (bt_value_real_get(value) < bt_value_real_get(min)) {
- bt_value_real_set(min, bt_value_real_get(value));
+ const auto value = bt_field_real_double_precision_get_value(member_field);
+
+ if (value < bt_value_real_get(min)) {
+ bt_value_real_set(min, value);
}
- if (bt_value_real_get(value) > bt_value_real_get(max)) {
- bt_value_real_set(max, bt_value_real_get(value));
+
+ if (value > bt_value_real_get(max)) {
+ bt_value_real_set(max, value);
}
- bt_value_put_ref(value);
} else if (bt_field_class_type_is(*member_class_type,
BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL)) {
- bt_value *value = bt_value_real_create_init(
- (double) bt_field_real_single_precision_get_value(member_field));
- if (bt_value_real_get(value) < bt_value_real_get(min)) {
- bt_value_real_set(min, bt_value_real_get(value));
+ const auto value = double(bt_field_real_single_precision_get_value(member_field));
+
+ if (value < bt_value_real_get(min)) {
+ bt_value_real_set(min, value);
}
- if (bt_value_real_get(value) > bt_value_real_get(max)) {
- bt_value_real_set(max, bt_value_real_get(value));
+
+ if (value > bt_value_real_get(max)) {
+ bt_value_real_set(max, value);
}
- bt_value_put_ref(value);
} else if (bt_field_class_type_is(*member_class_type, BT_FIELD_CLASS_TYPE_BIT_ARRAY)) {
- bt_value *value = bt_value_integer_unsigned_create_init(
- bt_field_bit_array_get_value_as_integer(member_field));
- if (bt_value_integer_unsigned_get(value) < bt_value_integer_unsigned_get(min)) {
- bt_value_integer_unsigned_set(min, bt_value_integer_unsigned_get(value));
+ const auto value = bt_field_bit_array_get_value_as_integer(member_field);
+
+ if (value < bt_value_integer_unsigned_get(min)) {
+ bt_value_integer_unsigned_set(min, value);
}
- if (bt_value_integer_unsigned_get(value) > bt_value_integer_unsigned_get(max)) {
- bt_value_integer_unsigned_set(max, bt_value_integer_unsigned_get(value));
+
+ if (value > bt_value_integer_unsigned_get(max)) {
+ bt_value_integer_unsigned_set(max, value);
}
- bt_value_put_ref(value);
} else {
- BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
- bt_self_component_sink_as_self_component(self_component_sink),
- "Unsupported field type '%ld' for member '%s'",
- *member_class_type,
- name);
- return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
+ throw std::runtime_error(lttng::format(
+ "Unsupported field type '%{}' for member '{}'", *member_class_type, name));
}
- return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
}
-static bt_component_class_sink_consume_method_status
+bt_component_class_sink_consume_method_status
update_stats(const bt_message *message,
- field_stats *field_stats,
+ field_stats& field_stats,
bt_self_component_sink *self_component_sink)
{
if (bt_message_get_type(message) != BT_MESSAGE_TYPE_EVENT) {
- /* It's not an error to get non-EVENT messages */
+ /* It's not an error to get non-EVENT messages. */
return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
}
- bt_component_class_sink_consume_method_status status;
- const bt_event *event = bt_message_event_borrow_event_const(message);
- const bt_field *event_payload = bt_event_borrow_payload_field_const(event);
- const bt_event_class *event_class = bt_event_borrow_class_const(event);
- const bt_field_class *event_payload_class =
+ const auto *event = bt_message_event_borrow_event_const(message);
+ const auto *event_payload = bt_event_borrow_payload_field_const(event);
+ const auto *event_class = bt_event_borrow_class_const(event);
+ const auto *event_payload_class =
bt_event_class_borrow_payload_field_class_const(event_class);
- if (field_stats->event_class != nullptr) {
- assert(event_class == field_stats->event_class);
+ if (field_stats.event_class != nullptr) {
+ LTTNG_ASSERT(event_class == field_stats.event_class.get());
} else {
- field_stats->event_class = event_class;
+ bt_event_class_get_ref(event_class);
+ field_stats.event_class.reset(event_class);
}
/* Iterate over each field in the event payload */
- for (uint64_t index = 0;
+ for (std::uint64_t index = 0;
index < bt_field_class_structure_get_member_count(event_payload_class);
index++) {
const bt_field_class_structure_member *member =
bt_field_class_structure_borrow_member_by_index_const(event_payload_class,
index);
- const char *name = bt_field_class_structure_member_get_name(member);
- const bt_field *member_field =
+ const auto *name = bt_field_class_structure_member_get_name(member);
+ const auto *member_field =
bt_field_structure_borrow_member_field_by_name_const(event_payload, name);
- const bt_field_class *member_class =
+ const auto *member_class =
bt_field_class_structure_member_borrow_field_class_const(member);
- const bt_field_class_type member_class_type = bt_field_class_get_type(member_class);
+ const auto member_class_type = bt_field_class_get_type(member_class);
- /* Ignore array and structure field types. */
if (bt_field_class_type_is(member_class_type, BT_FIELD_CLASS_TYPE_ARRAY) ||
bt_field_class_type_is(member_class_type, BT_FIELD_CLASS_TYPE_STRUCTURE)) {
+ /* Ignore array and structure field types. */
continue;
}
- bt_value *member_map =
- bt_value_map_borrow_entry_value(field_stats->stats_value, name);
- if (member_map == nullptr) {
- if (bt_value_map_insert_empty_map_entry(
- field_stats->stats_value, name, &member_map) !=
- BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) {
- BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
- bt_self_component_sink_as_self_component(
- self_component_sink),
- "Failed to insert new empty map entry for field '%s'",
- name);
- return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
- }
-
- status = member_stats_set_min_max(member_map,
- member,
- member_field,
- member_class,
- &member_class_type,
- self_component_sink);
- if (status != BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK) {
- return status;
- }
- } else {
- status = member_stats_update_min_max(member_map,
- member,
- member_field,
- &member_class_type,
- self_component_sink);
- if (status != BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK) {
- return status;
+ try {
+ auto *member_map = bt_value_map_borrow_entry_value(
+ field_stats.stats_value.get(), name);
+ if (member_map == nullptr) {
+ /* Initial creation of the value. */
+ if (bt_value_map_insert_empty_map_entry(
+ field_stats.stats_value.get(), name, &member_map) !=
+ BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK) {
+ throw std::runtime_error(lttng::format(
+ "Failed to insert new empty map entry for field '{}'",
+ name));
+ }
+
+ member_stats_set_min_max(member_map,
+ member,
+ member_field,
+ member_class,
+ &member_class_type);
+ } else {
+ /* Update the value with min/max values. */
+ member_stats_update_min_max(
+ member_map, member, member_field, &member_class_type);
}
+ } catch (const std::exception& ex) {
+ BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
+ bt_self_component_sink_as_self_component(self_component_sink),
+ "%s",
+ ex.what());
+ return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_ERROR;
}
}
+
return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
}
+} /* namespace */
+
+bt_component_class_initialize_method_status
+field_stats_initialize(bt_self_component_sink *self_component_sink,
+ bt_self_component_sink_configuration *,
+ const bt_value *,
+ void *)
+{
+ if (bt_self_component_sink_add_input_port(self_component_sink, "in", nullptr, nullptr) !=
+ BT_SELF_COMPONENT_ADD_PORT_STATUS_OK) {
+ BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
+ bt_self_component_sink_as_self_component(self_component_sink),
+ "Failed to add input port");
+ return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
+ }
+
+ std::unique_ptr<struct field_stats> field_stats;
+ try {
+ field_stats = lttng::make_unique<struct field_stats>();
+ } catch (const bad_alloc_with_msg& ex) {
+ BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
+ bt_self_component_sink_as_self_component(self_component_sink),
+ "%s",
+ ex.what());
+ return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
+ } catch (const std::bad_alloc&) {
+ BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
+ bt_self_component_sink_as_self_component(self_component_sink),
+ "Failed to allocate memory for private data");
+ return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_MEMORY_ERROR;
+ }
+
+ /* Transfer ownership to the component. */
+ bt_self_component_set_data(bt_self_component_sink_as_self_component(self_component_sink),
+ field_stats.release());
+ return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
+}
+
+void field_stats_finalize(bt_self_component_sink *self_component_sink)
+{
+ auto *field_stats = static_cast<struct field_stats *>(bt_self_component_get_data(
+ bt_self_component_sink_as_self_component(self_component_sink)));
+
+ delete field_stats;
+}
+
+bt_component_class_sink_graph_is_configured_method_status
+field_stats_graph_is_configured(bt_self_component_sink *self_component_sink)
+{
+ auto& field_stats = *static_cast<struct field_stats *>(bt_self_component_get_data(
+ bt_self_component_sink_as_self_component(self_component_sink)));
+ auto *input_port =
+ bt_self_component_sink_borrow_input_port_by_index(self_component_sink, 0);
+
+ bt_message_iterator *raw_iterator;
+ if (bt_message_iterator_create_from_sink_component(
+ self_component_sink, input_port, &raw_iterator) !=
+ BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK) {
+ BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_COMPONENT(
+ bt_self_component_sink_as_self_component(self_component_sink),
+ "input port message iterator creation failed");
+ return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_ERROR;
+ }
+
+ field_stats.upstream_iterator.reset(raw_iterator);
+ return BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
+}
bt_component_class_sink_consume_method_status
field_stats_consume(bt_self_component_sink *self_component_sink)
{
- bt_component_class_sink_consume_method_status status;
- struct field_stats *field_stats = (struct field_stats *) bt_self_component_get_data(
- bt_self_component_sink_as_self_component(self_component_sink));
- bt_message_array_const messages;
- uint64_t message_count;
- bt_message_iterator_next_status next_status;
+ auto& field_stats = *static_cast<struct field_stats *>(bt_self_component_get_data(
+ bt_self_component_sink_as_self_component(self_component_sink)));
- assert(field_stats);
- next_status = bt_message_iterator_next(field_stats->iterator, &messages, &message_count);
+ std::uint64_t message_count;
+ bt_message_array_const messages;
+ const auto next_status = bt_message_iterator_next(
+ field_stats.upstream_iterator.get(), &messages, &message_count);
if (next_status != BT_MESSAGE_ITERATOR_NEXT_STATUS_OK) {
if (next_status == BT_MESSAGE_ITERATOR_NEXT_STATUS_END) {
+ /* End reached, print the summary. */
bt_value_map_foreach_entry_const(
- field_stats->stats_value, stats_value_print_summary, nullptr);
- bt_message_iterator_put_ref(field_stats->iterator);
+ field_stats.stats_value.get(), stats_value_print_summary, nullptr);
}
- status = static_cast<bt_component_class_sink_consume_method_status>(next_status);
- goto end;
+
+ return static_cast<bt_component_class_sink_consume_method_status>(next_status);
}
- for (uint64_t index = 0; index < message_count; index++) {
- const bt_message *message = messages[index];
- status = update_stats(message, field_stats, self_component_sink);
- bt_message_put_ref(message);
+ for (std::uint64_t index = 0; index < message_count; index++) {
+ const auto message = lttng::bt2::message_const_ref(messages[index]);
+
+ const auto status = update_stats(message.get(), field_stats, self_component_sink);
if (status != BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK) {
- goto end;
+ return status;
}
}
- status = BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
-end:
- return status;
+
+ return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
}