* SOFTWARE.
*/
+#define BT_LOG_TAG "PLUGIN-UTILS-TRIMMER-FLT-ITER"
+#include "logging.h"
+
+#include <babeltrace/compat/time-internal.h>
+#include <babeltrace/compat/utc-internal.h>
#include <babeltrace/graph/notification-iterator.h>
#include <babeltrace/graph/private-notification-iterator.h>
#include <babeltrace/graph/notification.h>
#include <babeltrace/graph/private-port.h>
#include <babeltrace/graph/private-connection.h>
#include <babeltrace/graph/private-component.h>
+#include <babeltrace/graph/connection.h>
#include <babeltrace/ctf-ir/event.h>
#include <babeltrace/ctf-ir/stream.h>
#include <babeltrace/ctf-ir/stream-class.h>
#include "iterator.h"
#include "copy.h"
+static
+gboolean close_packets(gpointer key, gpointer value, gpointer user_data)
+{
+ struct bt_ctf_packet *writer_packet = value;
+
+ bt_put(writer_packet);
+ return TRUE;
+}
+
BT_HIDDEN
void trimmer_iterator_finalize(struct bt_private_notification_iterator *it)
{
- struct trimmer_iterator *it_data;
+ struct trimmer_iterator *trim_it;
- it_data = bt_private_notification_iterator_get_user_data(it);
- assert(it_data);
+ trim_it = bt_private_notification_iterator_get_user_data(it);
+ assert(trim_it);
- bt_put(it_data->input_iterator);
- g_hash_table_destroy(it_data->packet_map);
- g_free(it_data);
+ bt_put(trim_it->input_iterator);
+ g_hash_table_foreach_remove(trim_it->packet_map,
+ close_packets, NULL);
+ g_hash_table_destroy(trim_it->packet_map);
+ g_free(trim_it);
}
BT_HIDDEN
enum bt_notification_iterator_status ret =
BT_NOTIFICATION_ITERATOR_STATUS_OK;
enum bt_notification_iterator_status it_ret;
+ enum bt_connection_status conn_status;
struct bt_private_port *input_port = NULL;
struct bt_private_connection *connection = NULL;
struct bt_private_component *component =
connection = bt_private_port_get_private_connection(input_port);
assert(connection);
- it_data->input_iterator =
- bt_private_connection_create_notification_iterator(connection,
- notif_types);
- if (!it_data->input_iterator) {
- ret = BT_NOTIFICATION_ITERATOR_STATUS_NOMEM;
+ conn_status = bt_private_connection_create_notification_iterator(connection,
+ notif_types, &it_data->input_iterator);
+ if (conn_status != BT_CONNECTION_STATUS_OK) {
+ ret = BT_NOTIFICATION_ITERATOR_STATUS_ERROR;
goto end;
}
if (bound->lazy_values.gmt) {
/* Get day, month, year. */
- if (!gmtime_r(&timeval, &tm)) {
- printf_error("Failure in gmtime_r()");
+ if (!bt_gmtime_r(&timeval, &tm)) {
+ BT_LOGE_STR("Failure in bt_gmtime_r()");
goto error;
}
tm.tm_sec = bound->lazy_values.ss;
tm.tm_min = bound->lazy_values.mm;
tm.tm_hour = bound->lazy_values.hh;
- timeval = timegm(&tm);
+ timeval = bt_timegm(&tm);
if (timeval < 0) {
- printf_error("Failure in timegm(), incorrectly formatted %s timestamp",
+ BT_LOGE("Failure in bt_timegm(), incorrectly formatted %s timestamp",
name);
goto error;
}
} else {
/* Get day, month, year. */
- if (!localtime_r(&timeval, &tm)) {
- printf_error("Failure in localtime_r()");
+ if (!bt_localtime_r(&timeval, &tm)) {
+ BT_LOGE_STR("Failure in bt_localtime_r()");
goto error;
}
tm.tm_sec = bound->lazy_values.ss;
tm.tm_hour = bound->lazy_values.hh;
timeval = mktime(&tm);
if (timeval < 0) {
- printf_error("Failure in mktime(), incorrectly formatted %s timestamp",
+ BT_LOGE("Failure in mktime(), incorrectly formatted %s timestamp",
name);
goto error;
}
struct bt_notification *notification,
struct trimmer_iterator *trim_it,
struct trimmer_bound *begin, struct trimmer_bound *end,
- bool *_event_in_range)
+ bool *_event_in_range, bool *finished)
{
int64_t ts;
int clock_ret;
clock_value = bt_ctf_event_get_clock_value(event, clock_class);
if (!clock_value) {
- printf_error("Failed to retrieve clock value");
+ BT_LOGE_STR("Failed to retrieve clock value");
goto error;
}
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");
+ BT_LOGE_STR("Failed to retrieve clock value timestamp");
goto error;
}
if (update_lazy_bound(begin, "begin", ts, &lazy_update)) {
}
if (lazy_update && begin->set && end->set) {
if (begin->value > end->value) {
- printf_error("Unexpected: time range begin value is above end value");
+ BT_LOGE_STR("Unexpected: time range begin value is above end value");
goto error;
}
}
}
if (end->set && ts > end->value) {
in_range = false;
+ *finished = true;
}
goto end;
}
} else {
/* Signed clock values are unsupported. */
+ ret = -1;
goto end;
}
struct bt_notification *notification,
struct trimmer_iterator *trim_it,
struct trimmer_bound *begin, struct trimmer_bound *end,
- bool *_packet_in_range)
+ bool *_packet_in_range, bool *finished)
{
int64_t begin_ns, pkt_begin_ns, end_ns, pkt_end_ns;
bool in_range = true;
}
if (lazy_update && begin->set && end->set) {
if (begin->value > end->value) {
- printf_error("Unexpected: time range begin value is above end value");
+ BT_LOGE_STR("Unexpected: time range begin value is above end value");
goto end_no_notif;
}
}
if (!in_range) {
goto end_no_notif;
}
+ if (pkt_begin_ns > end_ns) {
+ *finished = true;
+ }
if (begin_ns > pkt_begin_ns) {
ret = update_packet_context_field(trim_it->err, writer_packet,
{
enum bt_notification_type type;
struct bt_notification *new_notification = NULL;
+ bool finished = false;
*in_range = true;
type = bt_notification_get_type(*notification);
switch (type) {
case BT_NOTIFICATION_TYPE_EVENT:
new_notification = evaluate_event_notification(*notification,
- trim_it, begin, end, in_range);
+ trim_it, begin, end, in_range, &finished);
break;
case BT_NOTIFICATION_TYPE_PACKET_BEGIN:
case BT_NOTIFICATION_TYPE_PACKET_END:
new_notification = evaluate_packet_notification(*notification,
- trim_it, begin, end, in_range);
+ trim_it, begin, end, in_range, &finished);
break;
case BT_NOTIFICATION_TYPE_STREAM_END:
new_notification = evaluate_stream_notification(*notification,
BT_PUT(*notification);
*notification = new_notification;
+ if (finished) {
+ return BT_NOTIFICATION_ITERATOR_STATUS_END;
+ }
+
return BT_NOTIFICATION_ITERATOR_STATUS_OK;
}