Move to kernel style SPDX license identifiers
[babeltrace.git] / src / bindings / python / bt2 / bt2 / trace_collection_message_iterator.py
index 74417776d07d15170258b931f075cb1516779efc..b9db82cd13716e90f57ff0d6481af8b6013b944f 100644 (file)
@@ -1,24 +1,6 @@
-# The MIT License (MIT)
+# SPDX-License-Identifier: MIT
 #
 # Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
 
 from bt2 import utils, native_bt
 import bt2
@@ -76,7 +58,8 @@ class ComponentSpec(_BaseComponentSpec):
         super().__init__(params, obj, logging_level)
 
         is_cc_object = isinstance(
-            component_class, (bt2._SourceComponentClass, bt2._FilterComponentClass)
+            component_class,
+            (bt2._SourceComponentClassConst, bt2._FilterComponentClassConst),
         )
         is_user_cc_type = isinstance(
             component_class, bt2_component._UserComponentType
@@ -258,15 +241,13 @@ def _get_ns(obj):
 
 
 class _TraceCollectionMessageIteratorProxySink(bt2_component._UserSinkComponent):
-    def __init__(self, params, msg_list):
+    def __init__(self, config, params, msg_list):
         assert type(msg_list) is list
         self._msg_list = msg_list
         self._add_input_port('in')
 
     def _user_graph_is_configured(self):
-        self._msg_iter = self._create_input_port_message_iterator(
-            self._input_ports['in']
-        )
+        self._msg_iter = self._create_message_iterator(self._input_ports['in'])
 
     def _user_consume(self):
         assert self._msg_list[0] is None
@@ -339,6 +320,43 @@ class TraceCollectionMessageIterator(bt2_message_iterator._MessageIterator):
 
         self._build_graph()
 
+    def _compute_stream_intersections(self):
+        # Pre-compute the trimmer range to use for each port in the graph, when
+        # stream intersection mode is enabled.
+        self._stream_inter_port_to_range = {}
+
+        for src_comp_and_spec in self._src_comps_and_specs:
+            # Query the port's component for the `babeltrace.trace-infos`
+            # object which contains the range for each stream, from which we can
+            # compute the intersection of the streams in each trace.
+            query_exec = bt2.QueryExecutor(
+                src_comp_and_spec.spec.component_class,
+                'babeltrace.trace-infos',
+                src_comp_and_spec.spec.params,
+            )
+            trace_infos = query_exec.query()
+
+            for trace_info in trace_infos:
+                begin = max(
+                    [
+                        stream['range-ns']['begin']
+                        for stream in trace_info['stream-infos']
+                    ]
+                )
+                end = min(
+                    [stream['range-ns']['end'] for stream in trace_info['stream-infos']]
+                )
+
+                # Each port associated to this trace will have this computed
+                # range.
+                for stream in trace_info['stream-infos']:
+                    # A port name is unique within a component, but not
+                    # necessarily across all components.  Use a component
+                    # and port name pair to make it unique across the graph.
+                    port_name = str(stream['port-name'])
+                    key = (src_comp_and_spec.comp.addr, port_name)
+                    self._stream_inter_port_to_range[key] = (begin, end)
+
     def _validate_source_component_specs(self, comp_specs):
         for comp_spec in comp_specs:
             if (
@@ -367,49 +385,9 @@ class TraceCollectionMessageIterator(bt2_message_iterator._MessageIterator):
         return msg
 
     def _create_stream_intersection_trimmer(self, component, port):
-        # find the original parameters specified by the user to create
-        # this port's component to get the `inputs` parameter
-        for src_comp_and_spec in self._src_comps_and_specs:
-            if component == src_comp_and_spec.comp:
-                break
-
-        try:
-            inputs = src_comp_and_spec.spec.params['inputs']
-        except Exception as e:
-            raise ValueError(
-                'all source components must be created with an "inputs" parameter in stream intersection mode'
-            ) from e
-
-        params = {'inputs': inputs}
-
-        # query the port's component for the `babeltrace.trace-info`
-        # object which contains the stream intersection range for each
-        # exposed trace
-        query_exec = bt2.QueryExecutor(
-            src_comp_and_spec.comp.cls, 'babeltrace.trace-info', params
-        )
-        trace_info_res = query_exec.query()
-        begin = None
-        end = None
-
-        # find the trace info for this port's trace
-        try:
-            for trace_info in trace_info_res:
-                for stream in trace_info['streams']:
-                    if stream['port-name'] == port.name:
-                        range_ns = trace_info['intersection-range-ns']
-                        begin = range_ns['begin']
-                        end = range_ns['end']
-                        break
-        except Exception:
-            pass
-
-        if begin is None or end is None:
-            raise RuntimeError(
-                'cannot find stream intersection range for port "{}"'.format(port.name)
-            )
-
-        name = 'trimmer-{}-{}'.format(src_comp_and_spec.comp.name, port.name)
+        key = (component.addr, port.name)
+        begin, end = self._stream_inter_port_to_range[key]
+        name = 'trimmer-{}-{}'.format(component.name, port.name)
         return self._create_trimmer(begin, end, name)
 
     def _create_muxer(self):
@@ -500,7 +478,7 @@ class TraceCollectionMessageIterator(bt2_message_iterator._MessageIterator):
         if not self._connect_ports:
             return
 
-        if type(port) is bt2_port._InputPort:
+        if type(port) is bt2_port._InputPortConst:
             return
 
         if component not in [comp.comp for comp in self._src_comps_and_specs]:
@@ -574,6 +552,9 @@ class TraceCollectionMessageIterator(bt2_message_iterator._MessageIterator):
             comp = self._create_comp(comp_spec)
             self._src_comps_and_specs.append(_ComponentAndSpec(comp, comp_spec))
 
+        if self._stream_intersection_mode:
+            self._compute_stream_intersections()
+
         # Now we connect the ports which exist at this point. We allow
         # self._graph_port_added() to automatically connect _new_ ports.
         self._connect_ports = True
This page took 0.024672 seconds and 4 git commands to generate.