Improve parse/solve process for better performance

parent 6c9314bc
......@@ -86,6 +86,7 @@ def main():
source=fetch_mod.LOCAL,
fetchto=".")
# Check if our top_module has been successfully assigned and
# contains a Manifest.py (ModulePool class)
if modules_pool.get_top_module().manifest is None:
......
......@@ -20,6 +20,7 @@
#
import os
import logging
from .util import path as path_mod
......@@ -147,6 +148,8 @@ class DepFile(File):
File.__init__(self, path=file_path, module=module)
self.file_path = file_path
self._rels = set()
self._inputs = set()
self._outputs = set()
self.depends_on = set() # set of files that the file depends on, items of type DepFile
self.dep_level = None
......@@ -158,15 +161,17 @@ class DepFile(File):
self.file_path = file_path
self.include_paths = include_paths
def _parse_if_needed(self):
def parse_if_needed(self):
logging.debug("Parse %s if needed!!!" % self.file_path)
from .new_dep_solver import ParserFactory
if not self.is_parsed:
logging.debug("Not parsed yet, let's go!")
parser = ParserFactory().create(self)
parser.parse(self)
#use proxy template here
def __get_rels(self):
self._parse_if_needed()
#self._parse_if_needed()
return self._rels
def __set_rels(self, what):
......@@ -179,11 +184,11 @@ class DepFile(File):
def satisfies(self, rel_b):
assert isinstance(rel_b, DepRelation)
self._parse_if_needed()
#self._parse_if_needed()
return any(map(lambda x: x.satisfies(rel_b), self.rels))
def show_relations(self):
self._parse_if_needed()
#self._parse_if_needed()
for r in self.rels:
print(str(r))
......
......@@ -188,13 +188,6 @@ class ModulePool(list):
else:
logging.debug("NOT appended to fetch queue: " + str(mod.url))
def solve_dependencies(self):
"""Set dependencies for all project files"""
if not self._deps_solved:
dep_solver.solve(self.build_complete_file_set())
self._deps_solved = True
def build_file_set(self):
from srcfile import SourceFileSet
build_files = SourceFileSet()
......@@ -203,16 +196,23 @@ class ModulePool(list):
def build_complete_file_set(self):
"""Build set of all files listed in the manifests"""
logging.debug("Begin build complete file set")
from .srcfile import SourceFileSet
all_manifested_files = SourceFileSet()
for module in self:
all_manifested_files.add(module.files)
logging.debug("End build complete file set")
return all_manifested_files
def build_limited_file_set(self):
top_entity = self.top_module.top_module
self.solve_dependencies()
#self.solve_dependencies()
all_files = self.build_complete_file_set()
if not self._deps_solved:
logging.debug("- begin solve")
dep_solver.solve(all_files)
logging.debug("- end solve")
self._deps_solved = True
from srcfile import SourceFileSet
source_files = SourceFileSet()
source_files.add(dep_solver.make_dependency_set(all_files, top_entity))
......
......@@ -57,31 +57,45 @@ def solve(fileset):
from .dep_file import DepRelation
assert isinstance(fileset, SourceFileSet)
fset = fileset.filter(DepFile)
#print(fileset)
#print(fset)
not_satisfied = 0
logging.debug("PARSE BEGIN: Here, we will parse all the files in the fileset: no parsing should be done beyond this point")
for investigated_file in fset:
logging.debug("Dependency solver investigates %s (%d relations)" % (investigated_file, len(investigated_file.rels)))
logging.debug("INVESTIGATED FILE: %s" % investigated_file)
investigated_file.parse_if_needed()
logging.debug("PARSE END: now the parsing is done")
logging.debug("SOLVE BEGIN")
for investigated_file in fset:
#logging.info("INVESTIGATED FILE: %s" % investigated_file)
#print(investigated_file.rels)
for rel in investigated_file.rels:
satisfied_by = set()
for dep_file in fset:
if dep_file.satisfies(rel):
if dep_file is not investigated_file:
investigated_file.depends_on.add(dep_file)
satisfied_by.add(dep_file)
if len(satisfied_by) > 1:
logging.warning("Relation %s satisfied by multpiple (%d) files: %s",
str(rel),
len(satisfied_by),
'\n'.join([file.path for file in list(satisfied_by)]))
elif len(satisfied_by) == 0:
logging.warning("Relation %s in %s not satisfied by any source file" % (str(rel), investigated_file.name))
not_satisfied += 1
#logging.info("- relation: %s" % rel)
#logging.info("- direction: %s" % rel.direction)
# Only analyze USE relations, we are looking for dependencies
if rel.direction == DepRelation.USE:
satisfied_by = set()
for dep_file in fset:
if dep_file.satisfies(rel):
if dep_file is not investigated_file:
investigated_file.depends_on.add(dep_file)
satisfied_by.add(dep_file)
if len(satisfied_by) > 1:
logging.warning("Relation %s satisfied by multpiple (%d) files: %s",
str(rel),
len(satisfied_by),
'\n'.join([file.path for file in list(satisfied_by)]))
elif len(satisfied_by) == 0:
logging.warning("Relation %s in %s not satisfied by any source file" % (str(rel), investigated_file.name))
not_satisfied += 1
logging.debug("SOLVE END")
if not_satisfied != 0:
logging.info("Dependencies solved, but %d relations were not satisfied.\n"
"It doesn't necessarily mean that there is some file missing, as it might be defined\n"
"internally in the compiler." % not_satisfied)
logging.warning("Dependencies solved, but %d relations were not satisfied" % not_satisfied)
else:
logging.info("Dependencies solved")
logging.info("Dependencies solved, all of the relations weres satisfied!")
def make_dependency_sorted_list(fileset, purge_unused=True, reverse=False):
......@@ -98,7 +112,7 @@ def make_dependency_sorted_list(fileset, purge_unused=True, reverse=False):
return sorted_list
def make_dependency_set(fileset, top_level_entity):
"""Create a set of all files required to build the named top_level_entity."""
logging.info("Create a set of all files required to build the named top_level_entity.")
from srcfile import SourceFileSet
from dep_file import DepRelation
assert isinstance(fileset, SourceFileSet)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment