Implement the trimmer plug-in
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Sun, 11 Dec 2016 08:54:26 +0000 (03:54 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Sat, 27 May 2017 18:09:08 +0000 (14:09 -0400)
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
plugins/trimmer/iterator.c
plugins/trimmer/iterator.h
plugins/trimmer/trimmer.c
plugins/trimmer/trimmer.h

index 492f3f1a5c83f1e66780d83188f1b1f4caef7337..44a58e43934173c800efbf4f18349b5e8ffee23b 100644 (file)
 #include "trimmer.h"
 #include "iterator.h"
 #include <babeltrace/plugin/notification/iterator.h>
+#include <babeltrace/plugin/notification/notification.h>
+#include <babeltrace/plugin/notification/event.h>
+#include <babeltrace/plugin/notification/stream.h>
+#include <babeltrace/plugin/notification/packet.h>
+#include <babeltrace/plugin/filter.h>
+#include <babeltrace/ctf-ir/event.h>
+#include <babeltrace/ctf-ir/stream.h>
+#include <babeltrace/ctf-ir/stream-class.h>
+#include <babeltrace/ctf-ir/clock.h>
+#include <babeltrace/ctf-ir/packet.h>
+#include <babeltrace/ctf-ir/trace.h>
+#include <assert.h>
+
+static
+void trimmer_iterator_destroy(struct bt_notification_iterator *it)
+{
+       struct trimmer_iterator *it_data;
+
+       it_data = bt_notification_iterator_get_private_data(it);
+       assert(it_data);
+
+       if (it_data->input_iterator_group) {
+               g_ptr_array_free(it_data->input_iterator_group, TRUE);
+       }
+       bt_put(it_data->current_notification);
+       if (it_data->stream_to_packet_start_notification) {
+               g_hash_table_destroy(it_data->stream_to_packet_start_notification);
+       }
+       g_free(it_data);
+}
 
 BT_HIDDEN
 enum bt_component_status trimmer_iterator_init(struct bt_component *component,
                struct bt_notification_iterator *iterator)
 {
-       enum bt_component_status ret;
+       enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
        enum bt_notification_iterator_status it_ret;
+       struct trimmer_iterator *it_data = g_new0(struct trimmer_iterator, 1);
+
+       if (!it_data) {
+               ret = BT_COMPONENT_STATUS_NOMEM;
+               goto end;
+       }
+
+       /* FIXME init trimmer_iterator */
+       it_ret = bt_notification_iterator_set_private_data(iterator, it_data);
+       if (it_ret) {
+               goto end;
+       }
+
+       it_ret = bt_notification_iterator_set_destroy_cb(iterator,
+                       trimmer_iterator_destroy);
+       if (it_ret) {
+               ret = BT_COMPONENT_STATUS_ERROR;
+               goto end;
+       }
 
        it_ret = bt_notification_iterator_set_next_cb(iterator,
                        trimmer_iterator_next);
@@ -65,17 +114,195 @@ BT_HIDDEN
 struct bt_notification *trimmer_iterator_get(
                struct bt_notification_iterator *iterator)
 {
-       return NULL;
+       struct trimmer_iterator *trim_it;
+
+       trim_it = bt_notification_iterator_get_private_data(iterator);
+       assert(trim_it);
+
+       if (!trim_it->current_notification) {
+               enum bt_notification_iterator_status it_ret;
+
+               it_ret = trimmer_iterator_next(iterator);
+               if (it_ret) {
+                       goto end;
+               }
+       }
+end:
+       return bt_get(trim_it->current_notification);
+}
+
+/*
+ * Remove me. This is a temporary work-around due to our inhability to use
+ * libbabeltrace-ctf from libbabeltrace-plugin.
+ */
+static
+struct bt_ctf_stream *internal_bt_notification_get_stream(
+               struct bt_notification *notification)
+{
+       struct bt_ctf_stream *stream = NULL;
+
+       assert(notification);
+       switch (bt_notification_get_type(notification)) {
+       case BT_NOTIFICATION_TYPE_EVENT:
+       {
+               struct bt_ctf_event *event;
+
+               event = bt_notification_event_get_event(notification);
+               stream = bt_ctf_event_get_stream(event);
+               bt_put(event);
+               break;
+       }
+       case BT_NOTIFICATION_TYPE_PACKET_START:
+       {
+               struct bt_ctf_packet *packet;
+
+               packet = bt_notification_packet_start_get_packet(notification);
+               stream = bt_ctf_packet_get_stream(packet);
+               bt_put(packet);
+               break;
+       }
+       case BT_NOTIFICATION_TYPE_PACKET_END:
+       {
+               struct bt_ctf_packet *packet;
+
+               packet = bt_notification_packet_end_get_packet(notification);
+               stream = bt_ctf_packet_get_stream(packet);
+               bt_put(packet);
+               break;
+       }
+       case BT_NOTIFICATION_TYPE_STREAM_END:
+               stream = bt_notification_stream_end_get_stream(notification);
+               break;
+       default:
+               goto end;
+       }
+end:
+       return stream;
+}
+
+/* Return true if the notification should be forwarded. */
+static
+bool evaluate_notification(struct bt_notification *notification,
+               struct trimmer *trimmer, struct trimmer_iterator *it)
+{
+       bool ret = true;
+       struct bt_ctf_clock *clock = NULL;
+       enum bt_notification_type type;
+       struct bt_ctf_trace *trace = NULL;
+       struct bt_ctf_stream *stream = NULL;
+       struct bt_ctf_stream_class *stream_class = NULL;
+       struct bt_ctf_clock_value *clock_value = NULL;
+
+       stream = internal_bt_notification_get_stream(notification);
+       if (!stream) {
+               goto end;
+       }
+
+       stream_class = bt_ctf_stream_get_class(stream);
+       assert(stream_class);
+       trace = bt_ctf_stream_class_get_trace(stream_class);
+       assert(trace);
+
+       type = bt_notification_get_type(notification);
+       switch (type) {
+       case BT_NOTIFICATION_TYPE_EVENT:
+       {
+               int64_t ts;
+               int clock_ret;
+               struct bt_ctf_event *event;
+
+               clock = bt_ctf_trace_get_clock(trace, 0);
+               if (!clock) {
+                       goto end;
+               }
+
+               event = bt_notification_event_get_event(notification);
+               assert(event);
+               clock_value = bt_ctf_event_get_clock_value(event, clock);
+               if (!clock_value) {
+                       printf_error("Failed to retrieve clock value\n");
+                       bt_put(event);
+                       goto end;
+               }
+
+               clock_ret = bt_ctf_clock_value_get_value_ns_from_epoch(
+                               clock_value, &ts);
+               if (clock_ret) {
+                       printf_error("Failed to retrieve clock value timestamp\n");
+                       goto end;
+               }
+
+               if (trimmer->begin.set && ts < trimmer->begin.value) {
+                       ret = false;
+               }
+               if (trimmer->end.set && ts > trimmer->end.value) {
+                       ret = false;
+               }
+               break;
+       }
+       default:
+               break;
+       }
+end:
+       bt_put(clock);
+       bt_put(trace);
+       bt_put(stream);
+       bt_put(clock_value);
+       return ret;
 }
 
 BT_HIDDEN
 enum bt_notification_iterator_status trimmer_iterator_next(
                struct bt_notification_iterator *iterator)
 {
-       enum bt_notification_iterator_status ret;
+       struct trimmer_iterator *trim_it = NULL;
+       struct bt_component *component = NULL;
+       struct trimmer *trimmer = NULL;
+       struct bt_notification_iterator *source_it = NULL;
+       enum bt_notification_iterator_status ret =
+                       BT_NOTIFICATION_ITERATOR_STATUS_OK;;
+       enum bt_component_status component_ret;
+       bool event_in_range = false;
 
-       ret = BT_NOTIFICATION_ITERATOR_STATUS_OK;
+       trim_it = bt_notification_iterator_get_private_data(iterator);
+       assert(trim_it);
+
+       component = bt_notification_iterator_get_component(iterator);
+       assert(component);
+       trimmer = bt_component_get_private_data(component);
+       assert(trimmer);
+
+       /* FIXME, should handle input iterator groups. */
+       component_ret = bt_component_filter_get_input_iterator(component, 0,
+                       &source_it);
+       assert((component_ret == BT_COMPONENT_STATUS_OK) && source_it);
+
+       while (!event_in_range) {
+               struct bt_notification *notification;
+
+               ret = bt_notification_iterator_next(source_it);
+               if (ret != BT_NOTIFICATION_ITERATOR_STATUS_OK) {
+                       goto end;
+               }
+
+               notification = bt_notification_iterator_get_notification(
+                               source_it);
+               if (!notification) {
+                       ret = BT_NOTIFICATION_ITERATOR_STATUS_ERROR;
+                       goto end;
+               }
+
+               event_in_range = evaluate_notification(notification, trimmer,
+                               trim_it);
+               if (event_in_range) {
+                       BT_MOVE(trim_it->current_notification, notification);
+               } else {
+                       bt_put(notification);
+               }
+       }
 end:
+       bt_put(source_it);
+       bt_put(component);
        return ret;
 }
 
index c32b498d1384c587a15a1c62d0d71527699fd005..a517b1f03e77118e71c993e31f5c88d022a54943 100644 (file)
  */
 
 #include "trimmer.h"
+#include <babeltrace/plugin/notification/notification.h>
+
+struct trimmer_iterator {
+       /* Input iterators associated with this output iterator. */
+       GPtrArray *input_iterator_group;
+       struct bt_notification *current_notification;
+       GHashTable *stream_to_packet_start_notification;
+};
 
 BT_HIDDEN
 enum bt_component_status trimmer_iterator_init(
index 7e6f024c94a0c368688fb55be6b096f38840dc81..23fe713481e67676941545bfe2db5e514b90cf14 100644 (file)
@@ -34,6 +34,7 @@
 #include <babeltrace/plugin/notification/event.h>
 #include "trimmer.h"
 #include "iterator.h"
+#include <assert.h>
 
 static
 void destroy_trimmer_data(struct trimmer *trimmer)
@@ -62,6 +63,39 @@ void destroy_trimmer(struct bt_component *component)
        destroy_trimmer_data(data);
 }
 
+static
+void init_from_params(struct trimmer *trimmer, struct bt_value *params)
+{
+       struct bt_value *value = NULL;
+
+       assert(params);
+
+        value = bt_value_map_get(params, "begin_ns_epoch");
+       if (value && bt_value_is_integer(value)) {
+               enum bt_value_status value_ret;
+
+               value_ret = bt_value_integer_get(value, &trimmer->begin.value);
+               if (!value_ret) {
+                       trimmer->begin.set = true;
+               } else {
+                       printf_error("Failed to retrieve begin_ns_epoch value\n");
+               }
+       }
+       bt_put(value);
+        value = bt_value_map_get(params, "end_ns_epoch");
+       if (value && bt_value_is_integer(value)) {
+               enum bt_value_status value_ret;
+
+               value_ret = bt_value_integer_get(value, &trimmer->end.value);
+               if (!value_ret) {
+                       trimmer->end.set = true;
+               } else {
+                       printf_error("Failed to retrieve end_ns_epoch value\n");
+               }
+       }
+       bt_put(value);
+}
+
 enum bt_component_status trimmer_component_init(
        struct bt_component *component, struct bt_value *params)
 {
@@ -89,6 +123,8 @@ enum bt_component_status trimmer_component_init(
        if (ret != BT_COMPONENT_STATUS_OK) {
                goto error;
        }
+
+       init_from_params(trimmer, params);
 end:
        return ret;
 error:
@@ -97,7 +133,7 @@ error:
 }
 
 /* Initialize plug-in entry points. */
-BT_PLUGIN_NAME("trimmer");
+BT_PLUGIN_NAME("utils");
 BT_PLUGIN_DESCRIPTION("Babeltrace Trace Trimmer Plug-In.");
 BT_PLUGIN_AUTHOR("Jérémie Galarneau");
 BT_PLUGIN_LICENSE("MIT");
index 9f4a34af915273bf98bbf335316692471873f68a..28bb1e2f1fd24076061820a7b498c1cc39e3289d 100644 (file)
 #include <babeltrace/plugin/component.h>
 #include <babeltrace/plugin/plugin-system.h>
 
+struct trimmer_bound {
+       int64_t value;
+       bool set;
+};
+
 struct trimmer {
-       int64_t range_start, range_end;
+       struct trimmer_bound begin, end;
 };
 
 #endif /* BABELTRACE_PLUGIN_TRIMMER_H */
This page took 0.029225 seconds and 4 git commands to generate.