Changeset 1851


Ignore:
Timestamp:
12/23/14 11:34:43 (10 years ago)
Author:
pharms
Message:
  • complete refactoring to improve performance and to fix diverse bugs.
  • now really all tasks are compared with each other
  • as diff is not commutative, comparison is now done in both directions and best comparison result is used as basis for merging
  • filter for parent tasks is now deterministic
  • filter for first to merge based on mergable level of similarity is now correct
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/utils/MostSimilarTaskDeterminer.java

    r1767 r1851  
    1515package de.ugoe.cs.autoquest.tasktrees.temporalrelation.utils; 
    1616 
    17 import java.util.ArrayList; 
    1817import java.util.HashMap; 
    1918import java.util.HashSet; 
     
    2524import java.util.logging.Level; 
    2625 
    27 import de.ugoe.cs.autoquest.tasktrees.temporalrelation.TaskInstanceComparator; 
     26import de.ugoe.cs.autoquest.tasktrees.temporalrelation.TaskComparator; 
    2827import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskTraversingVisitor; 
     28import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance; 
     29import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance; 
    2930import de.ugoe.cs.autoquest.tasktrees.treeifc.IStructuringTemporalRelationship; 
    3031import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; 
    3132import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo; 
     33import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance; 
     34import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList; 
    3235import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel; 
    3336import de.ugoe.cs.autoquest.tasktrees.treeifc.TaskMetric; 
     
    6164     
    6265    /** 
    63      * default indicator for unequal tasks 
    64      */ 
    65     private static final SimilarTasks UNEQUAL_TASKS = new SimilarTasks(null, null, null, null, null); 
    66      
    67     /** 
    6866     * task comparator used internally 
    6967     */ 
    70     private TaskInstanceComparator comparator; 
     68    private TaskComparator comparator; 
    7169     
    7270    /** 
     
    7573     */ 
    7674    private Set<Long> comparisonsToSkip = new HashSet<>(); 
     75     
     76    /** TODO comment */ 
     77    private long comparisonCounter = 0; 
    7778 
    7879    /** 
    7980     * Initialize instances of this class with the task comparator to be used 
    8081     */ 
    81     public MostSimilarTaskDeterminer(TaskInstanceComparator comparator) { 
     82    public MostSimilarTaskDeterminer(TaskComparator comparator) { 
    8283        this.comparator = comparator; 
    8384    } 
     
    9596     */ 
    9697    public List<SimilarTasks> getMostSimilarTasks(List<ITask> tasks, ITaskModel taskModel) { 
    97         Console.println("comparing " + tasks.size() + " tasks with each other"); 
    98  
    99         LinkedList<SimilarTasks> mostSimilarTasksList = performComparisons(tasks); 
     98        Console.println("comparing " + tasks.size() + " sequences with each other"); 
     99 
     100        LinkedList<SimilarTasks> mostSimilarTasksList = performComparisons(taskModel, tasks); 
     101         
     102        Console.println("initially found " + mostSimilarTasksList.size() + " similar sequences"); 
    100103         
    101104        applyFilterForSmallestDiffLevel(mostSimilarTasksList); 
     105         
     106        Console.println("only " + mostSimilarTasksList.size() + " have the smallest diff level"); 
     107         
    102108        applyFilterForParents(mostSimilarTasksList); 
     109         
     110        Console.println(mostSimilarTasksList.size() + " remain after filtering for parents"); 
     111         
    103112        applyFilterForMostCoveredEvents(mostSimilarTasksList, taskModel); 
    104113         
    105         Console.traceln 
    106             (Level.FINER, "calculated " + mostSimilarTasksList.size() + " most similar tasks"); 
     114        Console.println("calculated " + mostSimilarTasksList.size() + " most similar sequences"); 
    107115 
    108116        return mostSimilarTasksList; 
     
    147155        // generated through this rule 
    148156        Iterator<SimilarTasks> listIterator = mostSimilarTasksList.iterator(); 
     157        List<SimilarTasks> similarTasksToRemove = new LinkedList<SimilarTasks>(); 
    149158     
    150159        while (listIterator.hasNext()) { 
     
    161170                    TaskTreeUtils.isChild(task4, task2)) 
    162171                { 
     172                    similarTasksToRemove.add(candidate); 
     173                    break; 
     174                } 
     175            } 
     176        } 
     177         
     178        listIterator = mostSimilarTasksList.iterator(); 
     179         
     180        while (listIterator.hasNext()) { 
     181            SimilarTasks candidate = listIterator.next(); 
     182             
     183            for (SimilarTasks toRemove : similarTasksToRemove) { 
     184                if (candidate == toRemove) { 
    163185                    listIterator.remove(); 
    164                     break; 
    165186                } 
    166187            } 
     
    204225            mostSimilarTasksList.clear(); 
    205226 
    206             System.out.println("several comparisons for the same task exist with same diff level " + 
    207                                "--> filtering for pair to be merged first"); 
     227            Console.traceln(Level.FINEST, "several comparisons for the same task exist with " + 
     228                            "same diff level --> filtering for pair to be merged first"); 
    208229 
    209230            SimilarTasks firstToMerge = null; 
     
    285306        // depth is equal. Calculate for both the similarity 
    286307        // based on which the merging will take place  
    287         valFirst = 
    288             SimilarTasks.getMergableLevelOfSimilarity(first, comparator).getDiffLevel(); 
    289         valSecond = 
    290             SimilarTasks.getMergableLevelOfSimilarity(second, comparator).getDiffLevel(); 
    291  
    292         if (valSecond > valFirst) { 
     308        SimilarTasks tmp = SimilarTasks.getMergableLevelOfSimilarity(first, comparator); 
     309        valFirst = tmp != null ? tmp.getDiffLevel() : Integer.MAX_VALUE; 
     310             
     311        tmp = SimilarTasks.getMergableLevelOfSimilarity(second, comparator); 
     312        valSecond = tmp != null ? tmp.getDiffLevel() : Integer.MAX_VALUE; 
     313 
     314        if (valSecond < valFirst) { 
    293315            return second; 
    294316        } 
    295         else if (valSecond < valFirst) { 
     317        else if (valSecond > valFirst) { 
    296318            return first; 
    297319        } 
     
    325347     * starts several threads performing the task comparisons 
    326348     */ 
    327     private LinkedList<SimilarTasks> performComparisons(List<ITask> tasks) { 
     349    private LinkedList<SimilarTasks> performComparisons(ITaskModel taskModel, List<ITask> tasks) { 
    328350        LinkedList<SimilarTasks> mostSimilarTasks = new LinkedList<SimilarTasks>(); 
    329351        List<Runnable> startedRunnables = new LinkedList<Runnable>(); 
    330         List<Runnable> runnables = createRunnables(tasks, mostSimilarTasks, startedRunnables); 
    331  
    332         // create Runnables for all buckets 
    333         int noOfParallelThreads = Math.min(2, runnables.size()); 
    334          
    335         Console.traceln(Level.FINER, "will start " + runnables.size() + " threads"); 
    336          
    337         // start the Threads, wait for their completion, and start the next ones if there are 
    338         // remaining 
     352 
     353        comparisonCounter = 0; 
     354         
     355        // groups size is minimal 100 or maximal 1000 
     356        int groupSize = Math.max 
     357            (100, Math.min(3000, 1 + (tasks.size() / Runtime.getRuntime().availableProcessors()))); 
     358         
    339359        synchronized (startedRunnables) { 
    340             while ((runnables.size() > 0) || (startedRunnables.size() > 0)) { 
    341                 while ((startedRunnables.size() < noOfParallelThreads) && (runnables.size() > 0)) { 
    342                     Runnable runnable = runnables.remove(0); 
     360            int start1 = 0; 
     361            int end1; 
     362            int start2; 
     363            int end2; 
     364             
     365            do { 
     366                end1 = Math.min(start1 + groupSize, tasks.size()); 
     367                TaskTraversal[] leftHandTraversals = new TaskTraversal[end1 - start1]; 
     368                 
     369                Console.traceln(Level.FINE, "calculating left hand traversals from " + start1 + 
     370                                " to " + end1); 
     371                 
     372                int index = 0; 
     373                for (int j = start1; j < end1; j++) { 
     374                    leftHandTraversals[index++] = 
     375                        TaskTraversal.getTraversal(tasks.get(j), null); 
     376                } 
     377 
     378                start2 = 0; 
     379                do { 
     380                    end2 = Math.min(start2 + groupSize, end1 - 1); 
     381                    TaskTraversal[] rightHandTraversals = new TaskTraversal[end2 - start2]; 
     382 
     383                    if (end2 <= start1) { 
     384                        Console.traceln(Level.FINE, "calculating right hand traversals from " + 
     385                                        start2 + " to " + end2); 
     386                         
     387                        // traversals need to be created 
     388                        index = 0; 
     389                        for (int j = start2; j < end2; j++) { 
     390                            rightHandTraversals[index++] = 
     391                                TaskTraversal.getTraversal(tasks.get(j), null); 
     392                        } 
     393                         
     394                    } 
     395                    else { 
     396                        // traversals can be reused 
     397                        Console.traceln(Level.FINE, "reusing traversals for right hand from " + 
     398                                        start2 + " to " + end2); 
     399                         
     400                        rightHandTraversals = leftHandTraversals; 
     401                    } 
     402                     
     403                    Runnable runnable = new CompareRunnable(taskModel, leftHandTraversals, 
     404                                                            rightHandTraversals, 
     405                                                            mostSimilarTasks, startedRunnables); 
     406                     
     407                    while (startedRunnables.size() >=  
     408                               Math.max(1, Runtime.getRuntime().availableProcessors())) 
     409                    { 
     410                        try { 
     411                            Console.traceln(Level.FINER, "waiting for next thread to finish"); 
     412                            startedRunnables.wait(); 
     413                            Console.traceln(Level.FINER, "thread finished"); 
     414                        } 
     415                        catch (InterruptedException e) { 
     416                            // should not happen 
     417                            Console.logException(e); 
     418                        } 
     419                    } 
     420                 
     421                    Console.traceln(Level.FINER, "starting next thread"); 
    343422                    startedRunnables.add(runnable); 
    344423                    new Thread(runnable).start(); 
    345                     Console.traceln(Level.FINEST, "started next thread"); 
    346                 } 
    347             
     424                    Console.traceln(Level.FINER, "started next thread " + runnable); 
     425                     
     426                    start2 = end2; 
     427                } 
     428                while (end2 < (end1 - 1)); 
     429                 
     430                start1 = end1; 
     431            } 
     432            while (end1 < tasks.size()); 
     433             
     434             
     435            while (startedRunnables.size() > 0) { 
    348436                try { 
     437                    Console.traceln(Level.FINER, "waiting for next thread to finish"); 
    349438                    startedRunnables.wait(); 
     439                    Console.traceln(Level.FINER, "thread finished"); 
    350440                } 
    351441                catch (InterruptedException e) { 
     
    353443                    Console.logException(e); 
    354444                } 
    355  
    356                 Console.traceln(Level.FINEST, "thread finished (" + runnables.size() + ", " + 
    357                                 startedRunnables.size() + ")"); 
    358             } 
    359         } 
    360         Console.traceln(Level.FINER, "all threads finished"); 
     445            } 
     446        } 
     447         
     448        Console.traceln 
     449            (Level.FINER, "all threads finished, " + comparisonCounter + " comparisons done"); 
     450         
     451        if (comparisonCounter != (((tasks.size() - 1) * tasks.size()) / 2)) { 
     452            throw new RuntimeException(comparisonCounter + "  " + 
     453                                       (((tasks.size() - 1) * tasks.size()) / 2)); 
     454        } 
    361455         
    362456        return mostSimilarTasks; 
    363     } 
    364  
    365     /** 
    366      * creates runnables for comparing tasks by subdiving the input set of comparisons into  
    367      * several subsets where each is compared in a corresponding runnable. The subsets are 
    368      * at most 150000 comparisons large. 
    369      */ 
    370     private List<Runnable> createRunnables(List<ITask>              tasks, 
    371                                            LinkedList<SimilarTasks> mostSimilarTasksList, 
    372                                            List<Runnable>           startedRunnables) 
    373     { 
    374         // subdivide comparisons into buckets to be spread to different threads 
    375         int noOfComparisons = 0; 
    376         int noOfScheduledComparisons = 0; 
    377         List<Integer> bucketIndexes = new ArrayList<Integer>(); 
    378          
    379         bucketIndexes.add(0); 
    380          
    381         for (int i = 0; i < tasks.size(); i++) { 
    382             noOfComparisons += i; 
    383              
    384             if ((noOfComparisons - noOfScheduledComparisons) > 150000) { 
    385                 bucketIndexes.add(i); 
    386                 noOfScheduledComparisons = noOfComparisons; 
    387             } 
    388         } 
    389          
    390         bucketIndexes.add(tasks.size()); 
    391          
    392         Console.traceln(Level.FINER, "scheduling " + noOfComparisons + " comparisons"); 
    393          
    394         List<Runnable> runnables = new LinkedList<Runnable>(); 
    395          
    396         for (int i = 1; i < bucketIndexes.size(); i++) { 
    397             CompareRunnable runnable = new CompareRunnable 
    398                 (tasks, bucketIndexes.get(i - 1), bucketIndexes.get(i), mostSimilarTasksList, 
    399                  startedRunnables); 
    400              
    401             runnables.add(runnable); 
    402         } 
    403          
    404         return runnables; 
    405457    } 
    406458 
     
    468520 
    469521        /** */ 
    470         private List<ITask> taskList; 
     522        private ITaskModel taskModel; 
    471523         
    472524        /** */ 
    473         private int startIndex; 
     525        private TaskTraversal[] leftHandTraversals; 
    474526         
    475527        /** */ 
    476         private int endIndex; 
    477  
     528        private TaskTraversal[] rightHandTraversals; 
     529         
    478530        /** */ 
    479531        private List<SimilarTasks> mostSimilarTasksList; 
     
    485537         * 
    486538         */ 
    487         public CompareRunnable(List<ITask>         taskList, 
    488                                int                 startIndex, 
    489                                int                 endIndex, 
    490                                List<SimilarTasks>  mostSimilarTasksList, 
    491                                List<Runnable>      unfinishedRunnables) 
     539        public CompareRunnable(ITaskModel         taskModel, 
     540                               TaskTraversal[]    leftHandTraversals, 
     541                               TaskTraversal[]    rightHandTraversals, 
     542                               List<SimilarTasks> mostSimilarTasksList, 
     543                               List<Runnable>     unfinishedRunnables) 
    492544        { 
    493             this.taskList = taskList; 
    494             this.startIndex = startIndex; 
    495             this.endIndex = endIndex; 
     545            this.taskModel = taskModel; 
     546            this.leftHandTraversals = leftHandTraversals; 
     547            this.rightHandTraversals = rightHandTraversals; 
    496548            this.mostSimilarTasksList = mostSimilarTasksList; 
    497549            this.unfinishedRunnables = unfinishedRunnables; 
     
    503555        @Override 
    504556        public void run() { 
    505             int noOfComparisons = 0; 
    506              
    507             for (int i = startIndex; i < endIndex; i++) { 
    508                 noOfComparisons += i; 
    509             } 
    510  
    511             System.out.println("performing " + noOfComparisons + " comparisons"); 
    512              
    513             SimilarTasks mostSimilarTasks = UNEQUAL_TASKS; 
     557            SimilarTasks mostSimilarTasks = SimilarTasks.UNEQUAL_TASKS; 
     558            int mostSimilarDiffLevel = MAX_DIFF_LEVEL; 
    514559            List<SimilarTasks> allMostSimilarTasks = new LinkedList<SimilarTasks>(); 
    515              
    516             for (int i = startIndex + 1; i < endIndex; i++) { 
    517                 /*if (appData.isSelfCreatedTask(taskList.get(i))) { 
    518                     continue; 
    519                 }*/ 
    520                  
    521                 for (int j = startIndex; j < i; j++) { 
    522                     /*if (appData.isSelfCreatedTask(taskList.get(j))) { 
    523                         continue; 
    524                     }*/ 
     560            int counter = 0; 
     561             
     562            LEFT_HAND_TRAVERSAL: 
     563            for (int i = 0; i < leftHandTraversals.length; i++) { 
     564                 
     565                ITask leftHandTask = leftHandTraversals[i].getTask(); 
     566                 
     567                RIGHT_HAND_TRAVERSAL: 
     568                for (int j = 0; j < rightHandTraversals.length; j++) { 
     569 
     570                    ITask rightHandTask = rightHandTraversals[j].getTask(); 
    525571                     
    526                     if (isComparisonToSkip(taskList.get(i), taskList.get(j))) { 
    527                         continue; 
    528                     } 
    529                      
    530                     SimilarTasks similarTasks = SimilarTasks.compareTasks 
    531                         (taskList.get(i), taskList.get(j), comparator); 
    532                      
    533                     if (similarTasks.isInBetweenDifference()) { 
    534                         if (similarTasks.getDiffLevel() < mostSimilarTasks.getDiffLevel()) { 
    535                             mostSimilarTasks = similarTasks; 
    536                             allMostSimilarTasks.clear(); 
    537                             allMostSimilarTasks.add(similarTasks); 
     572                    try { 
     573                        if (leftHandTask == rightHandTask) { 
     574                            continue LEFT_HAND_TRAVERSAL; 
    538575                        } 
    539                         else if (similarTasks.getDiffLevel() == mostSimilarTasks.getDiffLevel()) { 
    540                             allMostSimilarTasks.add(similarTasks); 
     576 
     577                        counter++; 
     578 
     579                        if (isComparisonToSkip(leftHandTask, rightHandTask)) { 
     580                            continue RIGHT_HAND_TRAVERSAL; 
    541581                        } 
     582                         
     583                        if (!isBasicallySimilar(leftHandTraversals[i], rightHandTraversals[j])) { 
     584                            continue RIGHT_HAND_TRAVERSAL; 
     585                        } 
     586 
     587                        SimilarTasks similarTasks1 = SimilarTasks.compareTraversals 
     588                            (leftHandTraversals[i], rightHandTraversals[j], comparator); 
     589 
     590                        SimilarTasks similarTasks2 = SimilarTasks.compareTraversals 
     591                            (rightHandTraversals[j], leftHandTraversals[i], comparator); 
     592 
     593                        if ((similarTasks1.getDiffLevel() <= mostSimilarDiffLevel) || 
     594                            (similarTasks2.getDiffLevel() <= mostSimilarDiffLevel)) 
     595                        { 
     596                            SimilarTasks similarTasks = 
     597                                getSimilarTasksToPrefer(similarTasks1, similarTasks2); 
     598 
     599                            if (similarTasks.isInBetweenDifference()) { 
     600                                if (similarTasks.getDiffLevel() < mostSimilarDiffLevel) { 
     601                                    mostSimilarTasks = similarTasks; 
     602                                    mostSimilarDiffLevel = mostSimilarTasks.getDiffLevel(); 
     603                                    allMostSimilarTasks.clear(); 
     604                                    allMostSimilarTasks.add(similarTasks); 
     605                                } 
     606                                else if (similarTasks.getDiffLevel() == mostSimilarDiffLevel) { 
     607                                    allMostSimilarTasks.add(similarTasks); 
     608                                } 
     609                            } 
     610                        } 
     611                    } 
     612                    catch (Exception e) { 
     613                        e.printStackTrace(); 
     614 
     615                        SimilarTasks similarTasks1 = SimilarTasks.compareTraversals 
     616                            (leftHandTraversals[i], rightHandTraversals[j], comparator); 
     617 
     618                        SimilarTasks similarTasks2 = SimilarTasks.compareTraversals 
     619                            (rightHandTraversals[j], leftHandTraversals[i], comparator); 
     620 
     621                        similarTasks1.dump(System.err); 
     622 
     623                        similarTasks2.dump(System.err); 
    542624                    } 
    543625                } 
     
    546628            synchronized (unfinishedRunnables) { 
    547629                mostSimilarTasksList.addAll(allMostSimilarTasks); 
    548                  
    549                 //System.out.println("notifying finish"); 
     630                comparisonCounter += counter; 
     631                 
    550632                for (int i = 0; i < unfinishedRunnables.size(); i++) { 
    551633                    if (unfinishedRunnables.get(i) == this) { 
     
    557639        } 
    558640 
     641        /** 
     642         * 
     643         */ 
     644        private boolean isBasicallySimilar(TaskTraversal traversal1, TaskTraversal traversal2) { 
     645            int length1 = traversal1.size(); 
     646            int length2 = traversal2.size(); 
     647            int maxLength = Math.max(length1, length2); 
     648            int lengthDiff = 100 * Math.abs(length1 - length2) / maxLength; 
     649             
     650            if (lengthDiff > MAX_DIFF_LEVEL) { 
     651                return false; 
     652            } 
     653            else { 
     654                return true; 
     655            } 
     656        } 
     657 
     658        /** 
     659         * <p> 
     660         * TODO: comment 
     661         * </p> 
     662         * 
     663         * @param similarTasks1 
     664         * @param similarTasks2 
     665         * @return 
     666         */ 
     667        private SimilarTasks getSimilarTasksToPrefer(SimilarTasks similarTasks1, 
     668                                                     SimilarTasks similarTasks2) 
     669        { 
     670            if (similarTasks2.getDiffLevel() > similarTasks1.getDiffLevel()) { 
     671                return similarTasks2; 
     672            } 
     673            else if (similarTasks1.getDiffLevel() > similarTasks2.getDiffLevel()) { 
     674                return similarTasks1; 
     675            } 
     676            else if (similarTasks1.getDiffLevel() == similarTasks2.getDiffLevel()) { 
     677                ITask first = similarTasks1.getLeftHandSide(); 
     678                ITask second = similarTasks2.getLeftHandSide(); 
     679                 
     680                long valFirst = getTaskMetric(first, TaskMetric.EVENT_COVERAGE); 
     681                long valSecond = getTaskMetric(second, TaskMetric.EVENT_COVERAGE); 
     682 
     683                if (valSecond > valFirst) { 
     684                    return similarTasks2; 
     685                } 
     686                else if (valSecond < valFirst) { 
     687                    return similarTasks1; 
     688                } 
     689 
     690                // no of covered events is equal, try to distinguish by count 
     691 
     692                valFirst = getTaskMetric(first, TaskMetric.COUNT); 
     693                valSecond = getTaskMetric(second, TaskMetric.COUNT); 
     694 
     695                if (valSecond > valFirst) { 
     696                    return similarTasks2; 
     697                } 
     698                else if (valSecond < valFirst) { 
     699                    return similarTasks1; 
     700                } 
     701 
     702                // count is equal, try to distinguish by depth 
     703 
     704                valFirst = getTaskMetric(first, TaskMetric.DEPTH); 
     705                valSecond = getTaskMetric(second, TaskMetric.DEPTH); 
     706 
     707                if (valSecond < valFirst) { 
     708                    return similarTasks2; 
     709                } 
     710                else if (valSecond > valFirst) { 
     711                    return similarTasks1; 
     712                } 
     713 
     714                // no of covered events is equal, try to distinguish by count 
     715 
     716                valFirst = cumulateTaskMetric(first, TaskMetric.COUNT); 
     717                valSecond = cumulateTaskMetric(second, TaskMetric.COUNT); 
     718 
     719                if (valSecond > valFirst) { 
     720                    return similarTasks2; 
     721                } 
     722                else if (valSecond < valFirst) { 
     723                    return similarTasks1; 
     724                } 
     725 
     726                // depth is equal. Calculate for both the similarity 
     727                // based on which the merging will take place 
     728                SimilarTasks tmp = 
     729                    SimilarTasks.getMergableLevelOfSimilarity(similarTasks1, comparator); 
     730                 
     731                valFirst = tmp != null ? tmp.getDiffLevel() : Integer.MAX_VALUE; 
     732                 
     733                tmp = SimilarTasks.getMergableLevelOfSimilarity(similarTasks2, comparator); 
     734                valSecond = tmp != null ? tmp.getDiffLevel() : Integer.MAX_VALUE; 
     735 
     736                if (valSecond < valFirst) { 
     737                    return similarTasks2; 
     738                } 
     739                else if (valSecond > valFirst) { 
     740                    return similarTasks1; 
     741                } 
     742 
     743                valFirst = getFirstTimestamp(first); 
     744                valSecond = getFirstTimestamp(second); 
     745                 
     746                if (valSecond > valFirst) { 
     747                    return similarTasks1; 
     748                } 
     749                else if (valSecond < valFirst) { 
     750                    return similarTasks2; 
     751                } 
     752 
     753                similarTasks1.dump(System.out); 
     754                similarTasks2.dump(System.out); 
     755 
     756                throw new RuntimeException 
     757                    ("several tasks are similar so that it is undecidable which to merge first"); 
     758            } 
     759             
     760            return null; 
     761        } 
     762 
     763        /** 
     764         * <p> 
     765         * TODO: comment 
     766         * </p> 
     767         * 
     768         * @param first 
     769         * @param eventCoverage 
     770         * @param taskModel2 
     771         * @return 
     772         */ 
     773        private int getTaskMetric(ITask task, TaskMetric metric) { 
     774            ITaskInfo info = taskModel.getTaskInfo(task); 
     775            return info.getMeasureValue(metric); 
     776        } 
     777         
     778        /** 
     779         * convenience method to get the cumulative value of a task metric 
     780         */ 
     781        private int cumulateTaskMetric(ITask            task, 
     782                                       final TaskMetric metric) 
     783        { 
     784            final int[] value = new int[1]; 
     785            value[0] = 0; 
     786             
     787            DefaultTaskTraversingVisitor visitor = new DefaultTaskTraversingVisitor() { 
     788                @Override 
     789                public void visit(IStructuringTemporalRelationship relationship) { 
     790                    value[0] += taskModel.getTaskInfo(relationship).getMeasureValue(metric); 
     791                    super.visit(relationship); 
     792                } 
     793            }; 
     794             
     795            task.accept(visitor); 
     796             
     797            return value[0]; 
     798        } 
     799 
     800        /** 
     801         * <p> 
     802         * TODO: comment 
     803         * </p> 
     804         * 
     805         * @param first 
     806         * @return 
     807         */ 
     808        private long getFirstTimestamp(ITask task) { 
     809            long timestamp = Long.MAX_VALUE; 
     810             
     811            for (ITaskInstance instance : task.getInstances()) { 
     812                ITaskInstance eventTaskInstance = instance; 
     813                 
     814                do { 
     815                    if (eventTaskInstance instanceof ITaskInstanceList) { 
     816                        eventTaskInstance = ((ITaskInstanceList) eventTaskInstance).get(0); 
     817                    } 
     818                    else if (eventTaskInstance instanceof ISelectionInstance) { 
     819                        eventTaskInstance = ((ISelectionInstance) eventTaskInstance).getChild(); 
     820                    } 
     821                } 
     822                while (!(eventTaskInstance instanceof IEventTaskInstance)); 
     823                 
     824                if (eventTaskInstance != null) { 
     825                    long newTimestamp = 
     826                        ((IEventTaskInstance) eventTaskInstance).getEvent().getTimestamp(); 
     827                     
     828                    if (timestamp > newTimestamp) { 
     829                        timestamp = newTimestamp; 
     830                    } 
     831                } 
     832            } 
     833             
     834            return timestamp; 
     835        } 
     836         
     837        /* (non-Javadoc) 
     838         * @see java.lang.Object#toString() 
     839         */ 
     840        @Override 
     841        public String toString() { 
     842            return "CompareThread(" + leftHandTraversals.length + ", " + 
     843                rightHandTraversals.length + ")"; 
     844        } 
     845 
    559846    } 
    560847} 
Note: See TracChangeset for help on using the changeset viewer.