/** * Sort taskSet based on their impact factors and then merge similar taskSet together * * @param taskList */ @Override public void process(ArrayList<TaskSet> taskList) { if (taskList.size() > getClusterNum()) { ArrayList<TaskSet> jobList = new ArrayList<TaskSet>(); for (int i = 0; i < getClusterNum(); i++) { jobList.add(new TaskSet()); } int clusters_size = taskList.size() / getClusterNum(); if (clusters_size * getClusterNum() < taskList.size()) { clusters_size++; } // sortListDecreasing(taskList); preprocessing(taskList, jobList); for (TaskSet set : taskList) { // sortListIncreasing(jobList); TaskSet job = getCandidateTastSet(jobList, set, clusters_size); addTaskSet2TaskSet(set, job); job.addTask(set.getTaskList()); job.setImpactFafctor(set.getImpactFactor()); // update dependency for (Task task : set.getTaskList()) { getTaskMap().put(task, job); // this is enough // impact factor is not updated } } taskList.clear(); // you sure? } else { // do nothing since } }
private ArrayList<TaskSet> getNextPotentialTaskSets( ArrayList<TaskSet> taskList, TaskSet checkSet, int clusters_size) { int dis = Integer.MAX_VALUE; HashMap map = new HashMap<Integer, ArrayList>(); for (TaskSet set : taskList) { int distance = calDistance(checkSet, set); if (distance < dis) { dis = distance; } if (!map.containsKey(distance)) { map.put(distance, new ArrayList<TaskSet>()); } ArrayList<TaskSet> list = (ArrayList) map.get(distance); if (!list.contains(set)) { list.add(set); } } ArrayList returnList = new ArrayList<TaskSet>(); for (TaskSet set : (ArrayList<TaskSet>) map.get(dis)) { if (set.getTaskList().size() < clusters_size) { returnList.add(set); } } if (returnList.isEmpty()) { returnList.clear(); for (TaskSet set : taskList) { if (set.getTaskList().isEmpty()) { returnList.add(set); return returnList; } } // no empty available while (returnList.isEmpty()) { map.remove(dis); ArrayList<Integer> keys = new ArrayList(map.keySet()); int min = Integer.MAX_VALUE; for (int i : keys) { if (min > i) { min = i; } } dis = min; for (TaskSet set : (ArrayList<TaskSet>) map.get(dis)) { if (set.getTaskList().size() < clusters_size) { returnList.add(set); } } } return returnList; } else { return returnList; } }
private ArrayList preprocessing(ArrayList<TaskSet> taskList, ArrayList<TaskSet> jobList) { int size = taskList.size(); int[] record = new int[size]; for (int i = 0; i < size; i++) { record[i] = -1; } int index_record = 0; int[][] distances = new int[size][size]; for (int i = 0; i < size; i++) { for (int j = 0; j < i; j++) { TaskSet setA = taskList.get(i); TaskSet setB = taskList.get(j); int distance = calDistance(setA, setB); distances[i][j] = distance; } } int job_index = 0; // boolean [] popped = new boolean[size]; ArrayList idList = sortDistanceIncreasing(distances, size, jobList.size()); for (int i = 0; i < idList.size(); i++) { int max_i = (Integer) idList.get(i); record[index_record] = max_i; index_record++; TaskSet set = taskList.get(max_i); TaskSet job = jobList.get(job_index); addTaskSet2TaskSet(set, job); job.addTask(set.getTaskList()); job.setImpactFafctor(set.getImpactFactor()); // update dependency for (Task task : set.getTaskList()) { getTaskMap().put(task, job); // this is enough // impact factor is not updated } job_index++; if (job_index == jobList.size()) { break; } } /** Actually not really necessary because record[i] is already empty */ Arrays.sort(record); for (int i = size - 1; i >= 0 && record[i] >= 0; i--) { taskList.remove(record[i]); } return taskList; }
/** Update task set dependencies */ private void updateTaskSetDependencies() { Collection sets = mTask2TaskSet.values(); for (Iterator it = sets.iterator(); it.hasNext(); ) { TaskSet set = (TaskSet) it.next(); if (!set.hasChecked) { set.hasChecked = true; set.getChildList().clear(); set.getParentList().clear(); for (Task task : set.getTaskList()) { for (Iterator tIt = task.getParentList().iterator(); tIt.hasNext(); ) { Task parent = (Task) tIt.next(); TaskSet parentSet = (TaskSet) mTask2TaskSet.get(parent); if (!set.getParentList().contains(parentSet) && set != parentSet) { set.getParentList().add(parentSet); } } for (Iterator tIt = task.getChildList().iterator(); tIt.hasNext(); ) { Task child = (Task) tIt.next(); TaskSet childSet = (TaskSet) mTask2TaskSet.get(child); if (!set.getChildList().contains(childSet) && set != childSet) { set.getChildList().add(childSet); } } } } } // within each method cleanTaskSetChecked(); }
/** * Calculate the distance between two taskSet one assumption here taskA and taskB are at the same * level because it is horizontal clustering does not work with arbitary workflows * * @param taskA * @param taskB * @return */ private int calDistance(TaskSet taskA, TaskSet taskB) { if (taskA == null || taskB == null || taskA == taskB) { return 0; } LinkedList<TaskSet> listA = new LinkedList<TaskSet>(); LinkedList<TaskSet> listB = new LinkedList<TaskSet>(); int distance = 0; listA.add(taskA); listB.add(taskB); if (taskA.getTaskList().isEmpty() || taskB.getTaskList().isEmpty()) { return Integer.MAX_VALUE; } do { LinkedList<TaskSet> copyA = (LinkedList) listA.clone(); listA.clear(); for (TaskSet set : copyA) { for (TaskSet child : set.getChildList()) { if (!listA.contains(child)) { listA.add(child); } } } LinkedList<TaskSet> copyB = (LinkedList) listB.clone(); listB.clear(); for (TaskSet set : copyB) { for (TaskSet child : set.getChildList()) { if (!listB.contains(child)) { listB.add(child); } } } for (TaskSet set : listA) { if (listB.contains(set)) { return distance * 2; } } distance++; } while (!listA.isEmpty() && !listB.isEmpty()); return distance * 2; }
/** Print out the clustering information. */ private void printOut() { Collection sets = mTask2TaskSet.values(); for (Iterator it = sets.iterator(); it.hasNext(); ) { TaskSet set = (TaskSet) it.next(); if (!set.hasChecked) { set.hasChecked = true; Log.printLine("Job"); for (Task task : set.getTaskList()) { Log.printLine( "Task " + task.getCloudletId() + " " + task.getImpact() + " " + task.getCloudletLength()); } } } // within each method cleanTaskSetChecked(); }
@Override public void run() { if (clusterNum > 0) { for (Iterator it = getTaskList().iterator(); it.hasNext(); ) { Task task = (Task) it.next(); TaskSet set = new TaskSet(); set.addTask(task); mTask2TaskSet.put(task, set); } } remove(); updateTaskSetDependencies(); printMetrics(); String code = Parameters.getClusteringParameters().getCode(); Map<Integer, ArrayList<TaskSet>> map = getCurrentTaskSetAtLevels(); if (code != null) { for (char c : code.toCharArray()) { switch (c) { case 'v': // verticalClustering(); VerticalBalancing v = new VerticalBalancing(map, this.mTask2TaskSet, this.clusterNum); v.run(); break; case 'c': // childAwareHorizontalClustering(); ChildAwareHorizontalClustering ch = new ChildAwareHorizontalClustering(map, this.mTask2TaskSet, this.clusterNum); ch.run(); updateTaskSetDependencies(); break; case 'r': // horizontalRuntimeBalancing(); HorizontalRuntimeBalancing r = new HorizontalRuntimeBalancing(map, this.mTask2TaskSet, this.clusterNum); r.run(); updateTaskSetDependencies(); break; case 'i': HorizontalImpactBalancing i = new HorizontalImpactBalancing(map, this.mTask2TaskSet, this.clusterNum); i.run(); break; case 'd': HorizontalDistanceBalancing d = new HorizontalDistanceBalancing(map, this.mTask2TaskSet, this.clusterNum); d.run(); break; case 'h': HorizontalRandomClustering h = new HorizontalRandomClustering(map, this.mTask2TaskSet, this.clusterNum); h.run(); break; default: break; } } printMetrics(); } printOut(); Collection sets = mTask2TaskSet.values(); for (Iterator it = sets.iterator(); it.hasNext(); ) { TaskSet set = (TaskSet) it.next(); if (!set.hasChecked) { set.hasChecked = true; addTasks2Job(set.getTaskList()); } } // a good habit cleanTaskSetChecked(); updateDependencies(); addClustDelay(); recover(); }