]> git.cworth.org Git - apitrace/blobdiff - common/trace_callset.hpp
Use skiplist-based FastCallSet within trace::CallSet
[apitrace] / common / trace_callset.hpp
index b679d94867b3f095f78b574e07c4075deccafc7e..35729c4cc0f66d81a1534048d5d2f0d00bc5354f 100644 (file)
 #define _TRACE_CALLSET_HPP_
 
 
+#include <limits>
 #include <list>
 
 #include "trace_model.hpp"
-
+#include "trace_fast_callset.hpp"
 
 namespace trace {
 
-
-    // Should match Call::no
-    typedef unsigned CallNo;
-
-
     // Aliases for call flags
     enum {
         FREQUENCY_NONE         = 0,
@@ -106,12 +102,19 @@ namespace trace {
     // A collection of call ranges
     class CallSet
     {
+    private:
+        CallRange limits;
+
     public:
-        // TODO: use binary tree to speed up lookups
+        FastCallSet fast_call_set;
+
+        // TODO: use binary tree to speed up lookups, (less important
+        // now that we are using FastCallSet for ranges without step
+        // or freq).
         typedef std::list< CallRange > RangeList;
         RangeList ranges;
 
-        CallSet() {}
+        CallSet(): limits(std::numeric_limits<CallNo>::min(), std::numeric_limits<CallNo>::max()) {}
 
         CallSet(CallFlags freq);
 
@@ -120,7 +123,7 @@ namespace trace {
         // Not empty set
         inline bool
         empty() const {
-            return ranges.empty();
+            return fast_call_set.empty() && ranges.empty();
         }
 
         void
@@ -128,12 +131,27 @@ namespace trace {
             if (range.start <= range.stop &&
                 range.freq != FREQUENCY_NONE) {
 
-                RangeList::iterator it = ranges.begin();
-                while (it != ranges.end() && it->start < range.start) {
-                    ++it;
+                if (empty()) {
+                    limits.start = range.start;
+                    limits.stop = range.stop;
+                } else {
+                    if (range.start < limits.start)
+                        limits.start = range.start;
+                    if (range.stop > limits.stop)
+                        limits.stop = range.stop;
                 }
 
-                ranges.insert(it, range);
+                /* Optimize by using fast_call_set whenever possible */
+                if (range.step == 1 && range.freq == FREQUENCY_ALL) {
+                    fast_call_set.add(range.start, range.stop);
+                } else {
+                    RangeList::iterator it = ranges.begin();
+                    while (it != ranges.end() && it->start < range.start) {
+                        ++it;
+                    }
+
+                    ranges.insert(it, range);
+                }
             }
         }
 
@@ -142,6 +160,8 @@ namespace trace {
             if (empty()) {
                 return false;
             }
+            if (fast_call_set.contains(callNo))
+                return true;
             RangeList::const_iterator it;
             for (it = ranges.begin(); it != ranges.end() && it->start <= callNo; ++it) {
                 if (it->contains(callNo, callFlags)) {
@@ -155,6 +175,14 @@ namespace trace {
         contains(const trace::Call &call) {
             return contains(call.no, call.flags);
         }
+
+        CallNo getFirst() {
+            return limits.start;
+        }
+
+        CallNo getLast() {
+            return limits.stop;
+        }
     };