Fix seek n backward that did not check the end of a trace
[lttv.git] / lttv / lttv / traceset-process.c
index 3f6554d185c37809cb13186f913ccdb4e4683d5f..dc45b17d3a88c043f23f5bdfed06ceae150b7f4f 100644 (file)
@@ -25,7 +25,7 @@
 #include <lttv/event.h>
 #include <babeltrace/context.h>
 #include <babeltrace/iterator.h>
-
+#include <babeltrace/trace-handle.h>
 #include <babeltrace/ctf/events.h>
 #include <babeltrace/ctf/iterator.h>
 
@@ -34,7 +34,7 @@ void lttv_process_traceset_begin(LttvTraceset *traceset,
                LttvHooks *before_trace,
                LttvHooks *event)
 {
-
+       struct bt_iter_pos begin_pos;
        /* simply add hooks in context. _before hooks are called by add_hooks. */
        /* It calls all before_traceset, before_trace, and before_tracefile hooks. */
        lttv_traceset_add_hooks(traceset,
@@ -43,20 +43,6 @@ void lttv_process_traceset_begin(LttvTraceset *traceset,
                                event);
        
 
-}
-
-guint lttv_process_traceset_middle(LttvTraceset *traceset,
-               LttTime end,
-               gulong nb_events,
-               const LttvTracesetPosition *end_position)
-{
-       
-       unsigned count = 0;
-               
-       struct bt_ctf_event *bt_event;
-       
-       LttvEvent event;
-        struct bt_iter_pos begin_pos;
 
        begin_pos.type = BT_SEEK_BEGIN;
 
@@ -65,22 +51,49 @@ guint lttv_process_traceset_middle(LttvTraceset *traceset,
                                         &begin_pos,
                                         NULL);
        }
+}
+
+guint lttv_process_traceset_middle(LttvTraceset *traceset,
+                                       LttTime end,
+                                       gulong nb_events,
+                                       const LttvTracesetPosition *end_position)
+{
+       unsigned count = 0;
+       gint last_ret = 0;
+       LttvTracesetPosition *currentPos;
+        
+       struct bt_ctf_event *bt_event;
+       
+       LttvEvent event;
+  
        while(TRUE) {
 
-               if((count >= nb_events) && (nb_events != G_MAXULONG)) {
+               if(last_ret == TRUE || ((count >= nb_events) && (nb_events != G_MAXULONG))) {
                        break;
                }
 
                if((bt_event = bt_ctf_iter_read_event(traceset->iter)) != NULL) {
+
+                       LttTime time = ltt_time_from_uint64(bt_ctf_get_timestamp(bt_event));
+                       if(ltt_time_compare(end, time) <= 0) {
+                               break;
+                       }
                        
+                       currentPos = lttv_traceset_create_current_position(traceset);
+                       if(lttv_traceset_position_compare(currentPos,end_position ) == 0){
+                               lttv_traceset_destroy_position(currentPos);
+                               break;
+                       }
+                       lttv_traceset_destroy_position(currentPos);
                        count++;
 
                        event.bt_event = bt_event;
-                       /* TODO ybrosseau 2012-04-01: use bt_ctf_get_trace_handle 
-                          to retrieve the right state container */
-                       event.state = traceset->tmpState;
+
+                       /* Retreive the associated state */
+                       event.state = g_ptr_array_index(traceset->state_trace_handle_index,
+                                                       bt_ctf_event_get_handle_id(bt_event));
                        
-                       lttv_hooks_call(traceset->event_hooks, &event);
+                       last_ret = lttv_hooks_call(traceset->event_hooks, &event);
 
                        if(bt_iter_next(bt_ctf_get_iter(traceset->iter)) < 0) {
                                printf("ERROR NEXT\n");
@@ -93,9 +106,6 @@ guint lttv_process_traceset_middle(LttvTraceset *traceset,
                
                }
        }
-       
-
-
        return count;
 }
 
@@ -119,7 +129,6 @@ void lttv_traceset_add_hooks(LttvTraceset *traceset,
                             LttvHooks *before_trace,
                             LttvHooks *event)
 {
-       
        guint i, nb_trace;
 
        LttvTrace *trace;
@@ -143,7 +152,6 @@ void lttv_traceset_remove_hooks(LttvTraceset *traceset,
                                LttvHooks *after_trace,
                                LttvHooks *event)
 {
-
        guint i, nb_trace;
 
        LttvTrace *trace;
@@ -158,6 +166,7 @@ void lttv_traceset_remove_hooks(LttvTraceset *traceset,
 
        }
 
+       lttv_hooks_remove_list(traceset->event_hooks, event);
        lttv_hooks_call(after_traceset, traceset);
 
 
@@ -177,22 +186,134 @@ void lttv_trace_remove_hooks(LttvTrace *trace,
 
 {
        lttv_hooks_call(after_trace, trace);
-
 }
 
 void lttv_process_traceset_seek_time(LttvTraceset *traceset, LttTime start)
 {
-#ifdef WAIT_FOR_BABELTRACE_FIX_SEEK_ZERO
         struct bt_iter_pos seekpos;
         int ret;
+       if (traceset->iter == NULL) {
+               g_warning("Iterator not valid in seek_time");
+               return;
+       }
         seekpos.type = BT_SEEK_TIME;
         seekpos.u.seek_time = ltt_time_to_uint64(start);
-        ret = bt_iter_set_pos(bt_ctf_get_iter(self->iter), &seekpos);
+
+        ret = bt_iter_set_pos(bt_ctf_get_iter(traceset->iter), &seekpos);
         if(ret < 0) {
                 printf("Seek by time error: %s,\n",strerror(-ret));
         }
-#else
-#warning Seek time disabled because of babeltrace bugs
-#endif
+}
+
+guint lttv_process_traceset_seek_n_forward(LttvTraceset *traceset,
+                guint n,
+                check_handler *check,
+                gboolean *stop_flag,
+                LttvFilter *filter1,
+                LttvFilter *filter2,
+                LttvFilter *filter3,
+                gpointer data)
+{
+        unsigned count = 0;
+        while(count < n) {
+               if(bt_iter_next(bt_ctf_get_iter(traceset->iter)) < 0) {
+                       printf("ERROR NEXT\n");
+                       break;
+               }
+               count++;
+        }
+      return count;  
+}
+
+guint lttv_process_traceset_seek_n_backward(LttvTraceset *ts,
+                guint n,
+                gdouble ratio,
+                check_handler *check,
+                gboolean *stop_flag,
+                LttvFilter *filter1,
+                LttvFilter *filter2,
+                LttvFilter *filter3,
+                gpointer data)
+{
+        guint i, count, ret;
+        gint extraEvent = 0;
+        guint64 initialTimeStamp, previousTimeStamp;
+        LttvTracesetPosition *initialPos, *previousPos, *currentPos, beginPos;
+        struct bt_iter_pos pos;
+        beginPos.bt_pos = &pos;
+        beginPos.iter = ts->iter;
+        beginPos.bt_pos->type = BT_SEEK_BEGIN;
+        beginPos.timestamp = G_MAXUINT64;
+        beginPos.cpu_id = INT_MAX;
+        /*Save initial position of the traceset*/
+        initialPos = lttv_traceset_create_current_position (ts);
+        
+        /*Get the timespan of the initial position*/
+        initialTimeStamp = lttv_traceset_position_get_timestamp(initialPos);
+        /* 
+         * Create a position before the initial timestamp according
+         * to the ratio of nanosecond/event hopefully before the
+         * the desired seek position
+         */
+        while(1){
+               previousTimeStamp = initialTimeStamp - n*(guint)ceil(ratio);
+
+               previousPos = lttv_traceset_create_time_position(ts,ltt_time_from_uint64(previousTimeStamp));
+               if(initialTimeStamp == previousTimeStamp)
+                       break;
+                
+                currentPos = lttv_traceset_create_time_position(ts,ltt_time_from_uint64(previousTimeStamp));
+                /*Corner case: When we are near the beginning of the trace and the previousTimeStamp is before
+                        * the beginning of the trace. We have to seek to the first event.
+                        */
+                if((lttv_traceset_position_compare(currentPos,&beginPos ) == 0)){
+                                lttv_traceset_seek_to_position(&beginPos);
+                                break;
+                        }
+                /*move traceset position */
+                lttv_state_traceset_seek_position(ts, previousPos);
+                /* iterate to the initial position counting the number of event*/
+                count = 0;
+                do {
+                        if((ret = lttv_traceset_position_compare(currentPos,initialPos)) == 1){       
+                               if(bt_iter_next(bt_ctf_get_iter(ts->iter)) == 0) {
+                                       if(bt_ctf_iter_read_event(ts->iter) != NULL) {
+                                       lttv_traceset_destroy_position(currentPos);
+                                       currentPos = lttv_traceset_create_current_position(ts);
+                                       count++;
+                                       } else  {
+                                               break;
+                                       }
+                                       
+                               } else {
+
+                                       //No more event available
+                                       break;
+                               }
+                        }
+                }while(ret != 0);
+                
+                /*substract the desired number of event to the count*/
+                extraEvent = count - n;
+                if (extraEvent >= 0) {
+                        //if the extraEvent is over 0 go back to previousPos and 
+                        //move forward the value of extraEvent times
+                        lttv_state_traceset_seek_position(ts, previousPos);
+                        
+                        for(i = 0 ; i < extraEvent ; i++){
+                                if(bt_iter_next(bt_ctf_get_iter(ts->iter)) < 0){
+                                        printf("ERROR NEXT\n");
+                                        break;
+                                }
+                                
+                        }
+                        break; /* we successfully seeked backward */
+                }
+                else{ 
+                        /* if the extraEvent is below 0 create a position before and start over*/  
+                       ratio = ratio * 16;
+                }
+                lttv_traceset_destroy_position(currentPos);
+        }
+        return 0;
 }
This page took 0.025562 seconds and 4 git commands to generate.