Ignore:
Timestamp:
09/05/14 20:20:29 (10 years ago)
Author:
rkrimmel
Message:

Added automatically created javadoc, still needs to be commented properly though

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/SequenceForTaskDetectionRuleAlignment.java

    r1733 r1734  
    1515package de.ugoe.cs.autoquest.tasktrees.temporalrelation; 
    1616 
    17 import java.io.FileInputStream; 
    18 import java.io.FileOutputStream; 
    19 import java.io.IOException; 
    20 import java.io.ObjectInputStream; 
    21 import java.io.ObjectOutputStream; 
    2217import java.io.Serializable; 
    2318import java.util.ArrayList; 
     
    3631import java.util.logging.Level; 
    3732 
    38 import de.ugoe.cs.autoquest.CommandHelpers; 
    3933import de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentAlgorithm; 
    4034import de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentAlgorithmFactory; 
     
    5953import de.ugoe.cs.util.StopWatch; 
    6054import de.ugoe.cs.util.console.Console; 
    61 import de.ugoe.cs.util.console.GlobalDataContainer; 
     55 
    6256 
    6357/** 
     
    6660 * of recorded user sessions. For this, it first harmonizes all tasks. This 
    6761 * eases later comparison. Then it searches the sessions for iterations and 
    68  * replaces them accordingly. Then it searches for sub sequences being the 
    69  * longest and occurring most often. For each found sub sequence, it replaces 
     62 * replaces them accordingly. Then it searches for sub sequences using alignment algorithms 
     63 * For each found sub sequence, it replaces 
    7064 * the occurrences by creating appropriate {@link ISequence}s. Afterwards, again 
    7165 * searches for iterations and then again for sub sequences until no more 
     
    7569 *  
    7670 *  
    77  * @author Patrick Harms 
     71 * @author Ralph Krimmel 
    7872 */ 
    7973public class SequenceForTaskDetectionRuleAlignment implements ISessionScopeRule { 
    8074 
     75         
     76        /** 
     77         * The Class RuleApplicationData. 
     78         */ 
     79        private static class RuleApplicationData implements Serializable { 
     80 
     81                /** The Constant serialVersionUID. */ 
     82                private static final long serialVersionUID = -7559657686755522960L; 
     83 
     84                /** The number2task HashMap. Since we align the tasks just by their integer id,  
     85                 *  we need this to convert them back to Tasks again*/ 
     86                private final HashMap<Integer, ITask> number2task; 
     87 
     88                 
     89                /** The unique tasks, keeps track about all unique tasks  
     90                 * TODO: We Actually just need number2task here, this structure can be 
     91                 * removed in the future.*/ 
     92                private final HashSet<ITask> uniqueTasks; 
     93 
     94                /** The substitution matrix used by the alignment algorithm to be able to compare 
     95                 *  distances of tasks */ 
     96                private final ObjectDistanceSubstitionMatrix submat; 
     97 
     98                /** HashMap for keeping track in which sequence which replacement has been performed. 
     99                 *  Neccessary for updating the indices of other occurrences accordingly */ 
     100                public HashMap<Integer, List<MatchOccurence>> replacedOccurences; 
     101 
     102                /** The list of all found matches */ 
     103                public LinkedList<Match> matchseqs; 
     104 
     105                /** The generated NumberSequences.  
     106                 * This is the integer representation of the user sessions */ 
     107                private ArrayList<NumberSequence> numberseqs; 
     108 
     109                /** The list of newly created tasks (of one iteration). */ 
     110                private final LinkedList<ITask> newTasks; 
     111 
     112                /** The user sessions containing all EventTasks/Instances */ 
     113                private final List<IUserSession> sessions; 
     114 
     115                /** True if we replaced something in the user sessions in one iteration. */ 
     116                private boolean detectedAndReplacedTasks; 
     117 
     118                /** The result we give autoquest back */ 
     119                private final RuleApplicationResult result; 
     120 
     121                /** Stop Watch to measure performance */ 
     122                private final StopWatch stopWatch; 
     123 
     124                /** 
     125                 * Instantiates a new rule application data. 
     126                 * 
     127                 * @param sessions The user sessions 
     128                 */ 
     129                private RuleApplicationData(List<IUserSession> sessions) { 
     130                        this.sessions = sessions; 
     131                        numberseqs = new ArrayList<NumberSequence>(); 
     132                        uniqueTasks = new HashSet<ITask>(); 
     133                        number2task = new HashMap<Integer, ITask>(); 
     134                        stopWatch = new StopWatch(); 
     135                        result = new RuleApplicationResult(); 
     136                        submat = new ObjectDistanceSubstitionMatrix(6, -3, false); 
     137                        newTasks = new LinkedList<ITask>(); 
     138                        this.detectedAndReplacedTasks = true; 
     139                } 
     140 
     141                /** 
     142                 * Detected and replaced tasks. 
     143                 * 
     144                 * @return true, if successful 
     145                 */ 
     146                private boolean detectedAndReplacedTasks() { 
     147                        return detectedAndReplacedTasks; 
     148                } 
     149 
     150                /** 
     151                 * Gets the matchseqs. 
     152                 * 
     153                 * @return the matchseqs 
     154                 */ 
     155                public LinkedList<Match> getMatchseqs() { 
     156                        return matchseqs; 
     157                } 
     158 
     159                /** 
     160                 * Gets the new tasks. 
     161                 * 
     162                 * @return the new tasks 
     163                 */ 
     164                public LinkedList<ITask> getNewTasks() { 
     165                        return newTasks; 
     166                } 
     167 
     168                /** 
     169                 * Gets the number2task. 
     170                 * 
     171                 * @return the number2task HashMap 
     172                 */ 
     173                private HashMap<Integer, ITask> getNumber2Task() { 
     174                        return number2task; 
     175                } 
     176 
     177                /** 
     178                 * Gets the number sequences. 
     179                 * 
     180                 * @return the number sequences 
     181                 */ 
     182                private ArrayList<NumberSequence> getNumberSequences() { 
     183                        return numberseqs; 
     184                } 
     185 
     186                /** 
     187                 * Gets the replaced occurrences. 
     188                 * 
     189                 * @return the replaced occurences 
     190                 */ 
     191                public HashMap<Integer, List<MatchOccurence>> getReplacedOccurrences() { 
     192                        return replacedOccurences; 
     193                } 
     194 
     195                /** 
     196                 * Gets the result. 
     197                 * 
     198                 * @return the result 
     199                 */ 
     200                private RuleApplicationResult getResult() { 
     201                        return result; 
     202                } 
     203 
     204                /** 
     205                 * Gets the sessions. 
     206                 * 
     207                 * @return the UserSessions as List. 
     208                 */ 
     209                private List<IUserSession> getSessions() { 
     210                        return sessions; 
     211                } 
     212 
     213                /** 
     214                 * Gets the stop watch. 
     215                 * 
     216                 * @return the stopWatch 
     217                 */ 
     218                private StopWatch getStopWatch() { 
     219                        return stopWatch; 
     220                } 
     221 
     222                /** 
     223                 * Gets the submat. 
     224                 * 
     225                 * @return the submat 
     226                 */ 
     227                private ObjectDistanceSubstitionMatrix getSubmat() { 
     228                        return submat; 
     229                } 
     230 
     231                /** 
     232                 * Gets the unique tasks. 
     233                 * 
     234                 * @return the unique tasks 
     235                 */ 
     236                private HashSet<ITask> getUniqueTasks() { 
     237                        return uniqueTasks; 
     238                } 
     239 
     240                /** 
     241                 * New task created. 
     242                 * 
     243                 * @param task the task 
     244                 */ 
     245                private void newTaskCreated(ITask task) { 
     246                        number2task.put(task.getId(), task); 
     247                        newTasks.add(task); 
     248                } 
     249 
     250                /** 
     251                 * Reset newly created tasks. 
     252                 */ 
     253                synchronized private void resetNewlyCreatedTasks() { 
     254                        uniqueTasks.addAll(newTasks); 
     255                        newTasks.clear(); 
     256                } 
     257 
     258                /** 
     259                 * Sets the number sequences. 
     260                 * 
     261                 * @param numberseqs the new number sequences 
     262                 */ 
     263                private void setNumberSequences(ArrayList<NumberSequence> numberseqs) { 
     264                        this.numberseqs = numberseqs; 
     265                } 
     266 
     267                /** 
     268                 * Sets the replaced occurences. 
     269                 * 
     270                 * @param replacedOccurences the replaced occurences 
     271                 */ 
     272                public void setReplacedOccurences( 
     273                                HashMap<Integer, List<MatchOccurence>> replacedOccurences) { 
     274                        this.replacedOccurences = replacedOccurences; 
     275                } 
     276 
     277                /** 
     278                 * Update substitution matrix. 
     279                 */ 
     280                private void updateSubstitutionMatrix() { 
     281                        submat.update(getNewTasks()); 
     282                        resetNewlyCreatedTasks(); 
     283                } 
     284 
     285        } 
     286 
     287        /** The n threads. */ 
     288        public static int nThreads = Runtime.getRuntime().availableProcessors() - 1; 
     289 
     290        /** The iteration. */ 
     291        private int iteration = 0; 
     292 
     293        /** <p> the task factory to be used for creating substructures for the temporal relationships identified during rul application </p>. */ 
     294        private final ITaskFactory taskFactory; 
     295 
     296        /** <p> the task builder to be used for creating substructures for the temporal relationships identified during rule application </p>. */ 
     297        private final ITaskBuilder taskBuilder; 
     298 
     299        /** 
     300         * <p> 
     301         * the task handling strategy to be used for comparing tasks for 
     302         * preparation, i.e., before the tasks are harmonized 
     303         * </p> 
     304         */ 
     305        private final TaskHandlingStrategy preparationTaskHandlingStrategy; 
     306 
     307        /** 
     308         * <p> 
     309         * instantiates the rule and initializes it with a task equality to be 
     310         * considered when comparing tasks as well as a task factory and builder to 
     311         * be used for creating task structures. 
     312         * </p> 
     313         *  
     314         * @param minimalTaskEquality 
     315         *            the task equality to be considered when comparing tasks 
     316         * @param taskFactory 
     317         *            the task factory to be used for creating substructures 
     318         * @param taskBuilder 
     319         *            the task builder to be used for creating substructures 
     320         */ 
     321 
     322        SequenceForTaskDetectionRuleAlignment(TaskEquality minimalTaskEquality, 
     323                        ITaskFactory taskFactory, ITaskBuilder taskBuilder) { 
     324                this.taskFactory = taskFactory; 
     325                this.taskBuilder = taskBuilder; 
     326 
     327                this.preparationTaskHandlingStrategy = new TaskHandlingStrategy( 
     328                                minimalTaskEquality); 
     329        } 
     330 
     331        /* 
     332         * (non-Javadoc) 
     333         *  
     334         * @see 
     335         * de.ugoe.cs.autoquest.tasktrees.temporalrelation.ISessionScopeRule#apply 
     336         * (java.util.List) 
     337         */ 
     338        @Override 
     339        public RuleApplicationResult apply(List<IUserSession> sessions) { 
     340                final RuleApplicationData appData = new RuleApplicationData(sessions); 
     341                 
     342                harmonizeEventTaskInstancesModel(appData); 
     343 
     344 
     345                Console.traceln(Level.INFO, "generating substitution matrix from " 
     346                                + appData.getUniqueTasks().size() + " unique tasks"); 
     347                appData.getStopWatch().start("substitution matrix"); 
     348                appData.getSubmat().generate(appData.getUniqueTasks()); 
     349                appData.getStopWatch().stop("substitution matrix"); 
     350 
     351                Console.traceln(Level.INFO, "Starting main loop"); 
     352                do { 
     353                        Console.traceln(Level.INFO, "Iteration Number: " + iteration); 
     354                        iteration++; 
     355                        appData.detectedAndReplacedTasks = false; 
     356                        appData.getStopWatch().start("whole loop"); 
     357                        detectAndReplaceIterations(appData); 
     358                        appData.getStopWatch().start("task replacement"); 
     359                        appData.updateSubstitutionMatrix(); 
     360                        detectAndReplaceTasks(appData); // 
     361                        appData.getStopWatch().stop("task replacement"); 
     362                        appData.getStopWatch().stop("whole loop"); 
     363                        appData.getStopWatch().dumpStatistics(System.out); 
     364                        appData.getStopWatch().reset(); 
     365 
     366                } while (appData.detectedAndReplacedTasks()); 
     367 
     368                Console.println("created " 
     369                                + appData.getResult().getNewlyCreatedTasks().size() 
     370                                + " new tasks and " 
     371                                + appData.getResult().getNewlyCreatedTaskInstances().size() 
     372                                + " appropriate instances\n"); 
     373 
     374                if ((appData.getResult().getNewlyCreatedTasks().size() > 0) 
     375                                || (appData.getResult().getNewlyCreatedTaskInstances().size() > 0)) { 
     376                        appData.getResult().setRuleApplicationStatus( 
     377                                        RuleApplicationStatus.FINISHED); 
     378                } 
     379 
     380                return appData.getResult(); 
     381        } 
     382 
     383        /** 
     384         * Creates the number sequences. 
     385         * 
     386         * @param appData the app data 
     387         * @return the array list 
     388         */ 
     389        private ArrayList<NumberSequence> createNumberSequences( 
     390                        RuleApplicationData appData) { 
     391                final ArrayList<NumberSequence> result = new ArrayList<NumberSequence>(); 
     392                for (int i = 0; i < appData.getSessions().size(); i++) { 
     393                        final IUserSession session = appData.getSessions().get(i); 
     394                        final NumberSequence templist = new NumberSequence(session.size()); 
     395                        for (int j = 0; j < session.size(); j++) { 
     396                                final ITaskInstance taskInstance = session.get(j); 
     397                                templist.getSequence()[j] = taskInstance.getTask().getId(); 
     398                        } 
     399                        // Each NumberSequence is identified by its id, beginning to count 
     400                        // at zero 
     401                        templist.setId(i); 
     402                        result.add(templist); 
     403                } 
     404                return result; 
     405        } 
     406 
     407        /** 
     408         * <p> 
     409         * searches for direct iterations of single tasks in all sequences and 
     410         * replaces them with {@link IIteration}s, respectively appropriate 
     411         * instances. Also all single occurrences of a task that is iterated 
     412         * somewhen are replaced with iterations to have again an efficient way for 
     413         * task comparisons. 
     414         * </p> 
     415         *  
     416         * @param appData 
     417         *            the rule application data combining all data used for applying 
     418         *            this rule 
     419         */ 
     420        private void detectAndReplaceIterations(RuleApplicationData appData) { 
     421                Console.traceln(Level.FINE, "detecting iterations"); 
     422                appData.getStopWatch().start("detecting iterations"); 
     423 
     424                final List<IUserSession> sessions = appData.getSessions(); 
     425 
     426                final Set<ITask> iteratedTasks = searchIteratedTasks(sessions); 
     427 
     428                if (iteratedTasks.size() > 0) { 
     429                        replaceIterationsOf(iteratedTasks, sessions, appData); 
     430                } 
     431 
     432                appData.getStopWatch().stop("detecting iterations"); 
     433                Console.traceln(Level.INFO, "replaced " + iteratedTasks.size() 
     434                                + " iterated tasks"); 
     435        } 
     436 
     437        /** 
     438         * Detect and replace tasks. 
     439         * 
     440         * @param appData            the rule application data combining all data used for applying 
     441         *            this rule 
     442         */ 
     443        private void detectAndReplaceTasks(RuleApplicationData appData) { 
     444                Console.traceln(Level.FINE, "detecting and replacing tasks"); 
     445                appData.getStopWatch().start("detecting tasks"); 
     446 
     447                // Create NumberSequences 
     448                appData.setNumberSequences(this.createNumberSequences(appData)); 
     449 
     450                // Generate pairwise alignments 
     451                // appData.setMatchseqs(generatePairwiseAlignments(appData)); 
     452                generatePairwiseAlignments(appData); 
     453 
     454                // Searching each match in all other sessions, counting its occurences 
     455                searchMatchesInAllSessions(appData); 
     456 
     457                // Sort results to get the most occurring results 
     458                Console.traceln(Level.INFO, "sorting " + appData.getMatchseqs().size() 
     459                                + " results"); 
     460                final Comparator<Match> comparator = new Comparator<Match>() { 
     461                        @Override 
     462                        public int compare(Match m1, Match m2) { 
     463                                return m2.occurenceCount() - m1.occurenceCount(); 
     464 
     465                        } 
     466                }; 
     467                Collections.sort(appData.getMatchseqs(), comparator); 
     468                appData.getStopWatch().stop("detecting tasks"); 
     469 
     470                // Replace matches in the sessions 
     471                Console.traceln(Level.INFO, "Replacing matches in sessions"); 
     472                appData.getStopWatch().start("replacing tasks"); 
     473                replaceMatches(appData); 
     474                appData.getStopWatch().stop("replacing tasks"); 
     475        } 
     476 
     477         
     478        /** 
     479         * Generate pairwise alignments. 
     480         * 
     481         * @param appData the app data 
     482         */ 
     483        private void generatePairwiseAlignments(RuleApplicationData appData) { 
     484                final int numberSeqSize = appData.getNumberSequences().size(); 
     485                appData.matchseqs = new LinkedList<Match>(); 
     486                Console.traceln(Level.INFO, "generating pairwise alignments from " 
     487                                + numberSeqSize + " sessions with " + nThreads + " threads"); 
     488 
     489                int newThreads = nThreads; 
     490                if (numberSeqSize < nThreads) { 
     491                        newThreads = numberSeqSize; 
     492                } 
     493 
     494                final ExecutorService executor = Executors 
     495                                .newFixedThreadPool(newThreads); 
     496                final int interval = numberSeqSize / newThreads; 
     497                int rest = numberSeqSize % newThreads; 
     498 
     499                for (int i = 0; i < (numberSeqSize - interval); i += interval) { 
     500                        int offset = 0; 
     501                        if (rest != 0) { 
     502                                offset = 1; 
     503                                rest--; 
     504                        } 
     505                        final int from = i; 
     506                        final int to = i + interval + offset; 
     507                        System.out.println("Creating thread for sessions " + from 
     508                                        + " till " + to); 
     509                        final ParallelPairwiseAligner aligner = new ParallelPairwiseAligner( 
     510                                        appData, from, to); 
     511                        executor.execute(aligner); 
     512                } 
     513                executor.shutdown(); 
     514                try { 
     515                        executor.awaitTermination(2, TimeUnit.HOURS); 
     516                } catch (final InterruptedException e) { 
     517                        // TODO Auto-generated catch block 
     518                        e.printStackTrace(); 
     519                } 
     520        } 
     521 
     522        /** 
     523         * <p> 
     524         * harmonizes the event task instances by unifying tasks. This is done, as 
     525         * initially the event tasks being equal with respect to the considered task 
     526         * equality are distinct objects. The comparison of these distinct objects 
     527         * is more time consuming than comparing the object references. 
     528         * </p> 
     529         *  
     530         * @param appData 
     531         *            the rule application data combining all data used for applying 
     532         *            this rule 
     533         * @return Returns the unique tasks symbol map 
     534         */ 
     535        private void harmonizeEventTaskInstancesModel(RuleApplicationData appData) { 
     536                Console.traceln(Level.INFO, 
     537                                "harmonizing task model of event task instances"); 
     538                appData.getStopWatch().start("harmonizing event tasks"); 
     539                final SymbolMap<ITaskInstance, ITask> uniqueTasks = preparationTaskHandlingStrategy 
     540                                .createSymbolMap(); 
     541 
     542                final TaskInstanceComparator comparator = preparationTaskHandlingStrategy 
     543                                .getTaskComparator(); 
     544 
     545                int unifiedTasks = 0; 
     546                ITask task; 
     547                final List<IUserSession> sessions = appData.getSessions(); 
     548                for (int j = 0; j < sessions.size(); j++) { 
     549                        final IUserSession session = sessions.get(j); 
     550 
     551                        for (int i = 0; i < session.size(); i++) { 
     552                                final ITaskInstance taskInstance = session.get(i); 
     553                                task = uniqueTasks.getValue(taskInstance); 
     554 
     555                                if (task == null) { 
     556                                        uniqueTasks.addSymbol(taskInstance, taskInstance.getTask()); 
     557                                        appData.getUniqueTasks().add(taskInstance.getTask()); 
     558                                        appData.getNumber2Task().put( 
     559                                                        taskInstance.getTask().getId(), 
     560                                                        taskInstance.getTask()); 
     561                                } else { 
     562                                        taskBuilder.setTask(taskInstance, task); 
     563                                        unifiedTasks++; 
     564                                } 
     565                        } 
     566                        comparator.clearBuffers(); 
     567                } 
     568 
     569                appData.getStopWatch().stop("harmonizing event tasks"); 
     570                Console.traceln(Level.INFO, "harmonized " + unifiedTasks 
     571                                + " task occurrences (still " + appData.getUniqueTasks().size() 
     572                                + " different tasks)"); 
     573 
     574                appData.getStopWatch().dumpStatistics(System.out); 
     575                appData.getStopWatch().reset(); 
     576        } 
     577 
     578        /** 
     579         * <p> 
     580         * TODO clarify why this is done 
     581         * </p>. 
     582         * 
     583         * @param iteration the iteration 
     584         * @param iterationInstances the iteration instances 
     585         */ 
     586        private void harmonizeIterationInstancesModel(IIteration iteration, 
     587                        List<IIterationInstance> iterationInstances) { 
     588                final List<ITask> iteratedTaskVariants = new LinkedList<ITask>(); 
     589                final TaskInstanceComparator comparator = preparationTaskHandlingStrategy 
     590                                .getTaskComparator(); 
     591 
     592                // merge the lexically different variants of iterated task to a unique 
     593                // list 
     594                for (final IIterationInstance iterationInstance : iterationInstances) { 
     595                        for (final ITaskInstance executionVariant : iterationInstance) { 
     596                                final ITask candidate = executionVariant.getTask(); 
     597 
     598                                boolean found = false; 
     599                                for (final ITask taskVariant : iteratedTaskVariants) { 
     600                                        if (comparator.areLexicallyEqual(taskVariant, candidate)) { 
     601                                                taskBuilder.setTask(executionVariant, taskVariant); 
     602                                                found = true; 
     603                                                break; 
     604                                        } 
     605                                } 
     606 
     607                                if (!found) { 
     608                                        iteratedTaskVariants.add(candidate); 
     609                                } 
     610                        } 
     611                } 
     612 
     613                // if there are more than one lexically different variant of iterated 
     614                // tasks, adapt the 
     615                // iteration model to be a selection of different variants. In this case 
     616                // also adapt 
     617                // the generated iteration instances to correctly contain selection 
     618                // instances. If there 
     619                // is only one variant of an iterated task, simply set this as the 
     620                // marked task of the 
     621                // iteration. In this case, the instances can be preserved as is 
     622                if (iteratedTaskVariants.size() > 1) { 
     623                        final ISelection selection = taskFactory.createNewSelection(); 
     624 
     625                        for (final ITask variant : iteratedTaskVariants) { 
     626                                taskBuilder.addChild(selection, variant); 
     627                        } 
     628 
     629                        taskBuilder.setMarkedTask(iteration, selection); 
     630 
     631                        for (final IIterationInstance instance : iterationInstances) { 
     632                                for (int i = 0; i < instance.size(); i++) { 
     633                                        final ISelectionInstance selectionInstance = taskFactory 
     634                                                        .createNewTaskInstance(selection); 
     635                                        taskBuilder.setChild(selectionInstance, instance.get(i)); 
     636                                        taskBuilder.setTaskInstance(instance, i, selectionInstance); 
     637                                } 
     638                        } 
     639                } else { 
     640                        taskBuilder.setMarkedTask(iteration, iteratedTaskVariants.get(0)); 
     641                } 
     642        } 
     643 
     644 
     645        /** 
     646         * Match as sequence. 
     647         * 
     648         * @param appData            , Ruleapplication Data needed to keep track of all created 
     649         *            tasks 
     650         * @param m            The match to be converted into a Task 
     651         * @return The task of the match with an ISequence as it's root 
     652         */ 
     653        synchronized public ISequence matchAsSequence(RuleApplicationData appData, 
     654                        Match m) { 
     655                final ISequence sequence = taskFactory.createNewSequence(); 
     656                appData.newTaskCreated(sequence); 
     657 
     658                final int[] first = m.getFirstSequence().getSequence(); 
     659                final int[] second = m.getSecondSequence().getSequence(); 
     660 
     661                // Both sequences of a match are equally long 
     662                for (int i = 0; i < m.getFirstSequence().size(); i++) { 
     663 
     664                        // Two gaps aligned to each other: Have not seen it happening so 
     665                        // far, just to handle it 
     666                        if ((first[i] == -1) && (second[i] == -1)) { 
     667                                // Do nothing here. 
     668                        } 
     669                        // Both events are equal, we can simply add the task referring to 
     670                        // the number 
     671                        else if (first[i] == second[i]) { 
     672                                taskBuilder.addChild(sequence, 
     673                                                appData.getNumber2Task().get(first[i])); 
     674                        } 
     675                        // We have a gap in the first sequence, we need to add the task of 
     676                        // the second sequence as optional 
     677                        else if ((first[i] == -1) && (second[i] != -1)) { 
     678                                final IOptional optional = taskFactory.createNewOptional(); 
     679                                appData.newTaskCreated(optional); 
     680                                taskBuilder.setMarkedTask(optional, appData.getNumber2Task() 
     681                                                .get(second[i])); 
     682                                taskBuilder.addChild(sequence, optional); 
     683                        } 
     684                        // We have a gap in the second sequence, we need to add the task of 
     685                        // the first sequence as optional 
     686                        else if ((first[i] != -1) && (second[i] == -1)) { 
     687                                final IOptional optional = taskFactory.createNewOptional(); 
     688                                appData.newTaskCreated(optional); 
     689                                taskBuilder.setMarkedTask(optional, appData.getNumber2Task() 
     690                                                .get(first[i])); 
     691                                taskBuilder.addChild(sequence, optional); 
     692                        } 
     693                        // Both tasks are not equal, we need to insert a selection here. 
     694                        // Check if the next position is not a selection 
     695                        else if (i < (first.length - 1)) { 
     696 
     697                                if ((first[i] != second[i]) 
     698                                                && (((first[i + 1] == second[i + 1]) 
     699                                                                || (first[i + 1] == -1) || (second[i + 1] == -1)))) { 
     700 
     701                                        final ISelection selection = taskFactory 
     702                                                        .createNewSelection(); 
     703                                        appData.newTaskCreated(selection); 
     704                                        taskBuilder.addChild(selection, appData.getNumber2Task() 
     705                                                        .get(first[i])); 
     706                                        taskBuilder.addChild(selection, appData.getNumber2Task() 
     707                                                        .get(second[i])); 
     708                                        taskBuilder.addChild(sequence, selection); 
     709                                } else { 
     710                                        boolean selectionfound = true; 
     711                                        final ISelection selection = taskFactory 
     712                                                        .createNewSelection(); 
     713                                        appData.newTaskCreated(selection); 
     714 
     715                                        final ISequence subsequence1 = taskFactory 
     716                                                        .createNewSequence(); 
     717                                        appData.newTaskCreated(subsequence1); 
     718 
     719                                        final ISequence subsequence2 = taskFactory 
     720                                                        .createNewSequence(); 
     721                                        appData.newTaskCreated(subsequence2); 
     722 
     723                                        taskBuilder.addChild(selection, subsequence1); 
     724                                        taskBuilder.addChild(selection, subsequence2); 
     725                                        taskBuilder.addChild(sequence, selection); 
     726                                        while ((i < (first.length - 1)) && selectionfound) { 
     727                                                selectionfound = false; 
     728                                                taskBuilder.addChild(subsequence1, appData 
     729                                                                .getNumber2Task().get(first[i])); 
     730                                                taskBuilder.addChild(subsequence2, appData 
     731                                                                .getNumber2Task().get(second[i])); 
     732                                                if ((first[i + 1] != second[i + 1]) 
     733                                                                && (first[i + 1] != -1) 
     734                                                                && (second[i + 1] != -1)) { 
     735                                                        selectionfound = true; 
     736                                                } else { 
     737                                                        continue; 
     738                                                } 
     739                                                i++; 
     740                                        } 
     741                                        if ((i == (first.length - 1)) && selectionfound) { 
     742                                                taskBuilder.addChild(subsequence1, appData 
     743                                                                .getNumber2Task().get(first[i])); 
     744                                                taskBuilder.addChild(subsequence2, appData 
     745                                                                .getNumber2Task().get(second[i])); 
     746                                        } 
     747                                } 
     748                        } else { 
     749                                if ((first[i] != second[i])) { 
     750 
     751                                        final ISelection selection = taskFactory 
     752                                                        .createNewSelection(); 
     753                                        appData.newTaskCreated(selection); 
     754                                        taskBuilder.addChild(selection, appData.getNumber2Task() 
     755                                                        .get(first[i])); 
     756                                        taskBuilder.addChild(selection, appData.getNumber2Task() 
     757                                                        .get(second[i])); 
     758                                        taskBuilder.addChild(sequence, selection); 
     759                                } 
     760                        } 
     761 
     762                } 
     763                return sequence; 
     764        } 
     765 
     766        /** 
     767         * <p> 
     768         * replaces all occurrences of all tasks provided in the set with iterations 
     769         * </p>. 
     770         * 
     771         * @param iteratedTasks            the tasks to be replaced with iterations 
     772         * @param sessions            the sessions in which the tasks are to be replaced 
     773         * @param appData            the rule application data combining all data used for applying 
     774         *            this rule 
     775         */ 
     776        private void replaceIterationsOf(Set<ITask> iteratedTasks, 
     777                        List<IUserSession> sessions, RuleApplicationData appData) { 
     778                final Map<ITask, IIteration> iterations = new HashMap<ITask, IIteration>(); 
     779                final Map<IIteration, List<IIterationInstance>> iterationInstances = new HashMap<IIteration, List<IIterationInstance>>(); 
     780 
     781                for (final ITask iteratedTask : iteratedTasks) { 
     782 
     783                        final IIteration iteration = taskFactory.createNewIteration(); 
     784                        appData.newTaskCreated(iteration); 
     785                        iterations.put(iteratedTask, iteration); 
     786                        iterationInstances.put(iteration, 
     787                                        new LinkedList<IIterationInstance>()); 
     788                } 
     789 
     790                IIterationInstance iterationInstance; 
     791 
     792                for (final IUserSession session : sessions) { 
     793                        int index = 0; 
     794                        iterationInstance = null; 
     795 
     796                        while (index < session.size()) { 
     797                                // we prepared the task instances to refer to unique tasks, if 
     798                                // they are treated 
     799                                // as equal. Therefore, we just compare the identity of the 
     800                                // tasks of the task 
     801                                // instances 
     802                                final ITask currentTask = session.get(index).getTask(); 
     803                                final IIteration iteration = iterations.get(currentTask); 
     804                                if (iteration != null) { 
     805                                        if ((iterationInstance == null) 
     806                                                        || (iterationInstance.getTask() != iteration)) { 
     807                                                iterationInstance = taskFactory 
     808                                                                .createNewTaskInstance(iteration); 
     809                                                iterationInstances.get(iteration) 
     810                                                                .add(iterationInstance);// TODO:: Don't create 
     811                                                // TaskInstances here, 
     812                                                // use a set of tasks 
     813                                                // instead 
     814                                                taskBuilder.addTaskInstance(session, index, 
     815                                                                iterationInstance); 
     816                                                index++; 
     817                                        } 
     818 
     819                                        taskBuilder.addChild(iterationInstance, session.get(index)); 
     820                                        taskBuilder.removeTaskInstance(session, index); 
     821                                } else { 
     822                                        if (iterationInstance != null) { 
     823                                                iterationInstance = null; 
     824                                        } 
     825                                        index++; 
     826                                } 
     827                        } 
     828                } 
     829 
     830                for (final Map.Entry<IIteration, List<IIterationInstance>> entry : iterationInstances 
     831                                .entrySet()) { 
     832                        harmonizeIterationInstancesModel(entry.getKey(), entry.getValue()); 
     833                } 
     834        } 
     835 
     836        /** 
     837         * Replace matches. 
     838         * 
     839         * @param appData the app data 
     840         */ 
     841        private void replaceMatches(RuleApplicationData appData) { 
     842                appData.replacedOccurences = new HashMap<Integer, List<MatchOccurence>>(); 
     843 
     844                final int matchSeqSize = appData.getMatchseqs().size(); 
     845                int newThreads = nThreads; 
     846                if (matchSeqSize < nThreads) { 
     847                        newThreads = matchSeqSize; 
     848                } 
     849                final ExecutorService executor = Executors 
     850                                .newFixedThreadPool(newThreads); 
     851                final int interval = matchSeqSize / newThreads; 
     852                int rest = matchSeqSize % newThreads; 
     853 
     854                for (int i = 0; i < (matchSeqSize - interval); i += interval) { 
     855                        int offset = 0; 
     856                        if (rest != 0) { 
     857                                offset = 1; 
     858                                rest--; 
     859                        } 
     860                        final int from = i; 
     861                        final int to = i + interval + offset; 
     862                        System.out 
     863                        .println("Replacement: Creating thread with matches from " 
     864                                        + from + " to " + to); 
     865                        // search each match in every other sequence 
     866                        final ParallelMatchReplacer replacer = new ParallelMatchReplacer( 
     867                                        appData, from, to); 
     868                        executor.execute(replacer); 
     869                } 
     870                executor.shutdown(); 
     871                try { 
     872                        executor.awaitTermination(2, TimeUnit.HOURS); 
     873                } catch (final InterruptedException e) { 
     874                        // TODO Auto-generated catch block 
     875                        e.printStackTrace(); 
     876                } 
     877        } 
     878 
     879 
     880        /** 
     881         * <p> 
     882         * searches the provided sessions for task iterations. If a task is 
     883         * iterated, it is added to the returned set. 
     884         * </p> 
     885         * 
     886         * @param sessions the sessions 
     887         * @return a set of tasks being iterated somewhere 
     888         */ 
     889        private Set<ITask> searchIteratedTasks(List<IUserSession> sessions) { 
     890                final Set<ITask> iteratedTasks = new HashSet<ITask>(); 
     891                for (final IUserSession session : sessions) { 
     892                        for (int i = 0; i < (session.size() - 1); i++) { 
     893                                // we prepared the task instances to refer to unique tasks, if 
     894                                // they are treated 
     895                                // as equal. Therefore, we just compare the identity of the 
     896                                // tasks of the task 
     897                                // instances 
     898                                if (session.get(i).getTask() == session.get(i + 1).getTask()) { 
     899                                        iteratedTasks.add(session.get(i).getTask()); 
     900                                } 
     901                        } 
     902                } 
     903                return iteratedTasks; 
     904        } 
     905 
     906        /** 
     907         * Search matches in all sessions. 
     908         * 
     909         * @param appData the app data 
     910         */ 
     911        private void searchMatchesInAllSessions(RuleApplicationData appData) { 
     912                Console.traceln(Level.INFO, 
     913                                "searching for patterns occuring most with " + nThreads 
     914                                                + " threads"); 
     915                // Prepare parallel search of matchseqs 
     916 
     917                final int matchSeqSize = appData.getMatchseqs().size(); 
     918                int newThreads = nThreads; 
     919                if (matchSeqSize < nThreads) { 
     920                        newThreads = matchSeqSize; 
     921                } 
     922                final int interval = matchSeqSize / newThreads; 
     923                int rest = matchSeqSize % newThreads; 
     924                final ExecutorService executor = Executors.newFixedThreadPool(nThreads); 
     925 
     926                for (int i = 0; i < (matchSeqSize - interval); i += interval) { 
     927                        int offset = 0; 
     928                        if (rest != 0) { 
     929                                offset = 1; 
     930                                rest--; 
     931                        } 
     932                        final int from = i; 
     933                        final int to = i + interval + offset; 
     934                        System.out 
     935                        .println("Match finding: Creating thread with matches from " 
     936                                        + from + " to " + to); 
     937                        // search each match in every other sequence 
     938                        final ParallelMatchOcurrencesFinder finder = new ParallelMatchOcurrencesFinder( 
     939                                        appData, from, to); 
     940                        executor.execute(finder); 
     941                } 
     942                executor.shutdown(); 
     943                try { 
     944                        executor.awaitTermination(2, TimeUnit.HOURS); 
     945                } catch (final InterruptedException e) { 
     946                        // TODO Auto-generated catch block 
     947                        e.printStackTrace(); 
     948                } 
     949 
     950        } 
     951 
     952        /* 
     953         * (non-Javadoc) 
     954         *  
     955         * @see java.lang.Object#toString() 
     956         */ 
     957        @Override 
     958        public String toString() { 
     959                return "SequenceForTaskDetectionRuleAlignment"; 
     960        } 
     961 
     962        /** 
     963         * The Class ParallelMatchOcurrencesFinder. 
     964         */ 
    81965        private class ParallelMatchOcurrencesFinder implements Runnable { 
     966                 
     967                /** The app data. */ 
    82968                private final RuleApplicationData appData; 
     969                 
     970                /** The from. */ 
    83971                private final int from; 
     972                 
     973                /** The to. */ 
    84974                private final int to; 
    85975 
     976                /** 
     977                 * Instantiates a new parallel match ocurrences finder. 
     978                 * 
     979                 * @param appData the app data 
     980                 * @param from the from 
     981                 * @param to the to 
     982                 */ 
    86983                ParallelMatchOcurrencesFinder(RuleApplicationData appData, int from, 
    87984                                int to) { 
     
    91988                } 
    92989 
     990                /* (non-Javadoc) 
     991                 * @see java.lang.Runnable#run() 
     992                 */ 
    93993                @Override 
    94994                public void run() { 
     
    1291029        } 
    1301030 
     1031        /** 
     1032         * The Class ParallelMatchReplacer. 
     1033         */ 
    1311034        private class ParallelMatchReplacer implements Runnable { 
    1321035 
     1036                /** The app data. */ 
    1331037                private final RuleApplicationData appData; 
     1038                 
     1039                /** The from. */ 
    1341040                private final int from; 
     1041                 
     1042                /** The to. */ 
    1351043                private final int to; 
    1361044 
     1045                /** 
     1046                 * Instantiates a new parallel match replacer. 
     1047                 * 
     1048                 * @param appData the app data 
     1049                 * @param from the from 
     1050                 * @param to the to 
     1051                 */ 
    1371052                ParallelMatchReplacer(RuleApplicationData appData, int from, int to) { 
    1381053                        this.appData = appData; 
     
    1411056                } 
    1421057 
     1058                /* (non-Javadoc) 
     1059                 * @see java.lang.Runnable#run() 
     1060                 */ 
    1431061                @Override 
    1441062                public void run() { 
     
    1641082                                                // want to replace now 
    1651083 
    166                                                 synchronized (appData.getReplacedOccurences()) { 
    167                                                         if (appData.getReplacedOccurences().get( 
     1084                                                synchronized (appData.getReplacedOccurrences()) { 
     1085                                                        if (appData.getReplacedOccurrences().get( 
    1681086                                                                        oc.getSequenceId()) == null) { 
    169                                                                 appData.getReplacedOccurences().put( 
     1087                                                                appData.getReplacedOccurrences().put( 
    1701088                                                                                oc.getSequenceId(), 
    1711089                                                                                new LinkedList<MatchOccurence>()); 
     
    1861104                                                                // harmonized. 
    1871105                                                                for (final Iterator<MatchOccurence> jt = appData 
    188                                                                                 .getReplacedOccurences() 
     1106                                                                                .getReplacedOccurrences() 
    1891107                                                                                .get(oc.getSequenceId()).iterator(); jt 
    1901108                                                                                .hasNext();) { 
     
    2391157                                                // instance. (OptionalInstances may be shorter) 
    2401158 
    241                                                 synchronized (appData.getReplacedOccurences().get( 
     1159                                                synchronized (appData.getReplacedOccurrences().get( 
    2421160                                                                oc.getSequenceId())) { 
    243                                                         appData.getReplacedOccurences() 
     1161                                                        appData.getReplacedOccurrences() 
    2441162                                                        .get(oc.getSequenceId()).add(oc); 
    2451163                                                } 
     
    2501168        } 
    2511169 
     1170        /** 
     1171         * The Class ParallelPairwiseAligner. 
     1172         */ 
    2521173        private class ParallelPairwiseAligner implements Runnable { 
     1174                 
     1175                /** The app data. */ 
    2531176                private final RuleApplicationData appData; 
     1177                 
     1178                /** The from. */ 
    2541179                private final int from; 
     1180                 
     1181                /** The to. */ 
    2551182                private final int to; 
    2561183 
     1184                /** 
     1185                 * Instantiates a new parallel pairwise aligner. 
     1186                 * 
     1187                 * @param appData the app data 
     1188                 * @param from the from 
     1189                 * @param to the to 
     1190                 */ 
    2571191                ParallelPairwiseAligner(RuleApplicationData appData, int from, int to) { 
    2581192                        this.appData = appData; 
     
    2611195                } 
    2621196 
     1197                /* (non-Javadoc) 
     1198                 * @see java.lang.Runnable#run() 
     1199                 */ 
    2631200                @Override 
    2641201                public void run() { 
     
    2861223                } 
    2871224        } 
    288  
    289         /** 
    290          *  
    291          */ 
    292         private static class RuleApplicationData implements Serializable { 
    293  
    294                 /** 
    295                  *  
    296                  */ 
    297                 private static final long serialVersionUID = -7559657686755522960L; 
    298  
    299                 private final HashMap<Integer, ITask> number2task; 
    300  
    301                 // TODO: We Actually just need number2task here, this structure can be 
    302                 // removed in the future. 
    303                 private final HashSet<ITask> uniqueTasks; 
    304  
    305                 private final ObjectDistanceSubstitionMatrix submat; 
    306  
    307                 public HashMap<Integer, List<MatchOccurence>> replacedOccurences; 
    308  
    309                 public LinkedList<Match> matchseqs; 
    310  
    311                 private ArrayList<NumberSequence> numberseqs; 
    312  
    313                 private final LinkedList<ITask> newTasks; 
    314  
    315                 /** 
    316                  *  
    317                  */ 
    318                 private final List<IUserSession> sessions; 
    319  
    320                 /** 
    321                  *  
    322                  */ 
    323                 private boolean detectedAndReplacedTasks; 
    324  
    325                 /** 
    326                  *  
    327                  */ 
    328                 private final RuleApplicationResult result; 
    329  
    330                 /** 
    331                  *  
    332                  */ 
    333                 private final StopWatch stopWatch; 
    334  
    335                 /** 
    336                  *  
    337                  */ 
    338                 private RuleApplicationData(List<IUserSession> sessions) { 
    339                         this.sessions = sessions; 
    340                         numberseqs = new ArrayList<NumberSequence>(); 
    341                         uniqueTasks = new HashSet<ITask>(); 
    342                         number2task = new HashMap<Integer, ITask>(); 
    343                         stopWatch = new StopWatch(); 
    344                         result = new RuleApplicationResult(); 
    345                         submat = new ObjectDistanceSubstitionMatrix(6, -3, false); 
    346                         newTasks = new LinkedList<ITask>(); 
    347                         this.detectedAndReplacedTasks = true; 
    348                 } 
    349  
    350                 /** 
    351                  * 
    352                  */ 
    353                 private boolean detectedAndReplacedTasks() { 
    354                         return detectedAndReplacedTasks; 
    355                 } 
    356  
    357                 public LinkedList<Match> getMatchseqs() { 
    358                         return matchseqs; 
    359                 } 
    360  
    361                 public LinkedList<ITask> getNewTasks() { 
    362                         return newTasks; 
    363                 } 
    364  
    365                 private HashMap<Integer, ITask> getNumber2Task() { 
    366                         return number2task; 
    367                 } 
    368  
    369                 private ArrayList<NumberSequence> getNumberSequences() { 
    370                         return numberseqs; 
    371                 } 
    372  
    373                 public HashMap<Integer, List<MatchOccurence>> getReplacedOccurences() { 
    374                         return replacedOccurences; 
    375                 } 
    376  
    377                 /** 
    378                  * @return the result 
    379                  */ 
    380                 private RuleApplicationResult getResult() { 
    381                         return result; 
    382                 } 
    383  
    384                 /** 
    385                  * @return the UserSessions as List. 
    386                  */ 
    387                 private List<IUserSession> getSessions() { 
    388                         return sessions; 
    389                 } 
    390  
    391                 /** 
    392                  * @return the stopWatch 
    393                  */ 
    394                 private StopWatch getStopWatch() { 
    395                         return stopWatch; 
    396                 } 
    397  
    398                 private ObjectDistanceSubstitionMatrix getSubmat() { 
    399                         return submat; 
    400                 } 
    401  
    402                 private HashSet<ITask> getUniqueTasks() { 
    403                         return uniqueTasks; 
    404                 } 
    405  
    406                 private void newTaskCreated(ITask task) { 
    407                         number2task.put(task.getId(), task); 
    408                         newTasks.add(task); 
    409                 } 
    410  
    411                 synchronized private void resetNewlyCreatedTasks() { 
    412                         uniqueTasks.addAll(newTasks); 
    413                         newTasks.clear(); 
    414                 } 
    415  
    416                 private void setNumberSequences(ArrayList<NumberSequence> numberseqs) { 
    417                         this.numberseqs = numberseqs; 
    418                 } 
    419  
    420                 public void setReplacedOccurences( 
    421                                 HashMap<Integer, List<MatchOccurence>> replacedOccurences) { 
    422                         this.replacedOccurences = replacedOccurences; 
    423                 } 
    424  
    425                 private void updateSubstitutionMatrix() { 
    426                         submat.update(getNewTasks()); 
    427                         resetNewlyCreatedTasks(); 
    428                 } 
    429  
    430         } 
    431  
    432         public static int nThreads = Runtime.getRuntime().availableProcessors() - 1; 
    433  
    434         private int iteration = 0; 
    435  
    436         /** 
    437          * <p> 
    438          * the task factory to be used for creating substructures for the temporal 
    439          * relationships identified during rul application 
    440          * </p> 
    441          */ 
    442         private final ITaskFactory taskFactory; 
    443  
    444         /** 
    445          * <p> 
    446          * the task builder to be used for creating substructures for the temporal 
    447          * relationships identified during rule application 
    448          * </p> 
    449          */ 
    450         private final ITaskBuilder taskBuilder; 
    451  
    452         /** 
    453          * <p> 
    454          * the task handling strategy to be used for comparing tasks for 
    455          * preparation, i.e., before the tasks are harmonized 
    456          * </p> 
    457          */ 
    458         private final TaskHandlingStrategy preparationTaskHandlingStrategy; 
    459  
    460         /** 
    461          * <p> 
    462          * instantiates the rule and initializes it with a task equality to be 
    463          * considered when comparing tasks as well as a task factory and builder to 
    464          * be used for creating task structures. 
    465          * </p> 
    466          *  
    467          * @param minimalTaskEquality 
    468          *            the task equality to be considered when comparing tasks 
    469          * @param taskFactory 
    470          *            the task factory to be used for creating substructures 
    471          * @param taskBuilder 
    472          *            the task builder to be used for creating substructures 
    473          */ 
    474  
    475         SequenceForTaskDetectionRuleAlignment(TaskEquality minimalTaskEquality, 
    476                         ITaskFactory taskFactory, ITaskBuilder taskBuilder) { 
    477                 this.taskFactory = taskFactory; 
    478                 this.taskBuilder = taskBuilder; 
    479  
    480                 this.preparationTaskHandlingStrategy = new TaskHandlingStrategy( 
    481                                 minimalTaskEquality); 
    482         } 
    483  
    484         /* 
    485          * (non-Javadoc) 
    486          *  
    487          * @see 
    488          * de.ugoe.cs.autoquest.tasktrees.temporalrelation.ISessionScopeRule#apply 
    489          * (java.util.List) 
    490          */ 
    491         @Override 
    492         public RuleApplicationResult apply(List<IUserSession> sessions) { 
    493                 final RuleApplicationData appData = new RuleApplicationData(sessions); 
    494                 // File harmonized = new File("harmonized.dat"); 
    495                 // if(harmonized.exists() && !harmonized.isDirectory()) { 
    496                 // Console.traceln(Level.INFO,"loading harmonized sessions from file"); 
    497                 // appData = loadAppData("harmonized"); 
    498                 // } 
    499                 // else { 
    500                 // appData.getStopWatch().start("harmonization"); 
    501                 harmonizeEventTaskInstancesModel(appData); 
    502                 // appData.getStopWatch().stop("harmonization"); 
    503                 GlobalDataContainer.getInstance().addData("harmonized", appData); 
    504                 // Saving intermediate results to file 
    505                 Console.traceln(Level.INFO, "saving substitution matrix to file"); 
    506                 // saveAppData("harmonized"); 
    507                 // } 
    508  
    509                 // File substitution = new File("substitution.dat"); 
    510                 // if(!(substitution.exists() && !substitution.isDirectory())) { 
    511                 Console.traceln(Level.INFO, "generating substitution matrix from " 
    512                                 + appData.getUniqueTasks().size() + " unique tasks"); 
    513                 appData.getStopWatch().start("substitution matrix"); 
    514                 appData.getSubmat().generate(appData.getUniqueTasks()); 
    515                 appData.getStopWatch().stop("substitution matrix"); 
    516                 // GlobalDataContainer.getInstance().addData("substitution", appData); 
    517                 // saveAppData("substitution"); 
    518                 // } 
    519                 // else { 
    520                 // Console.traceln(Level.INFO,"loading substitution matrix from file"); 
    521                 // appData = loadAppData("substitution"); 
    522                 // } 
    523  
    524                 Console.traceln(Level.INFO, "Starting main loop"); 
    525                 do { 
    526                         Console.traceln(Level.INFO, "Iteration Number: " + iteration); 
    527                         iteration++; 
    528                         appData.detectedAndReplacedTasks = false; 
    529                         appData.getStopWatch().start("whole loop"); 
    530                         detectAndReplaceIterations(appData); 
    531                         appData.getStopWatch().start("task replacement"); 
    532                         // appData.updateSubstitutionMatrix(); 
    533                         detectAndReplaceTasks(appData); // 
    534                         appData.getStopWatch().stop("task replacement"); 
    535                         appData.getStopWatch().stop("whole loop"); 
    536                         appData.getStopWatch().dumpStatistics(System.out); 
    537                         appData.getStopWatch().reset(); 
    538  
    539                 } while (appData.detectedAndReplacedTasks()); 
    540  
    541                 Console.println("created " 
    542                                 + appData.getResult().getNewlyCreatedTasks().size() 
    543                                 + " new tasks and " 
    544                                 + appData.getResult().getNewlyCreatedTaskInstances().size() 
    545                                 + " appropriate instances\n"); 
    546  
    547                 if ((appData.getResult().getNewlyCreatedTasks().size() > 0) 
    548                                 || (appData.getResult().getNewlyCreatedTaskInstances().size() > 0)) { 
    549                         appData.getResult().setRuleApplicationStatus( 
    550                                         RuleApplicationStatus.FINISHED); 
    551                 } 
    552  
    553                 return appData.getResult(); 
    554         } 
    555  
    556         private ArrayList<NumberSequence> createNumberSequences( 
    557                         RuleApplicationData appData) { 
    558                 final ArrayList<NumberSequence> result = new ArrayList<NumberSequence>(); 
    559                 for (int i = 0; i < appData.getSessions().size(); i++) { 
    560                         final IUserSession session = appData.getSessions().get(i); 
    561                         final NumberSequence templist = new NumberSequence(session.size()); 
    562                         for (int j = 0; j < session.size(); j++) { 
    563                                 final ITaskInstance taskInstance = session.get(j); 
    564                                 templist.getSequence()[j] = taskInstance.getTask().getId(); 
    565                         } 
    566                         // Each NumberSequence is identified by its id, beginning to count 
    567                         // at zero 
    568                         templist.setId(i); 
    569                         result.add(templist); 
    570                 } 
    571                 return result; 
    572         } 
    573  
    574         /** 
    575          * <p> 
    576          * searches for direct iterations of single tasks in all sequences and 
    577          * replaces them with {@link IIteration}s, respectively appropriate 
    578          * instances. Also all single occurrences of a task that is iterated 
    579          * somewhen are replaced with iterations to have again an efficient way for 
    580          * task comparisons. 
    581          * </p> 
    582          *  
    583          * @param appData 
    584          *            the rule application data combining all data used for applying 
    585          *            this rule 
    586          */ 
    587         private void detectAndReplaceIterations(RuleApplicationData appData) { 
    588                 Console.traceln(Level.FINE, "detecting iterations"); 
    589                 appData.getStopWatch().start("detecting iterations"); 
    590  
    591                 final List<IUserSession> sessions = appData.getSessions(); 
    592  
    593                 final Set<ITask> iteratedTasks = searchIteratedTasks(sessions); 
    594  
    595                 if (iteratedTasks.size() > 0) { 
    596                         replaceIterationsOf(iteratedTasks, sessions, appData); 
    597                 } 
    598  
    599                 appData.getStopWatch().stop("detecting iterations"); 
    600                 Console.traceln(Level.INFO, "replaced " + iteratedTasks.size() 
    601                                 + " iterated tasks"); 
    602         } 
    603  
    604         /** 
    605          *  
    606          * @param appData 
    607          *            the rule application data combining all data used for applying 
    608          *            this rule 
    609          */ 
    610         private void detectAndReplaceTasks(RuleApplicationData appData) { 
    611                 Console.traceln(Level.FINE, "detecting and replacing tasks"); 
    612                 appData.getStopWatch().start("detecting tasks"); 
    613  
    614                 // Create NumberSequences 
    615                 appData.setNumberSequences(this.createNumberSequences(appData)); 
    616  
    617                 // Generate pairwise alignments 
    618                 // appData.setMatchseqs(generatePairwiseAlignments(appData)); 
    619                 generatePairwiseAlignments(appData); 
    620  
    621                 // Searching each match in all other sessions, counting its occurences 
    622                 searchMatchesInAllSessions(appData); 
    623  
    624                 // Sort results to get the most occurring results 
    625                 Console.traceln(Level.INFO, "sorting " + appData.getMatchseqs().size() 
    626                                 + " results"); 
    627                 final Comparator<Match> comparator = new Comparator<Match>() { 
    628                         @Override 
    629                         public int compare(Match m1, Match m2) { 
    630                                 return m2.occurenceCount() - m1.occurenceCount(); 
    631  
    632                         } 
    633                 }; 
    634  
    635                 Collections.sort(appData.getMatchseqs(), comparator); 
    636                 appData.getStopWatch().stop("detecting tasks"); 
    637  
    638                 // Replace matches in the sessions 
    639                 Console.traceln(Level.INFO, "Replacing matches in sessions"); 
    640                 replaceMatches(appData); 
    641                 appData.getStopWatch().start("replacing tasks"); 
    642  
    643                 // appData.setMatchseqs(null); 
    644                 appData.getStopWatch().stop("replacing tasks"); 
    645         } 
    646  
    647         // private LinkedList<Match> generatePairwiseAlignments(RuleApplicationData 
    648         // appData) { 
    649         private void generatePairwiseAlignments(RuleApplicationData appData) { 
    650                 final int numberSeqSize = appData.getNumberSequences().size(); 
    651                 appData.matchseqs = new LinkedList<Match>(); 
    652                 Console.traceln(Level.INFO, "generating pairwise alignments from " 
    653                                 + numberSeqSize + " sessions with " + nThreads + " threads"); 
    654  
    655                 int newThreads = nThreads; 
    656                 if (numberSeqSize < nThreads) { 
    657                         newThreads = numberSeqSize; 
    658                 } 
    659  
    660                 final ExecutorService executor = Executors 
    661                                 .newFixedThreadPool(newThreads); 
    662                 final int interval = numberSeqSize / newThreads; 
    663                 int rest = numberSeqSize % newThreads; 
    664  
    665                 for (int i = 0; i < (numberSeqSize - interval); i += interval) { 
    666                         int offset = 0; 
    667                         if (rest != 0) { 
    668                                 offset = 1; 
    669                                 rest--; 
    670                         } 
    671                         final int from = i; 
    672                         final int to = i + interval + offset; 
    673                         System.out.println("Creating thread for sessions " + from 
    674                                         + " till " + to); 
    675                         final ParallelPairwiseAligner aligner = new ParallelPairwiseAligner( 
    676                                         appData, from, to); 
    677                         executor.execute(aligner); 
    678                 } 
    679                 executor.shutdown(); 
    680                 try { 
    681                         executor.awaitTermination(2, TimeUnit.HOURS); 
    682                 } catch (final InterruptedException e) { 
    683                         // TODO Auto-generated catch block 
    684                         e.printStackTrace(); 
    685                 } 
    686         } 
    687  
    688         /** 
    689          * <p> 
    690          * harmonizes the event task instances by unifying tasks. This is done, as 
    691          * initially the event tasks being equal with respect to the considered task 
    692          * equality are distinct objects. The comparison of these distinct objects 
    693          * is more time consuming than comparing the object references. 
    694          * </p> 
    695          *  
    696          * @param appData 
    697          *            the rule application data combining all data used for applying 
    698          *            this rule 
    699          * @return Returns the unique tasks symbol map 
    700          */ 
    701         private void harmonizeEventTaskInstancesModel(RuleApplicationData appData) { 
    702                 Console.traceln(Level.INFO, 
    703                                 "harmonizing task model of event task instances"); 
    704                 appData.getStopWatch().start("harmonizing event tasks"); 
    705                 final SymbolMap<ITaskInstance, ITask> uniqueTasks = preparationTaskHandlingStrategy 
    706                                 .createSymbolMap(); 
    707  
    708                 final TaskInstanceComparator comparator = preparationTaskHandlingStrategy 
    709                                 .getTaskComparator(); 
    710  
    711                 int unifiedTasks = 0; 
    712                 ITask task; 
    713                 final List<IUserSession> sessions = appData.getSessions(); 
    714                 for (int j = 0; j < sessions.size(); j++) { 
    715                         final IUserSession session = sessions.get(j); 
    716  
    717                         for (int i = 0; i < session.size(); i++) { 
    718                                 final ITaskInstance taskInstance = session.get(i); 
    719                                 task = uniqueTasks.getValue(taskInstance); 
    720  
    721                                 if (task == null) { 
    722                                         uniqueTasks.addSymbol(taskInstance, taskInstance.getTask()); 
    723                                         appData.getUniqueTasks().add(taskInstance.getTask()); 
    724                                         appData.getNumber2Task().put( 
    725                                                         taskInstance.getTask().getId(), 
    726                                                         taskInstance.getTask()); 
    727                                 } else { 
    728                                         taskBuilder.setTask(taskInstance, task); 
    729                                         unifiedTasks++; 
    730                                 } 
    731                         } 
    732                         comparator.clearBuffers(); 
    733                 } 
    734  
    735                 appData.getStopWatch().stop("harmonizing event tasks"); 
    736                 Console.traceln(Level.INFO, "harmonized " + unifiedTasks 
    737                                 + " task occurrences (still " + appData.getUniqueTasks().size() 
    738                                 + " different tasks)"); 
    739  
    740                 appData.getStopWatch().dumpStatistics(System.out); 
    741                 appData.getStopWatch().reset(); 
    742         } 
    743  
    744         /** 
    745          * <p> 
    746          * TODO clarify why this is done 
    747          * </p> 
    748          */ 
    749         private void harmonizeIterationInstancesModel(IIteration iteration, 
    750                         List<IIterationInstance> iterationInstances) { 
    751                 final List<ITask> iteratedTaskVariants = new LinkedList<ITask>(); 
    752                 final TaskInstanceComparator comparator = preparationTaskHandlingStrategy 
    753                                 .getTaskComparator(); 
    754  
    755                 // merge the lexically different variants of iterated task to a unique 
    756                 // list 
    757                 for (final IIterationInstance iterationInstance : iterationInstances) { 
    758                         for (final ITaskInstance executionVariant : iterationInstance) { 
    759                                 final ITask candidate = executionVariant.getTask(); 
    760  
    761                                 boolean found = false; 
    762                                 for (final ITask taskVariant : iteratedTaskVariants) { 
    763                                         if (comparator.areLexicallyEqual(taskVariant, candidate)) { 
    764                                                 taskBuilder.setTask(executionVariant, taskVariant); 
    765                                                 found = true; 
    766                                                 break; 
    767                                         } 
    768                                 } 
    769  
    770                                 if (!found) { 
    771                                         iteratedTaskVariants.add(candidate); 
    772                                 } 
    773                         } 
    774                 } 
    775  
    776                 // if there are more than one lexically different variant of iterated 
    777                 // tasks, adapt the 
    778                 // iteration model to be a selection of different variants. In this case 
    779                 // also adapt 
    780                 // the generated iteration instances to correctly contain selection 
    781                 // instances. If there 
    782                 // is only one variant of an iterated task, simply set this as the 
    783                 // marked task of the 
    784                 // iteration. In this case, the instances can be preserved as is 
    785                 if (iteratedTaskVariants.size() > 1) { 
    786                         final ISelection selection = taskFactory.createNewSelection(); 
    787  
    788                         for (final ITask variant : iteratedTaskVariants) { 
    789                                 taskBuilder.addChild(selection, variant); 
    790                         } 
    791  
    792                         taskBuilder.setMarkedTask(iteration, selection); 
    793  
    794                         for (final IIterationInstance instance : iterationInstances) { 
    795                                 for (int i = 0; i < instance.size(); i++) { 
    796                                         final ISelectionInstance selectionInstance = taskFactory 
    797                                                         .createNewTaskInstance(selection); 
    798                                         taskBuilder.setChild(selectionInstance, instance.get(i)); 
    799                                         taskBuilder.setTaskInstance(instance, i, selectionInstance); 
    800                                 } 
    801                         } 
    802                 } else { 
    803                         taskBuilder.setMarkedTask(iteration, iteratedTaskVariants.get(0)); 
    804                 } 
    805         } 
    806  
    807         public RuleApplicationData loadAppData(String name) { 
    808                 final String objectName = name; 
    809                 final String filename = name + ".dat"; 
    810  
    811                 Object data = null; 
    812                 FileInputStream fis = null; 
    813                 ObjectInputStream in = null; 
    814                 try { 
    815                         fis = new FileInputStream(filename); 
    816                         in = new ObjectInputStream(fis); 
    817                         data = in.readObject(); 
    818                         in.close(); 
    819                 } catch (final IOException ex) { 
    820                         Console.logException(ex); 
    821                 } catch (final ClassNotFoundException ex) { 
    822                         Console.logException(ex); 
    823                 } 
    824                 if (GlobalDataContainer.getInstance().addData(objectName, data)) { 
    825                         CommandHelpers.dataOverwritten(objectName); 
    826                 } 
    827                 return (RuleApplicationData) GlobalDataContainer.getInstance().getData( 
    828                                 name); 
    829         } 
    830  
    831         /** 
    832          * @param appData 
    833          *            , Ruleapplication Data needed to keep track of all created 
    834          *            tasks 
    835          * @param m 
    836          *            The match to be converted into a Task 
    837          * @return The task of the match with an ISequence as it's root 
    838          */ 
    839         synchronized public ISequence matchAsSequence(RuleApplicationData appData, 
    840                         Match m) { 
    841                 final ISequence sequence = taskFactory.createNewSequence(); 
    842                 appData.newTaskCreated(sequence); 
    843  
    844                 final int[] first = m.getFirstSequence().getSequence(); 
    845                 final int[] second = m.getSecondSequence().getSequence(); 
    846  
    847                 // Both sequences of a match are equally long 
    848                 for (int i = 0; i < m.getFirstSequence().size(); i++) { 
    849  
    850                         // Two gaps aligned to each other: Have not seen it happening so 
    851                         // far, just to handle it 
    852                         if ((first[i] == -1) && (second[i] == -1)) { 
    853                                 // Do nothing here. 
    854                         } 
    855                         // Both events are equal, we can simply add the task referring to 
    856                         // the number 
    857                         else if (first[i] == second[i]) { 
    858                                 taskBuilder.addChild(sequence, 
    859                                                 appData.getNumber2Task().get(first[i])); 
    860                         } 
    861                         // We have a gap in the first sequence, we need to add the task of 
    862                         // the second sequence as optional 
    863                         else if ((first[i] == -1) && (second[i] != -1)) { 
    864                                 final IOptional optional = taskFactory.createNewOptional(); 
    865                                 appData.newTaskCreated(optional); 
    866                                 taskBuilder.setMarkedTask(optional, appData.getNumber2Task() 
    867                                                 .get(second[i])); 
    868                                 taskBuilder.addChild(sequence, optional); 
    869                         } 
    870                         // We have a gap in the second sequence, we need to add the task of 
    871                         // the first sequence as optional 
    872                         else if ((first[i] != -1) && (second[i] == -1)) { 
    873                                 final IOptional optional = taskFactory.createNewOptional(); 
    874                                 appData.newTaskCreated(optional); 
    875                                 taskBuilder.setMarkedTask(optional, appData.getNumber2Task() 
    876                                                 .get(first[i])); 
    877                                 taskBuilder.addChild(sequence, optional); 
    878                         } 
    879                         // Both tasks are not equal, we need to insert a selection here. 
    880                         // Check if the next position is not a selection 
    881                         else if (i < (first.length - 1)) { 
    882  
    883                                 if ((first[i] != second[i]) 
    884                                                 && (((first[i + 1] == second[i + 1]) 
    885                                                                 || (first[i + 1] == -1) || (second[i + 1] == -1)))) { 
    886  
    887                                         final ISelection selection = taskFactory 
    888                                                         .createNewSelection(); 
    889                                         appData.newTaskCreated(selection); 
    890                                         taskBuilder.addChild(selection, appData.getNumber2Task() 
    891                                                         .get(first[i])); 
    892                                         taskBuilder.addChild(selection, appData.getNumber2Task() 
    893                                                         .get(second[i])); 
    894                                         taskBuilder.addChild(sequence, selection); 
    895                                 } else { 
    896                                         boolean selectionfound = true; 
    897                                         final ISelection selection = taskFactory 
    898                                                         .createNewSelection(); 
    899                                         appData.newTaskCreated(selection); 
    900  
    901                                         final ISequence subsequence1 = taskFactory 
    902                                                         .createNewSequence(); 
    903                                         appData.newTaskCreated(subsequence1); 
    904  
    905                                         final ISequence subsequence2 = taskFactory 
    906                                                         .createNewSequence(); 
    907                                         appData.newTaskCreated(subsequence2); 
    908  
    909                                         taskBuilder.addChild(selection, subsequence1); 
    910                                         taskBuilder.addChild(selection, subsequence2); 
    911                                         taskBuilder.addChild(sequence, selection); 
    912                                         while ((i < (first.length - 1)) && selectionfound) { 
    913                                                 selectionfound = false; 
    914                                                 taskBuilder.addChild(subsequence1, appData 
    915                                                                 .getNumber2Task().get(first[i])); 
    916                                                 taskBuilder.addChild(subsequence2, appData 
    917                                                                 .getNumber2Task().get(second[i])); 
    918                                                 if ((first[i + 1] != second[i + 1]) 
    919                                                                 && (first[i + 1] != -1) 
    920                                                                 && (second[i + 1] != -1)) { 
    921                                                         selectionfound = true; 
    922                                                 } else { 
    923                                                         continue; 
    924                                                 } 
    925                                                 i++; 
    926                                         } 
    927                                         if ((i == (first.length - 1)) && selectionfound) { 
    928                                                 taskBuilder.addChild(subsequence1, appData 
    929                                                                 .getNumber2Task().get(first[i])); 
    930                                                 taskBuilder.addChild(subsequence2, appData 
    931                                                                 .getNumber2Task().get(second[i])); 
    932                                         } 
    933                                 } 
    934                         } else { 
    935                                 if ((first[i] != second[i])) { 
    936  
    937                                         final ISelection selection = taskFactory 
    938                                                         .createNewSelection(); 
    939                                         appData.newTaskCreated(selection); 
    940                                         taskBuilder.addChild(selection, appData.getNumber2Task() 
    941                                                         .get(first[i])); 
    942                                         taskBuilder.addChild(selection, appData.getNumber2Task() 
    943                                                         .get(second[i])); 
    944                                         taskBuilder.addChild(sequence, selection); 
    945                                 } 
    946                         } 
    947  
    948                 } 
    949                 return sequence; 
    950         } 
    951  
    952         /** 
    953          * <p> 
    954          * replaces all occurrences of all tasks provided in the set with iterations 
    955          * </p> 
    956          *  
    957          * @param iteratedTasks 
    958          *            the tasks to be replaced with iterations 
    959          * @param sessions 
    960          *            the sessions in which the tasks are to be replaced 
    961          * @param appData 
    962          *            the rule application data combining all data used for applying 
    963          *            this rule 
    964          */ 
    965         private void replaceIterationsOf(Set<ITask> iteratedTasks, 
    966                         List<IUserSession> sessions, RuleApplicationData appData) { 
    967                 final Map<ITask, IIteration> iterations = new HashMap<ITask, IIteration>(); 
    968                 final Map<IIteration, List<IIterationInstance>> iterationInstances = new HashMap<IIteration, List<IIterationInstance>>(); 
    969  
    970                 for (final ITask iteratedTask : iteratedTasks) { 
    971  
    972                         final IIteration iteration = taskFactory.createNewIteration(); 
    973                         appData.newTaskCreated(iteration); 
    974                         iterations.put(iteratedTask, iteration); 
    975                         iterationInstances.put(iteration, 
    976                                         new LinkedList<IIterationInstance>()); 
    977                 } 
    978  
    979                 IIterationInstance iterationInstance; 
    980  
    981                 for (final IUserSession session : sessions) { 
    982                         int index = 0; 
    983                         iterationInstance = null; 
    984  
    985                         while (index < session.size()) { 
    986                                 // we prepared the task instances to refer to unique tasks, if 
    987                                 // they are treated 
    988                                 // as equal. Therefore, we just compare the identity of the 
    989                                 // tasks of the task 
    990                                 // instances 
    991                                 final ITask currentTask = session.get(index).getTask(); 
    992                                 final IIteration iteration = iterations.get(currentTask); 
    993                                 if (iteration != null) { 
    994                                         if ((iterationInstance == null) 
    995                                                         || (iterationInstance.getTask() != iteration)) { 
    996                                                 iterationInstance = taskFactory 
    997                                                                 .createNewTaskInstance(iteration); 
    998                                                 iterationInstances.get(iteration) 
    999                                                                 .add(iterationInstance);// TODO:: Don't create 
    1000                                                 // TaskInstances here, 
    1001                                                 // use a set of tasks 
    1002                                                 // instead 
    1003                                                 taskBuilder.addTaskInstance(session, index, 
    1004                                                                 iterationInstance); 
    1005                                                 index++; 
    1006                                         } 
    1007  
    1008                                         taskBuilder.addChild(iterationInstance, session.get(index)); 
    1009                                         taskBuilder.removeTaskInstance(session, index); 
    1010                                 } else { 
    1011                                         if (iterationInstance != null) { 
    1012                                                 iterationInstance = null; 
    1013                                         } 
    1014                                         index++; 
    1015                                 } 
    1016                         } 
    1017                 } 
    1018  
    1019                 for (final Map.Entry<IIteration, List<IIterationInstance>> entry : iterationInstances 
    1020                                 .entrySet()) { 
    1021                         harmonizeIterationInstancesModel(entry.getKey(), entry.getValue()); 
    1022                 } 
    1023         } 
    1024  
    1025         private void replaceMatches(RuleApplicationData appData) { 
    1026                 appData.replacedOccurences = new HashMap<Integer, List<MatchOccurence>>(); 
    1027  
    1028                 final int matchSeqSize = appData.getMatchseqs().size(); 
    1029                 int newThreads = nThreads; 
    1030                 if (matchSeqSize < nThreads) { 
    1031                         newThreads = matchSeqSize; 
    1032                 } 
    1033                 final ExecutorService executor = Executors 
    1034                                 .newFixedThreadPool(newThreads); 
    1035                 final int interval = matchSeqSize / newThreads; 
    1036                 int rest = matchSeqSize % newThreads; 
    1037  
    1038                 for (int i = 0; i < (matchSeqSize - interval); i += interval) { 
    1039                         int offset = 0; 
    1040                         if (rest != 0) { 
    1041                                 offset = 1; 
    1042                                 rest--; 
    1043                         } 
    1044                         final int from = i; 
    1045                         final int to = i + interval + offset; 
    1046                         System.out 
    1047                         .println("Replacement: Creating thread with matches from " 
    1048                                         + from + " to " + to); 
    1049                         // search each match in every other sequence 
    1050                         final ParallelMatchReplacer replacer = new ParallelMatchReplacer( 
    1051                                         appData, from, to); 
    1052                         executor.execute(replacer); 
    1053                 } 
    1054                 executor.shutdown(); 
    1055                 try { 
    1056                         executor.awaitTermination(2, TimeUnit.HOURS); 
    1057                 } catch (final InterruptedException e) { 
    1058                         // TODO Auto-generated catch block 
    1059                         e.printStackTrace(); 
    1060                 } 
    1061         } 
    1062  
    1063         public void saveAppData(String name) { 
    1064                 final String objectName = name; 
    1065                 final String filename = name + ".dat"; 
    1066                 final Object dataObject = GlobalDataContainer.getInstance().getData( 
    1067                                 objectName); 
    1068                 if (dataObject == null) { 
    1069                         CommandHelpers.objectNotFoundMessage(objectName); 
    1070                 } 
    1071                 FileOutputStream fos = null; 
    1072                 ObjectOutputStream out = null; 
    1073                 try { 
    1074                         fos = new FileOutputStream(filename); 
    1075                         out = new ObjectOutputStream(fos); 
    1076                         out.writeObject(dataObject); 
    1077                         out.close(); 
    1078                 } catch (final IOException ex) { 
    1079                         Console.logException(ex); 
    1080                 } 
    1081         } 
    1082  
    1083         /** 
    1084          * <p> 
    1085          * searches the provided sessions for task iterations. If a task is 
    1086          * iterated, it is added to the returned set. 
    1087          * </p> 
    1088          *  
    1089          * @param the 
    1090          *            session to search for iterations in 
    1091          *  
    1092          * @return a set of tasks being iterated somewhere 
    1093          */ 
    1094         private Set<ITask> searchIteratedTasks(List<IUserSession> sessions) { 
    1095                 final Set<ITask> iteratedTasks = new HashSet<ITask>(); 
    1096                 for (final IUserSession session : sessions) { 
    1097                         for (int i = 0; i < (session.size() - 1); i++) { 
    1098                                 // we prepared the task instances to refer to unique tasks, if 
    1099                                 // they are treated 
    1100                                 // as equal. Therefore, we just compare the identity of the 
    1101                                 // tasks of the task 
    1102                                 // instances 
    1103                                 if (session.get(i).getTask() == session.get(i + 1).getTask()) { 
    1104                                         iteratedTasks.add(session.get(i).getTask()); 
    1105                                 } 
    1106                         } 
    1107                 } 
    1108                 return iteratedTasks; 
    1109         } 
    1110  
    1111         private void searchMatchesInAllSessions(RuleApplicationData appData) { 
    1112                 Console.traceln(Level.INFO, 
    1113                                 "searching for patterns occuring most with " + nThreads 
    1114                                                 + " threads"); 
    1115                 // Prepare parallel search of matchseqs 
    1116  
    1117                 final int matchSeqSize = appData.getMatchseqs().size(); 
    1118                 int newThreads = nThreads; 
    1119                 if (matchSeqSize < nThreads) { 
    1120                         newThreads = matchSeqSize; 
    1121                 } 
    1122                 final int interval = matchSeqSize / newThreads; 
    1123                 int rest = matchSeqSize % newThreads; 
    1124                 final ExecutorService executor = Executors.newFixedThreadPool(nThreads); 
    1125  
    1126                 for (int i = 0; i < (matchSeqSize - interval); i += interval) { 
    1127                         int offset = 0; 
    1128                         if (rest != 0) { 
    1129                                 offset = 1; 
    1130                                 rest--; 
    1131                         } 
    1132                         final int from = i; 
    1133                         final int to = i + interval + offset; 
    1134                         System.out 
    1135                         .println("Match finding: Creating thread with matches from " 
    1136                                         + from + " to " + to); 
    1137                         // search each match in every other sequence 
    1138                         final ParallelMatchOcurrencesFinder finder = new ParallelMatchOcurrencesFinder( 
    1139                                         appData, from, to); 
    1140                         executor.execute(finder); 
    1141                 } 
    1142                 executor.shutdown(); 
    1143                 try { 
    1144                         executor.awaitTermination(2, TimeUnit.HOURS); 
    1145                 } catch (final InterruptedException e) { 
    1146                         // TODO Auto-generated catch block 
    1147                         e.printStackTrace(); 
    1148                 } 
    1149  
    1150         } 
    1151  
    1152         /* 
    1153          * (non-Javadoc) 
    1154          *  
    1155          * @see java.lang.Object#toString() 
    1156          */ 
    1157         @Override 
    1158         public String toString() { 
    1159                 return "SequenceForTaskDetectionRuleAlignment"; 
    1160         } 
    1161  
     1225         
    11621226} 
Note: See TracChangeset for help on using the changeset viewer.