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

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