source: branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/temporalrelation/TaskInstanceComparator.java @ 1733

Last change on this file since 1733 was 1733, checked in by rkrimmel, 10 years ago

Used Eclipse code cleanup

File size: 8.3 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.tasktrees.taskequality.TaskEquality;
22import de.ugoe.cs.autoquest.tasktrees.taskequality.TaskEqualityRuleManager;
23import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
24import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
25import de.ugoe.cs.autoquest.usageprofiles.SymbolComparator;
26
27/**
28 * <p>
29 * implementation of a symbol comparator for task instances. Internally, it uses
30 * comparison buffers to prevent comparing two tasks or task instances several
31 * times. It internally instantiates comparers being the implementation strategy
32 * of the comparisons required for a specific level of task equality. The
33 * comparers internally use the {@link TaskEqualityRuleManager} for performing
34 * comparisons.
35 * </p>
36 */
37public class TaskInstanceComparator implements SymbolComparator<ITaskInstance> {
38
39        /**
40         * <p>
41         * interface for internally used comparers containing only a compare method
42         * </p>
43         */
44        private static interface Comparer {
45
46                /**
47                 * <p>
48                 * returns true, if this comparator considers the provided tasks as
49                 * equal, false else
50                 * </p>
51                 *
52                 * @param task1
53                 *            the first task to compare
54                 * @param task2
55                 *            the second task to compare
56                 *
57                 * @return as described
58                 */
59                boolean compare(ITask task1, ITask task2);
60        }
61
62        /**
63         * <p>
64         * comparer that performs comparisons only on the provided level
65         * </p>
66         */
67        private static class DefaultComparer implements Comparer {
68
69                /**
70                 * <p>
71                 * the minimal task equality considered by this comparer
72                 * </p>
73                 */
74                private final TaskEquality minimalTaskEquality;
75
76                /**
77                 * <p>
78                 * initializes this comparer with the task equality to be considered
79                 * </p>
80                 */
81                public DefaultComparer(TaskEquality minimalTaskEquality) {
82                        this.minimalTaskEquality = minimalTaskEquality;
83                }
84
85                /*
86                 * (non-Javadoc)
87                 *
88                 * @see Comparer#compare(ITask, ITask)
89                 */
90                @Override
91                public boolean compare(ITask task1, ITask task2) {
92                        return TaskEqualityRuleManager.getInstance().areAtLeastEqual(task1,
93                                        task2, minimalTaskEquality);
94                }
95        }
96
97        /**
98         * <p>
99         * comparer that performs comparisons only on the lexical level
100         * </p>
101         */
102        private static class LexicalComparer implements Comparer {
103
104                /*
105                 * (non-Javadoc)
106                 *
107                 * @see Comparer#compare(ITask, ITask)
108                 */
109                @Override
110                public boolean compare(ITask task1, ITask task2) {
111                        return TaskEqualityRuleManager.getInstance().areLexicallyEqual(
112                                        task1, task2);
113                }
114        }
115
116        /**
117         * <p>
118         * comparer that performs comparisons only on the semantical level
119         * </p>
120         */
121        private static class SemanticalComparer implements Comparer {
122
123                /*
124                 * (non-Javadoc)
125                 *
126                 * @see Comparer#compare(ITask, ITask)
127                 */
128                @Override
129                public boolean compare(ITask task1, ITask task2) {
130                        return TaskEqualityRuleManager.getInstance().areSemanticallyEqual(
131                                        task1, task2);
132                }
133        }
134
135        /**
136         * <p>
137         * comparer that performs comparisons only on the syntactical level
138         * </p>
139         *
140         */
141        private static class SyntacticalComparer implements Comparer {
142
143                /*
144                 * (non-Javadoc)
145                 *
146                 * @see Comparer#compare(ITask, ITask)
147                 */
148                @Override
149                public boolean compare(ITask task1, ITask task2) {
150                        return TaskEqualityRuleManager.getInstance().areSyntacticallyEqual(
151                                        task1, task2);
152                }
153        }
154
155        /**  */
156        private static final long serialVersionUID = 1L;
157
158        /**
159         * the maximum size of the internal buffer used for storing comparison
160         * results
161         */
162        private static final int MAX_BUFFER_SIZE = 2 * 1024 * 1024;
163
164        /**
165         * the considered level of task equality
166         */
167        private final TaskEquality minimalTaskEquality;
168
169        /**
170         * the comparer used internally for comparing two tasks
171         */
172        private transient Comparer comparer;
173
174        /**
175         * the comparer used for comparing two tasks on the lexical level
176         */
177        private transient Comparer lexicalComparer;
178
179        /**
180         * internal buffer used for storing comparison results
181         */
182        private transient HashMap<Long, Boolean> equalityBuffer = new HashMap<Long, Boolean>();
183
184        /**
185         * internal buffer used for storing comparison results only for lexical
186         * comparisons
187         */
188        private transient HashMap<Long, Boolean> lexicalEqualityBuffer;
189
190        /**
191         * <p>
192         * initializes the comparator with a considered task equality level
193         * </p>
194         *
195         * @param minimalTaskEquality
196         *            the considered task equality level
197         */
198        public TaskInstanceComparator(TaskEquality minimalTaskEquality) {
199                this.minimalTaskEquality = minimalTaskEquality;
200                init();
201        }
202
203        /**
204         * <p>
205         * returns true, if this comparator considers the provided tasks as
206         * lexically equal, false else
207         * </p>
208         *
209         * @param task1
210         *            the first task to compare
211         * @param task2
212         *            the second task to compare
213         *
214         * @return as described
215         */
216        public boolean areLexicallyEqual(ITask task1, ITask task2) {
217                Boolean result;
218
219                if (task1 != task2) {
220                        long key = ((long) System.identityHashCode(task1)) << 32;
221                        key += System.identityHashCode(task2);
222
223                        result = lexicalEqualityBuffer.get(key);
224
225                        if (result == null) {
226                                result = lexicalComparer.compare(task1, task2);
227                                if (equalityBuffer.size() < MAX_BUFFER_SIZE) {
228                                        lexicalEqualityBuffer.put(key, result);
229                                }
230                        }
231                } else {
232                        result = true;
233                }
234
235                return result;
236        }
237
238        /**
239         * <p>
240         * can be called externally to clear the internal comparison buffers
241         * </p>
242         */
243        public void clearBuffers() {
244                equalityBuffer.clear();
245                init();
246        }
247
248        /**
249         * <p>
250         * returns true, if this comparator considers the provided tasks as equal,
251         * false else
252         * </p>
253         *
254         * @param task1
255         *            the first task to compare
256         * @param task2
257         *            the second task to compare
258         *
259         * @return as described
260         */
261        public boolean equals(ITask task1, ITask task2) {
262                Boolean result;
263
264                if (task1 != task2) {
265                        // if ((task1 instanceof IEventTask) && (task2 instanceof
266                        // IEventTask)) {
267                        long key = ((long) System.identityHashCode(task1)) << 32;
268                        key += System.identityHashCode(task2);
269
270                        result = equalityBuffer.get(key);
271
272                        if (result == null) {
273                                result = comparer.compare(task1, task2);
274
275                                if (equalityBuffer.size() < MAX_BUFFER_SIZE) {
276                                        equalityBuffer.put(key, result);
277                                }
278                        }
279                        /*
280                         * } else { result = false; }
281                         */
282                } else {
283                        result = true;
284                }
285
286                return result;
287        }
288
289        /*
290         * (non-Javadoc)
291         *
292         * @see SymbolComparator#equals(Object, Object)
293         */
294        @Override
295        public boolean equals(ITaskInstance taskInstance1,
296                        ITaskInstance taskInstance2) {
297                return equals(taskInstance1.getTask(), taskInstance2.getTask());
298        }
299
300        /**
301         * <p>
302         * initializes the comparator with comparers depending on the different
303         * comparison levels as well as with the required comparison buffers.
304         * Comparers and buffers for lexical comparison may be reused if the
305         * considered equality level is also lexical.
306         * </p>
307         */
308        private void init() {
309                if (minimalTaskEquality == TaskEquality.LEXICALLY_EQUAL) {
310                        comparer = new LexicalComparer();
311                } else if (minimalTaskEquality == TaskEquality.SYNTACTICALLY_EQUAL) {
312                        comparer = new SyntacticalComparer();
313                } else if (minimalTaskEquality == TaskEquality.SEMANTICALLY_EQUAL) {
314                        comparer = new SemanticalComparer();
315                } else {
316                        comparer = new DefaultComparer(this.minimalTaskEquality);
317                }
318
319                if (minimalTaskEquality == TaskEquality.LEXICALLY_EQUAL) {
320                        lexicalComparer = comparer;
321                        lexicalEqualityBuffer = equalityBuffer;
322                } else {
323                        lexicalComparer = new LexicalComparer();
324                        lexicalEqualityBuffer = new HashMap<Long, Boolean>();
325                }
326        }
327
328        /**
329         * <p>
330         * deserialize this object and reinitialize the buffers
331         * </p>
332         */
333        private void readObject(ObjectInputStream in) throws IOException,
334                        ClassNotFoundException {
335                in.defaultReadObject();
336                init();
337        }
338
339}
Note: See TracBrowser for help on using the repository browser.