source: trunk/autoquest-core-tasktrees/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskComparator.java @ 1256

Last change on this file since 1256 was 1256, checked in by pharms, 11 years ago
  • performance improvement for task tree generation
File size: 8.0 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.tasktrees.temporalrelation;
16
17import java.io.IOException;
18import java.io.ObjectInputStream;
19import java.util.HashMap;
20
21import de.ugoe.cs.autoquest.eventcore.IEventType;
22import de.ugoe.cs.autoquest.tasktrees.taskequality.TaskEquality;
23import de.ugoe.cs.autoquest.tasktrees.taskequality.TaskEqualityRuleManager;
24import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
25import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
26import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
27import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
28import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
29import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
30import de.ugoe.cs.autoquest.usageprofiles.SymbolComparator;
31
32/**
33 * TODO comment
34 */
35class TaskComparator implements SymbolComparator<ITaskInstance> {
36   
37    /**  */
38    private static final long serialVersionUID = 1L;
39   
40    /** */
41    private static final int MAX_BUFFER_SIZE = 10 * 1024 * 1024;
42
43    /** */
44    private TaskEquality minimalNodeEquality;
45
46    /** */
47    private transient Comparer comparer;
48
49    /** */
50    private transient Comparer lexicalComparer;
51
52    /** */
53    private transient HashMap<Long, Boolean> equalityBuffer = new HashMap<Long, Boolean>();
54
55    /** */
56    private transient HashMap<Long, Boolean> lexicalEqualityBuffer;
57
58    /**
59     *
60     */
61    public TaskComparator(TaskEquality minimalNodeEquality) {
62        this.minimalNodeEquality = minimalNodeEquality;
63        init();
64    }
65
66    /* (non-Javadoc)
67     * @see SymbolComparator#equals(Object, Object)
68     */
69    @Override
70    public boolean equals(ITaskInstance taskInstance1, ITaskInstance taskInstance2) {
71        return equals(taskInstance1.getTask(), taskInstance2.getTask());
72    }       
73
74    /**
75     *
76     */
77    public boolean equals(ITask task1, ITask task2) {
78        Boolean result;
79       
80        if (task1 != task2) {
81            if ((task1 instanceof IEventTask) && (task2 instanceof IEventTask)) {
82                long key = ((long) System.identityHashCode(task1)) << 32;
83                key += System.identityHashCode(task2);
84           
85                result = equalityBuffer.get(key);
86           
87                if (result == null) {
88                    result = comparer.compare(task1, task2);
89                   
90                    if (equalityBuffer.size() < MAX_BUFFER_SIZE) {
91                        equalityBuffer.put(key, result);
92                    }
93                }
94            }
95            else {
96                result = false;
97            }
98        }
99        else {
100            result = true;
101        }
102       
103        return result;
104    }
105
106    /**
107     *
108     */
109    public boolean areLexicallyEqual(ITask task1, ITask task2) {
110        Boolean result;
111       
112        if (task1 != task2) {
113            long key = ((long) System.identityHashCode(task1)) << 32;
114            key += System.identityHashCode(task2);
115           
116            result = lexicalEqualityBuffer.get(key);
117           
118            if (result == null) {
119                result = lexicalComparer.compare(task1, task2);
120                if (equalityBuffer.size() < 1024 * 1024 * 10) {
121                    lexicalEqualityBuffer.put(key, result);
122                }
123            }
124        }
125        else {
126            result = true;
127        }
128       
129        return result;
130    }
131   
132    /* (non-Javadoc)
133     * @see SymbolComparator#getBucketSearchOrder(Object)
134     */
135    @Override
136    public int[] getBucketSearchOrder(ITaskInstance taskInstance) {
137        // 0 = sequence; 1 = selection; 2 = iteration; 3 = optional; 4 = event task in general;
138        // other = hashCode of name of event type
139       
140        ITask task = taskInstance.getTask();
141       
142        if (task instanceof IEventTask) {
143            // event tasks are most likely equal to those of the event type with the same name,
144            // Afterwards, they may be equal to iterations, optionals, other event tasks,
145            // selections, and finally the rest.
146            IEventType eventType = ((IEventTask) task).getEventType();
147            return new int[] { eventType.getName().hashCode(), 2, 3, 4, 1 };                       
148        }
149        else if (task instanceof ISequence) {
150            return new int[] { 0, 2, 3, 1 };                       
151        }
152        else if (task instanceof ISelection) {
153            return new int[] { 1, 4, 2, 3 };                       
154        }
155        else if (task instanceof IIteration) {
156            return new int[] { 2, 1, 4 };                       
157        }
158       
159        return null;
160    }
161
162    /**
163     *
164     */
165    private void init() {
166        if (minimalNodeEquality == TaskEquality.LEXICALLY_EQUAL) {
167            comparer = new LexicalComparer();
168        }
169        else if (minimalNodeEquality == TaskEquality.SYNTACTICALLY_EQUAL) {
170            comparer = new SyntacticalComparer();
171        }
172        else if (minimalNodeEquality == TaskEquality.SEMANTICALLY_EQUAL) {
173            comparer = new SemanticalComparer();
174        }
175        else {
176            comparer = new DefaultComparer(this.minimalNodeEquality);
177        }
178       
179        if (minimalNodeEquality == TaskEquality.LEXICALLY_EQUAL) {
180            lexicalComparer = comparer;
181            lexicalEqualityBuffer = equalityBuffer;
182        }
183        else {
184            lexicalComparer = new LexicalComparer();
185            lexicalEqualityBuffer = new HashMap<Long, Boolean>();
186        }
187    }
188   
189    /**
190     * <p>
191     * deserialize this object and reinitialize the buffers
192     * </p>
193     */
194    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
195        in.defaultReadObject();
196        init();
197    }
198
199
200    /**
201     *
202     */
203    private static interface Comparer {
204       
205        /**
206         *
207         */
208        boolean compare(ITask task1, ITask task2);
209    }
210
211    /**
212     *
213     */
214    private static class LexicalComparer implements Comparer {
215       
216        /**
217         *
218         */
219        public boolean compare(ITask task1, ITask task2) {
220            return TaskEqualityRuleManager.getInstance().areLexicallyEqual(task1, task2);
221        }
222    }
223
224    /**
225     *
226     */
227    private static class SyntacticalComparer implements Comparer {
228       
229        /**
230         *
231         */
232        public boolean compare(ITask task1, ITask task2) {
233            return TaskEqualityRuleManager.getInstance().areSyntacticallyEqual(task1, task2);
234        }
235    }
236
237    /**
238     *
239     */
240    private static class SemanticalComparer implements Comparer {
241       
242        /**
243         *
244         */
245        public boolean compare(ITask task1, ITask task2) {
246            return TaskEqualityRuleManager.getInstance().areSemanticallyEqual(task1, task2);
247        }
248    }
249
250    /**
251     *
252     */
253    private static class DefaultComparer implements Comparer {
254       
255        /**
256         * <p>
257         * the minimal task equality two identified sublists need to have to consider them as equal
258         * </p>
259         */
260        private TaskEquality minimalNodeEquality;
261       
262        /**
263         *
264         */
265        public DefaultComparer(TaskEquality minimalNodeEquality) {
266           this.minimalNodeEquality = minimalNodeEquality;
267        }
268       
269        /**
270         *
271         */
272        public boolean compare(ITask task1, ITask task2) {
273            return TaskEqualityRuleManager.getInstance().areAtLeastEqual
274                (task1, task2, minimalNodeEquality);
275        }
276    }
277}
Note: See TracBrowser for help on using the repository browser.