Commit 947faea8 authored by Ayush Tiwari's avatar Ayush Tiwari

bt5_config: Updated reduced function for Business Manager class

parent ceb9a4de
...@@ -231,22 +231,21 @@ class BusinessManager(XMLObject): ...@@ -231,22 +231,21 @@ class BusinessManager(XMLObject):
If l1 > l2, If l1 > l2,
reduce([(p, s, l1, (a, b, c)), (p, s, l2, (d, e))]) = [(p, s, l1, merge(a, b, c))] reduce([(p, s, l1, (a, b, c)), (p, s, l2, (d, e))]) = [(p, s, l1, merge(a, b, c))]
Where the merge is a monotonic commutative function that depends on the type of a, b and c:
if a, b and c are sets, merge = union
if a, b and c are lists, merge = ordered concatenation
if a, b and c are objects, merge = the object created the last
else merge = MAX
A Business Manager BT is said to be reduced if and only if: A Business Manager BT is said to be reduced if and only if:
reduce(BT) = BT reduce(BT) = BT
""" """
path_list = [path_item.getBusinessPath() for path in self._path_item_list] path_list = [path_item.getBusinessPath() for path in self._path_item_list]
reduced_path_item_list = [] reduced_path_item_list = []
# We separate the path list in the ones which are repeated and the ones # We separate the path list in the ones which are repeated and the ones
# which are unique for the installation # which are unique for the installation
seen_path_list = set() seen_path_list = set()
unique_path_list = [x for x in path_list if x not in seen_path_list and not seen_path_list.add(x)] unique_path_list = [x for x
in path_list
if x not in seen_path_list
and not seen_path_list.add(x)]
# Create an extra dict for values on path which are repeated in the path list # Create an extra dict for values on path which are repeated in the path list
seen_path_dict = {path: [] for path in seen_path_list} seen_path_dict = {path: [] for path in seen_path_list}
...@@ -263,25 +262,66 @@ class BusinessManager(XMLObject): ...@@ -263,25 +262,66 @@ class BusinessManager(XMLObject):
# Reduce the values and get the merged result out of it # Reduce the values and get the merged result out of it
for path, path_item_list in seen_path_dict.items(): for path, path_item_list in seen_path_dict.items():
higest_priority_layer = max(path_item_list, attrgetter='_layer') # Create separate list of list items with highest priority
prioritized_path_item = [path_item in path_item_list where \ higest_priority_layer = max(path_item_list, key=attrgetter('_layer'))
path_item._layer==higest_priority_layer] prioritized_path_item = [ path_item for path_item
merged_business_item = prioritized_path_item[0] in path_item_list
if path_item._layer == higest_priority_layer._layer]
# Separate the positive and negative sign path_item
if len(prioritized_path_item) > 1:
if len(prioritized_path_item) != 1: path_item_list_add = [item for item
path_item_list_add = [path_item in path_item_list where path_item._sign > 0 ] in prioritized_path_item
path_item_list_subtract = [path_item in path_item_list where path_item._sign < 0 ] if item._sign > 0 ]
combined_path_item_add = reduce(lambda x, y: x+y, path_item_list_add) path_item_list_subtract = [item for item
combined_path_item_subtract = reduce(lambda x, y: x+y, path_item_list_subtract) in prioritized_path_item
# TODO: Process the intersection for the above mentioned 2 paths. This if item._sign < 0 ]
# would make it easier to install
reduced_path_item_list.append(combined_path_item_add) combined_added_path_item = reduce(lambda x, y: x+y, path_item_list_add)
reduced_path_item_list.append(combined_path_item_subtract) combined_subtracted_path_item = reduce(lambda x, y: x+y, path_item_list_subtract)
added_value = combined_added_path_item._value
subtraced_value = combined_subtracted_path_item._value
if added_value != subtracted_value:
# Append the arithmetically combined path_item objects in the final
# reduced list after removing the intersection
added_value, subtracted_value = \
self._simplifyValueIntersection(added_value, subtracted_value)
combined_added_path_item._value = added_value
combined_subtracted_path_item._value = subtracted_value
# Append the path_item to the final reduced path_item_list after
# doing required arithmetic on it
reduced_path_item_list.append(combined_added_path_item)
reduced_path_item_list.append(combined_subtracted_path_item)
else:
reduced_path_item_list.append(prioritized_path_item[0])
self._path_item_list = reduced_path_item_list self._path_item_list = reduced_path_item_list
self.setStatus('reduced') self.setStatus('reduced')
def _simplifyValueIntersection(self, added_value, subtracted_value):
"""
Returns values for the Business Item having same path and layer after
removing the intersection of the values
Parameters:
added_value - Value for the Business Item having sign = +1
subtracted_value - Value for Busienss Item having sign = -1
"""
built_in_number_type = (int, long, float, complex)
built_in_container_type = (tuple, list, dict, set)
if all(isinstance(added_value, built_in_container_type)) and \
all(isinstance(subtracted_value, built_in_container_type)):
# For all the values of container type, we remove the intersection
pass
class BusinessItem(Implicit, Persistent): class BusinessItem(Implicit, Persistent):
"""Saves the path and values for objects, properties, etc, the """Saves the path and values for objects, properties, etc, the
...@@ -439,8 +479,7 @@ class BusinessItem(Implicit, Persistent): ...@@ -439,8 +479,7 @@ class BusinessItem(Implicit, Persistent):
""" """
if self._path != other._path: if self._path != other._path:
raise ValueError, "BusinessItem are incommensurable, have different path" raise ValueError, "BusinessItem are incommensurable, have different path"
else: elif self._sign != other._sign:
if self._sign != other._sign:
raise ValueError, "BusinessItem are incommensurable, have different sign" raise ValueError, "BusinessItem are incommensurable, have different sign"
else: else:
self._value = self._mergeValue(value_list=[self._value, other._value]) self._value = self._mergeValue(value_list=[self._value, other._value])
...@@ -449,8 +488,16 @@ class BusinessItem(Implicit, Persistent): ...@@ -449,8 +488,16 @@ class BusinessItem(Implicit, Persistent):
def _mergeValue(self, value_list): def _mergeValue(self, value_list):
""" """
Merge value in value list Merge value in value list
merge(a, b, c) : A monotonic commutative function that depends on the
type of a, b and c:
if a, b and c are sets, merge = union
if a, b and c are lists, merge = ordered concatenation
if a, b and c are objects, merge = the object created the last
else merge = MAX
""" """
built_in_number_type = (int, long, float, complex) builtin_number_type = (int, long, float, complex)
# Now, consider the type of both values # Now, consider the type of both values
if all(isinstance(x, builtin_number_type) for x in value_list): if all(isinstance(x, builtin_number_type) for x in value_list):
...@@ -468,9 +515,10 @@ class BusinessItem(Implicit, Persistent): ...@@ -468,9 +515,10 @@ class BusinessItem(Implicit, Persistent):
# XXX: Should we go with creation date or modification_date ?? # XXX: Should we go with creation date or modification_date ??
# TODO: # TODO:
# 1. Add check that the values are ERP5 objects # 1. Add check that the values are ERP5 objects
# 2. In case 2 maximums are created at same time, prefer one with higher # 2. In case 2 maximum values are created at same time, prefer one with
# priority layer # higher priority layer
merged_value = max(value_list, attrgetter='creation_date') merged_value = max([max(value, key=attrgetter('creation_date'))
for value in value_list], key=attrgetter('creation_date'))
return merged_value return merged_value
......
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