示例#1
0
文件: rules.py 项目: woisnow/hue
    def evaluate(self, profile, plan_node_id):
        """
        Evaluate the impact of this cause to the query. The return is a json string with
        this format:
        {
            "impact": the amount of slow down (in ns),
            "message" : the displayed "explanation" string
        }
        :return:
        """
        impact = -1
        if len(self.exprs):
            assert len(self.metric_names) == 1

            # metric_names can have multiple values create a dict for all of
            # them
            db_result = models.query_element_by_metric(profile, 'Summary', self.metric_names[0])
            for k, g in groupby(db_result, lambda x: x.fid):
                grouped = list(g)
                # A list of pairs, with aggregated value and index at value for
                # max / min like exprs
                converted_exprs = self.check_exprs(grouped)
                expr_vars = {
                    "vars": dict(zip(self.exprs, map(lambda x: x[0], converted_exprs))),
                    "idxs": dict(zip(self.exprs, map(lambda x: x[1], converted_exprs))),
                }

                expr_val = exprs.Expr.evaluate(self.rule["expr"], expr_vars)
                if (impact is None or impact < expr_val):
                    impact = expr_val
        else:
            # For each of the metrics get the result
            with Timer() as t:
                # Get the metric values from the db grouped by metric name
                db_result = [models.query_element_by_metric(profile, 'Summary', m) for m in self.metric_names]
                # Assuming that for all metric names the same number of rows have been returned transpose the array
                all_metrics = zip(*db_result)

            for row in all_metrics:
                # Convert to double values if unit is 6(double)
                metric_values = map(lambda x: x.value if x.unit != 6 else to_double(x.value), row)

                local_vars = {"vars": dict(zip(self.metric_names, metric_values))}
                condition = True
                if ("condition" in self.rule):
                    condition = exprs.Expr.evaluate(self.rule["condition"], local_vars)
                if (condition):
                    expr_val = exprs.Expr.evaluate(self.rule["expr"], local_vars)
                    if (impact is None or impact < expr_val):
                        impact = expr_val

        return {
            "impact": impact,
            "message": self.rule["message"],
            "label": self.rule["label"]
        }
示例#2
0
    def evaluate(self, profile, plan_node_id):
        """
        Evaluate the impact of this cause to the query. The return is a json string with
        this format:
        {
            "impact": the amount of slow down (in ns),
            "message" : the displayed "explanation" string
        }
        :return:
        """
        impact = -1
        expr_data = ''
        if len(self.exprs):
            assert len(self.metric_names) == 1

            # metric_names can have multiple values create a dict for all of
            # them
            db_result = models.query_node_by_id(profile, plan_node_id,
                                                self.metric_names[0])
            for k, g in groupby(db_result, lambda x: x.fid):
                grouped = list(g)
                # A list of pairs, with aggregated value and index at value for
                # max / min like exprs
                converted_exprs = self.check_exprs(grouped)
                expr_vars = {
                    "vars":
                    dict(zip(self.exprs, map(lambda x: x[0],
                                             converted_exprs))),
                    "idxs":
                    dict(zip(self.exprs, map(lambda x: x[1],
                                             converted_exprs))),
                }

                expr_val = exprs.Expr.evaluate(self.rule["expr"], expr_vars)
                if (impact is None or impact < expr_val):
                    impact = expr_val
        else:
            # For each of the metrics get the result
            with Timer() as t:
                # Get the metric values from the db grouped by metric name
                db_result = [
                    models.query_node_by_id(profile, plan_node_id, m)
                    for m in self.metric_names
                ]
                # Assuming that for all metric names the same number of rows have been returned transpose the array
                all_metrics = zip(*db_result)

            for row in all_metrics:
                # Convert to double values if unit is 6(double)
                metric_values = map(
                    lambda x: x.value
                    if x.unit != 6 else to_double(x.value), row)

                surrogate_node = row[0].node
                local_vars = {
                    "vars": dict(zip(self.metric_names, metric_values))
                }
                local_vars["vars"]["IOBound"] = self.isStorageBound(
                    surrogate_node)
                local_vars["vars"]['InputRows'] = self.getNumInputRows(
                    surrogate_node)
                condition = True
                if ("condition" in self.rule):
                    condition = exprs.Expr.evaluate(self.rule["condition"],
                                                    local_vars)
                if (condition):
                    expr_val = exprs.Expr.evaluate(self.rule["expr"],
                                                   local_vars)
                    if (impact is None or impact < expr_val):
                        impact = expr_val

            if self.kwargs.get('info_names'):
                db_result = [
                    models.query_element_by_info(profile, plan_node_id, m)
                    for m in self.kwargs['info_names']
                ]
                all_metrics = zip(*db_result)
                for row in all_metrics:
                    metric_values = map(lambda x: x.value, row)
                    local_vars['vars'].update(
                        dict(zip(self.kwargs['info_names'], metric_values)))
                    expr_data = exprs.Expr.evaluate(self.kwargs['fix']['data'],
                                                    local_vars)

        msg = self.rule["label"] + ": " + self.rule["message"]
        return {"impact": impact, "message": msg, "data": expr_data}