Esempio n. 1
0
def update_smt_constraints(pattern_repository, mspl, spl_groups,
                           pattern_added_updated_content, spl_added_list,
                           implicit_use_flag_changed):
    utils.phase_start("Updating the core SMT Constraints")
    # the spls for which we need to recompute the constraint are:
    #  - all spls if the use flag changed
    #      (it is a good enough approximation, and computing the actual set would be far to costly)
    #  - otherwise the added spls and the ones with a reference to the modified patterns
    # additionally, we need to update the SMT of the spl_group of these spls
    #
    # Note about the computation of the set of spl in case of use flag modification:
    #  - we need to update the constraint of all these spls
    #  - plus the ones that depend on these spls (because e.g. some use flags might not exist anymore)
    # too costly
    if implicit_use_flag_changed or (len(pattern_repository) / 2 <
                                     len(pattern_added_updated_content)):
        iterator_spl = mspl.itervalues()
        iterator_spl_group = spl_groups.itervalues()
    else:
        spl_set = set(spl_added_list)
        for pattern in pattern_added_updated_content:
            spl_set.update(pattern_repository[pattern].containing_spl.keys())
        spl_group_set = {spl_groups[spl.group_name] for spl in spl_set}
        iterator_spl = iter(spl_set)
        iterator_spl_group = iter(spl_group_set)

    for spl in iterator_spl:
        spl.reset_smt()
        _ = spl.smt

    for spl_group in iterator_spl_group:
        spl_group.reset_smt()
        _ = spl_group.smt

    utils.phase_end("Updating completed")
Esempio n. 2
0
def missing_externally():
	utils.phase_start("Computing the USE Flags ``Missing Externally''  Statistics.")
	data = {}
	for pattern, el in hyportage_db.flat_pattern_repository.iteritems():
		installable = False
		missing = {}
		for spl in hyportage_pattern.pattern_repository_element_get_spls(el, hyportage_db.mspl, hyportage_db.spl_groups):
			diff = set(hyportage_pattern.pattern_repository_element_get_required_use_required(el)).difference(spl.iuses_default)
			diff.difference_update(hyportage_data.keywords_get_core_set(spl.keywords_list))
			if diff:
				missing[spl.name] = sorted(diff)
			else:
				installable = True
		if missing:
			data[hyportage_pattern.pattern_to_atom(pattern)] = {
				'installable': installable,
				'missing': missing
			}
	res = {
		'pattern_number': len(filter(lambda el: not el['installable'], data.values())),
		'spl_number': len({spl_name for el in data.values() for spl_name in el['missing'].keys()}),
		'use_flag_number': len({use_flag for el in data.values() for use_flags in el['missing'].values() for use_flag in use_flags}),
		'data': data
	}
	global data
	statistics['missing_externally'] = res
	utils.phase_end("Computation Completed")
Esempio n. 3
0
def update_revert_dependencies(pattern_repository, pattern_added_updated,
                               pattern_removed):
    """
	This function resets the cached data in the spls related to the core use flags declared in the pattern.
	Indeed, because the pattern repository changed, the set of core use flags of an spl may change as well.
	:param pattern_repository: the hyportage pattern repository
	:param pattern_added: the patterns that were added to the repository
	:param pattern_updated: the patterns that were changed in the repository
	:param pattern_removed: the patterns that were removed from the repository
	:return: the set of spls whose cache has been reset
	"""
    utils.phase_start("Updating the set of externally required features.")
    updated_spl_list = []
    for pattern in pattern_added_updated:
        pel = pattern_repository[pattern]
        required_uses = pel.required_uses
        for spl in pel.matched_spls:
            if spl.update_revert_dependencies(pattern, required_uses):
                updated_spl_list.append(spl)

    for pattern in pattern_removed:
        pel = pattern_repository[pattern]
        for spl in pel.matched_spls:
            spl.reset_revert_dependencies(pattern)

    utils.phase_end("Updating completed")
    return updated_spl_list
Esempio n. 4
0
def core():
	utils.phase_start("Computing the USE Flags Core Statistics.")
	use_flags_max = 0
	use_flags_sum = 0
	use_flags_min = 100
	spl_min = []
	spl_max = []
	nb_spl = len(hyportage_db.mspl)
	for spl in hyportage_db.mspl.values():
		use_flag_size = len(hyportage_data.spl_get_iuses_default(spl))
		if use_flag_size < use_flags_min:
			use_flags_min = use_flag_size
			spl_min = [spl.name]
		elif use_flag_size == use_flags_min: spl_min.append(spl.name)
		if use_flag_size > use_flags_max:
			use_flags_max = use_flag_size
			spl_max = [spl.name]
		elif use_flag_size == use_flags_max: spl_max.append(spl.name)
		use_flags_sum = use_flags_sum + use_flag_size
	res = {
		'min': use_flags_min,
		'min_spl_list': sorted(spl_min),
		'max': use_flags_max,
		'max_spl_list': sorted(spl_max),
		'number': use_flags_sum,
		'spl_number': nb_spl,
		'average': use_flags_sum / nb_spl,
		'keywords': len(hyportage_db.keywords)
	}
	global data
	statistics['core'] = res
	utils.phase_end("Computation Completed")
Esempio n. 5
0
def run_local_hyvar(json_data, explain_modality, cmd, par_cores):
    """
	Run hyvar locally assuming that there is a command hyvar-rec
	"""
    file_name = utils.get_new_temp_file(".json")
    with open(file_name, "w") as f:
        json.dump(json_data, f)
    cmd.extend([
        "--constraints-minimization", "--features-as-boolean",
        "--no-default-preferences"
    ])
    if explain_modality: cmd.append("--explain")
    if par_cores > 1: cmd.extend(["-p", unicode(par_cores)])
    cmd.append(file_name)

    # executing the solver
    utils.phase_start("Running: " + unicode(cmd))
    process = subprocess.Popen(cmd,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    out, err = process.communicate()
    if process.returncode != 0:
        logging.error("command ended with an error code: " +
                      str(process.returncode))
        return None
    logging.debug("Stderr of the command")
    logging.debug(err)
    utils.phase_end("Execution ended")
    res = json.loads(out)
    return res
Esempio n. 6
0
def save_hyportage(path=config_db_path_default,
                   save_modality=config_db_save_modality_default):
    utils.phase_start("Saving the hyportage database.")
    global pattern_repository, id_repository, mspl, spl_groups
    data = pattern_repository, id_repository, mspl, spl_groups
    utils.store_data_file(path, data, save_modality)
    utils.phase_end("Saving Completed")
Esempio n. 7
0
def update_id_repository(id_repository, changed_ids_spl_set, spl_removed):
    utils.phase_start("Updating the Id Repository")
    for spl in spl_removed:
        id_repository.remove_spl(spl)
    for spl in changed_ids_spl_set:
        id_repository.add_spl(spl)
    utils.phase_end("Generation completed")
Esempio n. 8
0
def dependencies(filter_function=host.scripts.utils.filter_function_simple):
    utils.phase_start("Computing the Dependencies Statistics.")
    visitor = GETGuardedDependenciesVisitor()
    local_map = {
        spl.name: visitor.visitSPL(spl)
        for spl in hyportage_db.mspl.itervalues()
    }

    def extraction_function_all(data):
        return data.keys()

    def extraction_function_guarded(data):
        return {
            pattern
            for pattern in data.iterkeys() if data[pattern]['guarded']
        }

    def extraction_function_selects(data):
        return {
            pattern
            for pattern in data.iterkeys() if data[pattern]['selects']
        }

    global data
    data['dependencies_all'] = generic_map(local_map, extraction_function_all,
                                           filter_function)
    data['dependencies_guarded'] = generic_map(local_map,
                                               extraction_function_guarded,
                                               filter_function)
    data['dependencies_selects'] = generic_map(local_map,
                                               extraction_function_selects,
                                               filter_function)
    utils.phase_end("Computation Completed")
Esempio n. 9
0
def update_use_flag_selection(mspl, spl_added, new_keywords,
                              new_use_flag_config):
    utils.phase_start("Updating the SPL use flag Selection")
    if new_keywords or new_use_flag_config:
        for spl in mspl.itervalues():
            spl.reset_use_selection()
            _ = spl.use_selection_core
    else:
        for spl in spl_added:
            _ = spl.use_selection_core
    utils.phase_end("Generation completed")
Esempio n. 10
0
def pattern_refinement(
        filter_function=host.scripts.utils.filter_function_simple):
    utils.phase_start("Computing the Pattern (refinement) Statistics.")

    def extraction_function(element):
        return element.matched_spls(hyportage_db.mspl, hyportage_db.spl_groups)

    global data
    data['pattern_refinement'] = generic_map(
        hyportage_db.flat_pattern_repository, extraction_function,
        filter_function)
    utils.phase_end("Computation Completed")
Esempio n. 11
0
def graph(filter_function=host.scripts.utils.filter_function_simple):
    utils.phase_start("Computing the Graph Core Statistics.")
    graph_mspl, spl_nodes = graphs.mspl(filter_function, keep_self_loop=True)
    nodes_spl = {node: spl for spl, node in spl_nodes.iteritems()}
    visited = graph_mspl.getBooleanProperty("visited")

    for n in graph_mspl.getNodes():
        visited.setNodeValue(n, False)

    shairplay_len = sys.maxint

    cycles = []
    for n in graph_mspl.getNodes():
        if not visited.getNodeValue(n):
            visited.setNodeValue(n, True)
            path = [n]
            branches = [graph_mspl.getOutNodes(n)]
            if "shairplay" in nodes_spl[n].name: shairplay_len = 1
            while path:
                if len(path) >= shairplay_len:
                    print(str([nodes_spl[node].name for node in path]))
                if branches[-1].hasNext():
                    succ = branches[-1].next()
                    if len(path) >= shairplay_len:
                        print("  found: " + nodes_spl[succ].name)
                    if succ in path:
                        if len(path) >= shairplay_len:
                            print("  loop found: " + str([
                                nodes_spl[node].name
                                for node in path[path.index(succ):]
                            ]))
                        cycles.append([
                            nodes_spl[node].name
                            for node in path[path.index(succ):]
                        ])
                    elif not visited.getNodeValue(succ):
                        visited.setNodeValue(succ, True)
                        path.append(succ)
                        branches.append(graph_mspl.getOutNodes(succ))
                        if "shairplay" in nodes_spl[succ].name:
                            shairplay_len = len(path)
                else:
                    path.pop()
                    branches.pop()
                    if len(path) < shairplay_len: shairplay_len = sys.maxint

    res = generic_map({tuple(v): v
                       for v in cycles}, core_data.identity,
                      host.scripts.utils.filter_function_simple)
    res['cycles'] = cycles
    global data
    data['graph'] = res
    utils.phase_end("Computation Completed")
Esempio n. 12
0
def save_configuration(path=config_db_path_default,
                       save_modality=config_db_save_modality_default):
    utils.phase_start("Saving the hyportage config.")
    global config, mspl_config
    mspl_config.new_masks = False
    mspl_config.new_use_declaration_eapi4 = False
    mspl_config.new_use_declaration_eapi5 = False
    mspl_config.new_keywords_config = False
    mspl_config.new_licenses_config = False
    mspl_config.new_use_flag_config = False
    utils.store_data_file(path, config, save_modality)
    utils.phase_end("Saving Completed")
Esempio n. 13
0
def statistics_pattern(
        filter_function=host.scripts.utils.filter_function_simple):
    utils.phase_start("Computing the Pattern Core Statistics.")
    pattern_number = 0
    pattern_usage = {}
    pattern_usage_max = 0
    for pattern_element in hyportage_db.flat_pattern_repository.itervalues():
        if filter_function(pattern_element):
            pattern_number = pattern_number + 1
            size = len(pattern_element.containing_spl)
            if pattern_usage_max < size:
                pattern_usage_max = size
            if size in pattern_usage:
                pattern_usage[size].extend(pattern_element)
            else:
                pattern_usage[size] = [pattern_element]
    pattern_abstraction_number = 0
    pattern_abstraction_max = [0, []]
    pattern_abstraction_min = [100, []]
    for pattern_element in hyportage_db.flat_pattern_repository.itervalues():
        if filter_function(pattern_element):
            pattern_abstraction_size = len(
                pattern_element.matched_spls(hyportage_db.mspl,
                                             hyportage_db.spl_groups))
            if pattern_abstraction_size < pattern_abstraction_min[0]:
                pattern_abstraction_min[0] = pattern_abstraction_size
                pattern_abstraction_min[1] = [pattern_element]
            elif pattern_abstraction_size == pattern_abstraction_min[0]:
                pattern_abstraction_min[1].append(pattern_element)
            if pattern_abstraction_size > pattern_abstraction_max[0]:
                pattern_abstraction_max[0] = pattern_abstraction_size
                pattern_abstraction_max[1] = [pattern_element]
            elif pattern_abstraction_size == pattern_abstraction_max[0]:
                pattern_abstraction_max[1].append(pattern_element)
            pattern_abstraction_number = pattern_abstraction_number + pattern_abstraction_size

    res = {
        'number': pattern_number,
        'usage': pattern_usage,
        'usage_max': pattern_usage_max,
        'usage_average': pattern_usage_max / pattern_number,
        'total_abstraction_number': pattern_abstraction_number,
        'abstraction_min': pattern_abstraction_min[0],
        'abstraction_min_list': pattern_abstraction_min[1],
        'abstraction_max': pattern_abstraction_max[0],
        'abstraction_max_list': pattern_abstraction_max[1]
    }
    global data
    data['patterns'] = res
    utils.phase_end("Computation Completed")
Esempio n. 14
0
def features_usage(filter_function=host.scripts.utils.filter_function_simple):
    utils.phase_start("Computing the USE Flags Core Statistics.")
    map_features = {}
    for key, value in hyportage_db.mspl.iteritems():
        if filter_function(value):
            for feature in hyportage_data.spl_get_required_iuses(value):
                if feature in map_features: map_features[feature].add(key)
                else: map_features[feature] = {key}

    global data
    data['feature_usage'] = generic_map(map_features, core_data.identity,
                                        filter_function)
    data['feature_usage']['map_data'] = map_features
    utils.phase_end("Computation Completed")
Esempio n. 15
0
def update_visibility(mspl, spl_added, new_masks, new_keywords, new_licenses):
    utils.phase_start("Updating the SPL Visibility")
    if new_masks:
        for spl in mspl.itervalues():
            spl.reset_unmasked()
            spl.generate_visibility_data()
    elif new_keywords or new_licenses:
        for spl in mspl.itervalues():
            spl.reset_unmasked_other()
            spl.generate_visibility_data()
    else:
        for spl in spl_added:
            spl.generate_visibility_data()
    utils.phase_end("Generation completed")
Esempio n. 16
0
def update_mspl_and_groups(mspl, spl_groups, spl_name_set, loaded_spls):
    """
	This function updates the mspl and the spl_groups structures with the newly loaded spls,
	while removing the spl that are not in the portage repository anymore
	:param mspl: the hyportage mspl
	:param spl_groups: the hyportage spl_groups
	:param spl_name_set: the full set of spl names in the portage repository
	:param loaded_spls: the newly loaded spls
	:return: a tuple describing what changed (added spls, removed spls, added spl_groups, updated spl_groups and removed spl_groups)
	Additionally, the mspl and spl_groups in parameter have been updated
	"""
    utils.phase_start("Updating the core hyportage data (mspl, spl_groups).")
    spl_to_add, spl_to_update = [], []
    for spl in loaded_spls:
        if spl.name in mspl: spl_to_update.append((mspl[spl.name], spl))
        else: spl_to_add.append(spl)
    spl_to_remove = [
        spl for spl_name, spl in mspl.iteritems()
        if spl_name not in spl_name_set
    ]

    spl_groups_added = set()
    spl_groups_updated = set()
    spl_groups_removed = set()

    # add the added spls
    for new_spl in spl_to_add:
        hyportage_data.mspl_add_spl(mspl, new_spl)
        added_group = hyportage_data.spl_groups_add_spl(spl_groups, new_spl)
        if added_group is not None: spl_groups_added.add(added_group)

    # update the updated spls
    for old_spl, new_spl in spl_to_update:
        hyportage_data.mspl_update_spl(mspl, old_spl, new_spl)
        spl_groups_updated.add(new_spl.group_name)

    # remove the removed spls
    for old_spl in spl_to_remove:
        hyportage_data.mspl_remove_spl(mspl, old_spl)
        removed_group = hyportage_data.spl_groups_remove_spl(
            spl_groups, old_spl)
        if removed_group is not None: spl_groups_removed.add(removed_group)
    utils.phase_end("Updating completed")
    spl_added_full = loaded_spls
    spl_removed_full = spl_to_remove
    spl_removed_full.extend([el[0] for el in spl_to_update])
    return spl_added_full, spl_removed_full, spl_groups_added, spl_groups_updated, spl_groups_removed
Esempio n. 17
0
def load_hyportage(path=hyportage_db_path_default,
                   save_modality=hyportage_db_save_modality_default):
    utils.phase_start("Loading the hyportage database.")
    global hyportage_db_loaded
    global pattern_repository, id_repository, mspl, spl_groups
    if not hyportage_db_loaded:
        if os.path.exists(path):
            pattern_repository, id_repository, mspl, spl_groups = utils.load_data_file(
                path, save_modality)
        else:
            logging.info("No hyportage database found: creating an empty one")
            pattern_repository = hyportage_pattern.PatternRepository()
            id_repository = hyportage_ids.IDRepository()
            mspl = hyportage_data.mspl_create()
            spl_groups = hyportage_data.spl_groups_create()
        hyportage_db_loaded = True
    utils.phase_end("Loading Completed")
Esempio n. 18
0
def load_config(path=config_db_path_default,
                save_modality=config_db_save_modality_default):
    global config_db_loaded
    global config, mspl_config, keyword_list, installed_packages, world
    utils.phase_start("Loading the hyportage config.")
    if not config_db_loaded:
        if os.path.exists(path):
            config = utils.load_data_file(path, save_modality)
        else:
            logging.info("No config found: creating an empty one")
            config = core_data.Config()
        mspl_config = config.mspl_config
        keyword_list = config.keyword_list
        installed_packages = config.installed_packages
        world = config.world
        config_db_loaded = True
    utils.phase_end("Loading Completed")
Esempio n. 19
0
def load_spl_to_load(concurrent_map, egencache_files_to_load):
    """
	This function loads the spl in the list in parameter
	:param concurrent_map: the map used to parallel the load
	:param egencache_files_to_load: the list of files to load
	:return: the list of loaded spls
	"""
    nb_egencache_files_to_load = len(egencache_files_to_load)
    if nb_egencache_files_to_load > 0:  # load new hyportage spls  from egencache files
        utils.phase_start("Loading the " + str(nb_egencache_files_to_load) +
                          " egencache files.")
        loaded_spls = concurrent_map(
            utils_egencache.create_spl_from_egencache_file,
            egencache_files_to_load)
        utils.phase_end("Loading completed")
    else:
        loaded_spls = []
    return loaded_spls
Esempio n. 20
0
def update_pattern_repository(pattern_repository, spl_added, spl_removed):
    """
	This function updates the pattern repository in input with the newly added spls and the ones removed. In particular,
	this function updates the set of patterns in the repository to only contains those referenced in the mspl,
	and reset the cache of the patterns that are modified by the addition and removal of the spls in parameter
	:param pattern_repository: the pattern repository to update
	:param spl_added: the spls that are added to the mspl
	:param spl_removed: the spls that are removed from the mspl
	:return: the set of patterns that are added, updated and removed during the update
	"""
    utils.phase_start(
        "Updating the pattern hyportage data (pattern_repository).")
    pattern_added, pattern_updated_containing, pattern_removed = \
     __update_pattern_repository_spl_dependencies(pattern_repository, spl_added, spl_removed)
    pattern_updated_content = __update_pattern_repository_reset_pel(
        pattern_repository, spl_added, spl_removed)
    utils.phase_end("Updating completed")
    return pattern_added, pattern_updated_containing, pattern_updated_content, pattern_removed
Esempio n. 21
0
def missing_locally():
	utils.phase_start("Computing the USE Flags ``Missing Locally''  Statistics.")
	data = {}
	for spl in hyportage_db.mspl.values():
		diff = spl.required_iuses_local.difference(spl.iuses_default)
		diff.difference_update(hyportage_data.keywords_get_core_set(spl.keywords_list))
		if diff:
			data[spl.name] = sorted(diff)
	missing_use_flags = {use_flag for use_flags in data.values() for use_flag in use_flags}
	res = {
		'use_flags': sorted(missing_use_flags),
		'use_flag_number': len(missing_use_flags),
		'spl_number': len(data),
		'data': data
	}
	global data
	statistics['missing_locally'] = res
	utils.phase_end("Computation Completed")
Esempio n. 22
0
def reset_implicit_features(mspl, is_eapi4_updated, is_eapi5_updated):
    """
	This function resets the cached data of the spls if the implicit use flags changed
	:param mspl: the hyportage mspl
	:param is_eapi4_updated: if the implicit use fags for eapi4 or less changed
	:param is_eapi5_updated: if the implicit use fags for eapi5 or more changed
	:return: the list of updated spls
	"""
    utils.phase_start("Adding the implicit Features to the spls.")
    updated_spl_list = []
    if is_eapi4_updated or is_eapi5_updated:
        for spl in mspl.itervalues():
            if (spl.eapi < 5) and is_eapi4_updated:
                spl.reset_iuses_full()
                updated_spl_list.append(spl)
            elif (spl.eapi > 4) and is_eapi5_updated:
                spl.reset_iuses_full()
                updated_spl_list.append(spl)
    utils.phase_end("Addition completed")
    return updated_spl_list
Esempio n. 23
0
def run_remote_hyvar(json_data, explain_modality, url):
    """
	Run hyvar
	"""
    if explain_modality: url += "/explain"
    else: url += "/process"
    utils.phase_start("Invoking url: " + url)
    response = requests.post(url,
                             data=json.dumps(json_data),
                             headers={'content-type': 'application/json'})
    utils.phase_end("Execution ended")
    if response.status_code != requests.codes.ok:
        logging.error("server answered with an error code: " +
                      str(response.status_code))
        return None
    res = response.json()
    if 'error' in res:
        logging.error("server answered with an error message: " +
                      json.dumps(res))
        return None
    return res
Esempio n. 24
0
def features(filter_function=host.scripts.utils.filter_function_simple):
    utils.phase_start("Computing the USE Flags Core Statistics.")

    required = sum([
        len(spl.required_iuses) for spl in hyportage_db.mspl.itervalues()
        if filter_function(spl)
    ])
    local = sum([
        len(spl.iuses_default) for spl in hyportage_db.mspl.itervalues()
        if filter_function(spl)
    ])

    global data
    data['features'] = generic_map(hyportage_db.mspl,
                                   hyportage_data.spl_get_iuses_full,
                                   filter_function)
    data['features']['average_required'] = required / float(
        data['features']['number'])
    data['features']['average_local'] = local / float(
        data['features']['number'])
    utils.phase_end("Computation Completed")
Esempio n. 25
0
def compute_to_load(last_update, force, path_egencache_packages):
    """
	This function collects the names of the packages in the portage repository, and lists the ones that need to be loaded
	:param last_update: the date of the last update of the hyportage repository
	:param force: the list of patterns to force to load
	:param path_egencache_packages: the path to the portage repository
	:return: a pair consisting of the list of files to load, plus the set of packages in the portage repository
		(so we know which spl must be removed from hyportage)
	"""
    utils.phase_start("Computing what to do.")
    egencache_files = utils_egencache.get_egencache_files(
        path_egencache_packages)
    if force:
        atom_list = force.split()
        patterns = [
            hyportage_pattern.pattern_create_from_atom(atom)
            for atom in atom_list
        ]

        def filter_function(path_file):
            return filter_egencache_file_full(path_file, last_update, patterns)
    else:

        def filter_function(path_file):
            return filter_egencache_file(path_file, last_update)

    egencache_files_to_load = filter(filter_function, egencache_files)
    logging.info("number of egencache files found: " +
                 str(len(egencache_files)))
    logging.info("number of egencache files to load: " +
                 str(len(egencache_files_to_load)))

    utils.phase_end("Computation completed")
    return egencache_files_to_load, {
        utils_egencache.get_package_name_from_path(f)[0]
        for f in egencache_files
    }