Ejemplo n.º 1
0
    def _rewrite_concat(self, node: saldag.Concat):
        """ Concat nodes with more than 1 child can be forked into multiple Concats. """

        if node.requires_mpc():
            node.is_mpc = True
            if len(node.children) > 1 and node.is_boundary():
                fork_node(node)
Ejemplo n.º 2
0
    def _rewrite_concat(self, node: saldag.Concat):
        """
        Concats are always reversible, only need to know if we are
        dealing with a boundary node (in which case it can be computed
        outside of MPC).
        """

        if node.is_lower_boundary():

            out_stored_with = node.out_rel.stored_with
            for par in node.parents:
                if not par.is_root():
                    par.out_rel.stored_with = copy.copy(out_stored_with)
            node.is_mpc = False
Ejemplo n.º 3
0
def fork_node(node: saldag.Concat):
    """
    Concat nodes are often MPC boundaries. This method forks a Concat
    node that has more than one child node into a separate Concat node
    for each of it's children.
    """

    # we can skip the first child
    child_it = enumerate(copy.copy(node.get_sorted_children()))
    next(child_it)
    # clone node for each of the remaining children
    for idx, child in child_it:
        # create clone and rename output relation to
        # avoid identical relation names for different nodes
        clone = copy.deepcopy(node)
        clone.out_rel.rename(node.out_rel.name + "_" + str(idx))
        clone.parents = copy.copy(node.parents)
        warnings.warn("hacky fork_node")
        clone.ordered = copy.copy(node.ordered)
        clone.children = {child}
        for parent in clone.parents:
            parent.children.add(clone)
        node.children.remove(child)
        # make cloned node the child's new parent
        child.replace_parent(node, clone)
        child.update_op_specific_cols()
Ejemplo n.º 4
0
    def _generate_concat(self, concat_op: saldag.Concat):
        """ Generate code for concat operations. """

        in_rel_str = ", ".join(
            [in_rel.dbg_str() for in_rel in concat_op.get_in_rels()])
        return "CONCAT{} [{}] AS {}\n".format(
            "MPC" if concat_op.is_mpc else "", in_rel_str,
            concat_op.out_rel.dbg_str())
Ejemplo n.º 5
0
    def _rewrite_concat(self, node: saldag.Concat):
        """
        Insert a Close op above a Concat node if it's
        parent's stored_with sets do not match it's own.
        """

        assert (not node.is_lower_boundary())

        out_stored_with = node.out_rel.stored_with
        ordered_pars = node.get_sorted_parents()
        for parent in ordered_pars:
            par_stored_with = parent.out_rel.stored_with
            if par_stored_with != out_stored_with:
                out_rel = copy.deepcopy(parent.out_rel)
                out_rel.rename(out_rel.name + "_close")
                out_rel.stored_with = copy.copy(out_stored_with)
                # create and insert close node
                store_op = saldag.Close(out_rel, None)
                store_op.is_mpc = True
                saldag.insert_between(parent, node, store_op)
Ejemplo n.º 6
0
    def _rewrite_concat(self, node: saldag.Concat):
        """ Push down collusion sets for a Concat node. """

        # Copy over columns from existing relation
        out_rel_cols = node.out_rel.columns

        # Combine per-column collusion sets
        for idx, col in enumerate(out_rel_cols):
            columns_at_idx = [
                in_rel.columns[idx] for in_rel in node.get_in_rels()
            ]
            col.coll_sets = utils.coll_sets_from_columns(columns_at_idx)
Ejemplo n.º 7
0
    def _generate_concat(self, concat_op: saldag.Concat):
        """ Generate code for Concat operations. """

        all_rels = concat_op.get_in_rels()
        test = len(all_rels[0].columns)
        assert (all(test == len(rel.columns) for rel in all_rels))

        store_code = ''
        if concat_op.is_leaf():
            store_code += self._generate_store(concat_op)

        template = open(
            "{0}/{1}.tmpl".format(self.template_directory, 'concat'),
            'r').read()

        data = {
            'INRELS': ', '.join(r.name for r in concat_op.get_in_rels()),
            'OUTREL': concat_op.out_rel.name,
            'CACHE_VAR': cache_var(concat_op)
        }

        return pystache.render(template, data) + store_code
Ejemplo n.º 8
0
 def _generate_concat(self, concat_op: ccdag.Concat):
     """ Generate code for Concat operations. """
     in_rel_str = " + ".join(
         [in_rel.name for in_rel in concat_op.get_in_rels()])
     return "{}{} = {}\n".format(self.space, concat_op.out_rel.name,
                                 in_rel_str)