]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/IntSet.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / IntSet.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2018 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.db.impl.query;
13
14 import java.util.Arrays;
15 import java.util.Collection;
16 import java.util.Iterator;
17 import java.util.Set;
18
19 import org.simantics.db.Resource;
20 import org.simantics.db.ResourceSet;
21 import org.simantics.db.exception.DatabaseException;
22 import org.simantics.db.impl.ResourceImpl;
23 import org.simantics.db.impl.graph.ReadGraphImpl;
24 import org.simantics.db.impl.support.ResourceSupport;
25
26 import gnu.trove.procedure.TIntProcedure;
27
28
29 final public class IntSet implements ResourceSet {
30
31     final private ResourceSupport support;
32
33     public int[] data;
34
35     private int sizeOrData;
36
37     /** the default capacity for new lists */
38     protected static final int DEFAULT_CAPACITY = 3;
39
40     public static final int NO_DATA = -1;
41     
42     private static final Object[] EMPTY_ARRAY = new Object[0];
43
44     public static IntSet EMPTY = new IntSet();
45
46     private IntSet() {
47         support = null;
48         data = null;
49         sizeOrData = NO_DATA;
50     }
51
52     public IntSet(QuerySupport support) {
53         this.support = support.getSupport();
54         data = null;
55         sizeOrData = NO_DATA;
56     }
57
58     public IntSet(QuerySupport support, int value) {
59         this.support = support.getSupport();
60         data = null;
61         sizeOrData = value;
62     }
63
64     @Override
65     public int hashCode() {
66         return 31 * sizeOrData + 41 * Arrays.hashCode(data);
67     }
68     
69     @Override
70     public boolean equals(Object object) {
71         if (this == object)
72             return true;
73         else if (object == null)
74             return false;
75         else if (IntSet.class != object.getClass())
76             return false;
77         IntSet r = (IntSet)object;
78 //        System.out.println("equals " + this + " vs. " + r);
79         return sizeOrData == r.sizeOrData && Arrays.equals(data, r.data);
80     }
81
82
83     /**
84      * Returns the number of values in the list.
85      *
86      * @return the number of values in the list.
87      */
88     public int size() {
89         return data != null ? sizeOrData : (sizeOrData != NO_DATA ? 1 : 0);
90     }
91
92     /**
93      * Tests whether this list contains any values.
94      *
95      * @return true if the list is empty.
96      */
97     public boolean isEmpty() {
98         return sizeOrData == NO_DATA;
99     }
100
101     // modifying
102
103     /**
104      * Adds <tt>val</tt> to the end of the list, growing as needed.
105      *
106      * @param val an <code>int</code> value
107      */
108     public boolean add(int val) {
109         if(data == null) {
110             if(sizeOrData == val) return false;
111             if(sizeOrData == NO_DATA) {
112                 sizeOrData = val;
113                 return true;
114             } else {
115                 data = new int[DEFAULT_CAPACITY];
116                 data[0] = sizeOrData;
117                 data[1] = val;
118                 sizeOrData = 2;
119                 return true;
120             }
121         } else {
122             for(int i=0;i<sizeOrData;i++) if(data[i] == val) return false;
123             if(data.length == sizeOrData) {
124                 int newCap = data.length << 1;
125                 int[] tmp = new int[newCap];
126                 System.arraycopy(data, 0, tmp, 0, data.length);
127                 data = tmp;
128                 data[sizeOrData++] = val;
129             } else {
130                 data[sizeOrData++] = val;
131             }
132             return true;
133         }
134     }
135
136     public void forEach(TIntProcedure proc) {
137         if(data == null) {
138             if(sizeOrData != NO_DATA) proc.execute(sizeOrData);
139         } else {
140             for(int i = 0;i < sizeOrData ; i++) proc.execute(data[i]);
141         }
142     }
143     
144     public boolean contains(int val) {
145         if(data == null) {
146             return sizeOrData == val;
147         } else {
148             for(int i = 0;i < sizeOrData ; i++) if(data[i] == val) return true;
149         }
150         return false;
151     }
152
153     public void trim() {
154         if(data != null && sizeOrData < data.length) {
155             int newCap = sizeOrData;
156             int[] tmp = new int[newCap];
157             System.arraycopy(data, 0, tmp, 0, newCap);
158             data = tmp;
159             sizeOrData = newCap;
160         }
161     }
162
163     @Override
164     public boolean add(Resource e) {
165         return add(((ResourceImpl)e).id);
166     }
167
168     @Override
169     public boolean addAll(Collection<? extends Resource> c) {
170         boolean ret = false;
171         for (Resource r : c) {
172                 if (add(r))
173                         ret = true;
174         }
175         return ret;
176     }
177
178     @Override
179     public void clear() {
180         sizeOrData = NO_DATA;
181         data = null;
182     }
183
184     @Override
185     public boolean contains(Object o) {
186         assert(o != null);
187         return contains(((ResourceImpl)o).id);
188     }
189
190     @Override
191     public boolean containsAll(Collection<?> c) {
192         for (Object o : c) {
193                 if (!contains(o))
194                         return false;
195         }
196         return true;
197     }
198
199     @Override
200     public Iterator<Resource> iterator() {
201
202         class ArraySetIterator implements Iterator<Resource> {
203
204             int next = 0;
205
206             @Override
207             public boolean hasNext() {
208                 return next < size();
209             }
210
211             @Override
212             public Resource next() {
213                 if(size() == 1) {
214                     next++;
215                     return new ResourceImpl(support, sizeOrData);
216                 } else {
217                     return new ResourceImpl(support, data[next++]);
218                 }
219             }
220
221             @Override
222             public void remove() {
223                 throw new UnsupportedOperationException();
224             }
225
226         }
227
228         return new ArraySetIterator();
229
230     }
231
232     @Override
233     public boolean remove(Object o) {
234         throw new UnsupportedOperationException();
235     }
236
237     @Override
238     public boolean removeAll(Collection<?> c) {
239         throw new UnsupportedOperationException();
240     }
241
242     @Override
243     public boolean retainAll(Collection<?> c) {
244         throw new UnsupportedOperationException();
245     }
246
247     @Override
248     public Object[] toArray() {
249         if(data != null) {
250             Object[] result = new Object[sizeOrData];
251             for(int i=0;i<sizeOrData;++i)
252                 result[i] = new ResourceImpl(support, data[i]);
253             return result;
254         }
255         else if(sizeOrData == NO_DATA)
256             return EMPTY_ARRAY;
257         else
258             return new Object[] { new ResourceImpl(support, sizeOrData) };
259     }
260
261     @Override
262     public <T> T[] toArray(T[] a) {
263         throw new UnsupportedOperationException();
264     }
265
266     @Override
267     public String toString() {
268         return "IntSet " + sizeOrData + " " + Arrays.toString(data);
269     }
270     
271     @Override
272     public boolean disjoint(Set<Resource> other) {
273         if(other instanceof ResourceSet) {
274             ResourceSet rs = (ResourceSet)other;
275             if(data == null) {
276                 return !rs.contains(sizeOrData);
277             } else {
278                 for(int i = 0;i < sizeOrData ; i++) 
279                     if(rs.contains(data[i])) return false;
280                 return true;
281             }
282         } else {
283             if(data == null) {
284                 return !other.contains(sizeOrData);
285             } else {
286                 for(int i = 0;i < sizeOrData ; i++) 
287                     if(other.contains(data[i])) return false;
288                 return true;
289             }
290         }
291     }
292
293     public void forEach(ReadGraphImpl graph, IntProcedure procedure) throws DatabaseException {
294         if (data != null) {
295             for (int i=0;i<sizeOrData;++i)
296                 procedure.execute(graph, data[i]);
297         } else if(sizeOrData == NO_DATA) {
298         } else {
299             procedure.execute(graph, sizeOrData);
300         }
301         procedure.finished(graph);
302     }
303     
304     public void serialize(QuerySerializer serializer) {
305         serializer.writeLE(size());
306         forEach(new TIntProcedure() {
307             
308             @Override
309             public boolean execute(int value) {
310                 serializer.addResource(value);
311                 return true;
312             }
313         });
314     }
315     
316     public static IntSet deserialize(QueryDeserializer deserializer) throws DatabaseException {
317         int size = deserializer.readLE4();
318         IntSet result = new IntSet();
319         for(int i=0;i<size;i++) {
320             result.add(deserializer.readResource());
321         }
322         return result;
323     }
324
325 }