Commit f42cc5ab authored by Nicolas Dumazet's avatar Nicolas Dumazet

Optimize isBuildable towards most common case, i.e. case where

Business Process is in the same direction than the Simulation Tree flow.

First look up simulation tree ancestors to see if movements related
to business path ancestors are indeed in this ancestor set.
Most of the time this check is enough. Conveniently, it's also cheap.

And if we're unlucky and have a Business Process going upwards, we
go through descendants of the movement (which is costly) to check
buildability.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@36588 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 026da3ff
...@@ -567,26 +567,53 @@ class SimulationMovement(Movement, PropertyRecordableMixin): ...@@ -567,26 +567,53 @@ class SimulationMovement(Movement, PropertyRecordableMixin):
# first one, can be built # first one, can be built
return True return True
simulation_movement_list = business_path.getBusinessPathClosure([self])
# store a causality -> causality_related_movement_list mapping # store a causality -> causality_related_movement_list mapping
causality_dict = dict() causality_dict = dict()
for mov in simulation_movement_list:
causality_dict.setdefault(mov.getCausality(), []).append(mov)
# for now only explore ancestors
current = self.getParentValue()
while True:
portal_type = current.getPortalType()
if portal_type == "Simulation Movement":
causality_dict[current.getCausality()] = current
elif portal_type != "Applied Rule":
break
# XXX or maybe directly go up by two levels?
current = current.getParentValue()
parent_path_list = predecessor.getSuccessorRelatedValueList()
remaining_path_list = []
for path in parent_path_list:
related_simulation = causality_dict.get(path.getRelativeUrl())
if related_simulation is None:
remaining_path_list.append(path)
continue
if related_simulation.getDeliveryValue() is None:
return False # related movement is not delivered yet
if related_simulation.getSimulationState() not in \
path.getCompletedStateList():
return False
for parent_path in predecessor.getSuccessorRelatedValueList(): # in 90% of cases, Business Path goes downward and this is enough
causality = parent_path.getRelativeUrl() if not remaining_path_list:
related_simulation_list = causality_dict.get(causality, []) return True
completed_state_list = parent_path.getCompletedStateList() # But sometimes we have to dig deeper
for business_path_movement in related_simulation_list:
business_path_movement_delivery = business_path_movement \ # reset dict
.getDeliveryValue() causality_dict = dict()
if business_path_movement_delivery is None:
return False # related movement is not delivered yet # and explore descendants
if business_path_movement.getSimulationState() not in completed_state_list: for descendant in business_path._recurseGetValueList(self, 'Simulation Movement'):
causality_dict.setdefault(descendant.getCausality(), []).append(descendant)
for path in remaining_path_list:
completed_state_list = path.getCompletedStateList()
for simulation in causality_dict.get(path.getRelativeUrl(), []):
if simulation.getDeliveryValue() is None:
return False return False
if simulation.getSimulationState() not in completed_state_list:
return False
return True return True
def getSolverProcessValueList(self, movement=None, validation_state=None): def getSolverProcessValueList(self, movement=None, validation_state=None):
......
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