/* * * Copyright 2012-2013 University Of Southern California * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.workflowsim.clustering.balancing.methods; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import org.workflowsim.clustering.AbstractArrayList; import org.workflowsim.clustering.TaskSet; /** * ChildAwareHorizontalClsutering is a method that merges a task and its children * * @author Weiwei Chen * @since WorkflowSim Toolkit 1.0 * @date Apr 9, 2013 */ public class ChildAwareHorizontalClustering extends BalancingMethod { /** * Initialize a ChildAwareHorizontalClustering object * @param levelMap the level map * @param taskMap the task map * @param clusterNum the clusters.num */ public ChildAwareHorizontalClustering(Map levelMap, Map taskMap, int clusterNum) { super(levelMap, taskMap, clusterNum); } /** * The main function */ @Override public void run() { Map<Integer, List<TaskSet>> map = getLevelMap(); Map<List<TaskSet>, AbstractArrayList> tmpMap = new HashMap(); for (Map.Entry entry : map.entrySet()) { int depth = (Integer) entry.getKey(); ArrayList<TaskSet> list = (ArrayList) entry.getValue(); AbstractArrayList abList = new AbstractArrayList(list, depth); tmpMap.put(list, abList); } List<AbstractArrayList> abList = new ArrayList(tmpMap.values()); sortMap(abList); for (AbstractArrayList list : abList) { if (!list.hasChecked) { boolean hasClustered = CHBcheckLevel(list.getArrayList()); //Log.printLine("Depth:"+list.getDepth()); if (hasClustered) { list.hasChecked = true; //check its parent levels int depth = list.getDepth(); int i = depth + 1; while (map.containsKey(i)) { List<TaskSet> tsList = map.get(i); CHBcheckLevel(tsList); AbstractArrayList tsAbList = tmpMap.get(tsList); tsAbList.hasChecked = true; i++; } } } } //within each method cleanTaskSetChecked(); } /** * Sort taskSets based on their size * @param list taskSets to be sorted */ private void sortMap(List<AbstractArrayList> list) { Collections.sort(list, new Comparator<AbstractArrayList>() { @Override public int compare(AbstractArrayList l1, AbstractArrayList l2) { return (int) (l2.getArrayList().size() - l1.getArrayList().size()); } }); } /** * Process taskSets level by level * @param taskList to be processed * @return */ private boolean CHBcheckLevel(List<TaskSet> taskList) { boolean hasClustered = false; for (TaskSet setA : taskList) { setA.hasChecked = false;//for safety } for (int i = 0; i < taskList.size(); i++) { TaskSet setA = taskList.get(i); if (!setA.hasChecked) { for (int j = i + 1; j < taskList.size(); j++) { TaskSet setB = taskList.get(j); if (!setB.hasChecked) { TaskSet kid = CHBhasOneParent(setA, setB); if (kid != null) { if (true) {//this condition is that the runtime is fine setA.hasChecked = true;//it does not matter setB.hasChecked = true; addTaskSet2TaskSet(setA, setB); hasClustered = true; } } } } } } return hasClustered; } /** * Checks whether two taskSets have only the same child * @param setA the first taskSet to compare * @param setB the second taskSet to compare * @return whether they have the same child alone */ private TaskSet CHBhasOnlyChild(TaskSet setA, TaskSet setB) { if (setA.getChildList().size() == 1 && setB.getChildList().size() == 1) { TaskSet kidA = setA.getChildList().get(0); TaskSet kidB = setB.getChildList().get(0); if (kidA.equals(kidB)) { return kidA; } } return null; } /** * Checks whether two taskSets have only the same parent * @param setA the first taskSet to compare * @param setB the second taskSet to compare * @return whether they have the same parent alone */ private TaskSet CHBhasOnlyParent(TaskSet setA, TaskSet setB) { if (setA.getParentList().size() == 1 && setB.getParentList().size() == 1) { TaskSet kidA = setA.getParentList().get(0); TaskSet kidB = setB.getParentList().get(0); if (kidA.equals(kidB)) { return kidA; } } return null; } /** * Checks whether two taskSets have one common parent * @param setA the first taskSet to compare * @param setB the second taskSet to compare * @return whether they have the same parent */ private TaskSet CHBhasOneParent(TaskSet setA, TaskSet setB) { for (TaskSet parentA : setA.getParentList()) { for (TaskSet parentB : setB.getParentList()) { if (parentA.equals(parentB)) { return parentA; } } } return null; } }