]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/IntSet.java
Merge "Multiple reader thread support for db client"
[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     /** the index after the last entry in the list */
36     public int sizeOrData;
37
38     /** the default capacity for new lists */
39     protected static final int DEFAULT_CAPACITY = 3;
40
41     public static final int NO_DATA = -1;
42     
43     private static final Object[] EMPTY_ARRAY = new Object[0];
44
45     public static IntSet EMPTY = new IntSet();
46
47     private IntSet() {
48         support = null;
49     }
50
51     public IntSet(QuerySupport support) {
52         this.support = support.getSupport();
53         data = null;
54         sizeOrData = NO_DATA;
55     }
56
57     public IntSet(QuerySupport support, int value) {
58         this.support = support.getSupport();
59         data = null;
60         sizeOrData = value;
61     }
62
63     @Override
64     public int hashCode() {
65         return 31 * sizeOrData + 41 * Arrays.hashCode(data);
66     }
67     
68     @Override
69     public boolean equals(Object object) {
70         if (this == object)
71             return true;
72         else if (object == null)
73             return false;
74         else if (IntSet.class != object.getClass())
75             return false;
76         IntSet r = (IntSet)object;
77 //        System.out.println("equals " + this + " vs. " + r);
78         return sizeOrData == r.sizeOrData && Arrays.equals(data, r.data);
79     }
80
81
82     /**
83      * Returns the number of values in the list.
84      *
85      * @return the number of values in the list.
86      */
87     public int size() {
88         return data != null ? sizeOrData : (sizeOrData != NO_DATA ? 1 : 0);
89     }
90
91     /**
92      * Tests whether this list contains any values.
93      *
94      * @return true if the list is empty.
95      */
96     public boolean isEmpty() {
97         return sizeOrData == NO_DATA;
98     }
99
100     // modifying
101
102     /**
103      * Adds <tt>val</tt> to the end of the list, growing as needed.
104      *
105      * @param val an <code>int</code> value
106      */
107     public boolean add(int val) {
108         if(data == null) {
109             if(sizeOrData == val) return false;
110             if(sizeOrData == NO_DATA) {
111                 sizeOrData = val;
112                 return true;
113             } else {
114                 data = new int[DEFAULT_CAPACITY];
115                 data[0] = sizeOrData;
116                 data[1] = val;
117                 sizeOrData = 2;
118                 return true;
119             }
120         } else {
121             for(int i=0;i<sizeOrData;i++) if(data[i] == val) return false;
122             if(data.length == sizeOrData) {
123                 int newCap = data.length << 1;
124                 int[] tmp = new int[newCap];
125                 System.arraycopy(data, 0, tmp, 0, data.length);
126                 data = tmp;
127                 data[sizeOrData++] = val;
128             } else {
129                 data[sizeOrData++] = val;
130             }
131             return true;
132         }
133     }
134
135     public void forEach(TIntProcedure proc) {
136         if(data == null) {
137             if(sizeOrData != NO_DATA) proc.execute(sizeOrData);
138         } else {
139             for(int i = 0;i < sizeOrData ; i++) proc.execute(data[i]);
140         }
141     }
142     
143     public boolean contains(int val) {
144         if(data == null) {
145             return sizeOrData == val;
146         } else {
147             for(int i = 0;i < sizeOrData ; i++) if(data[i] == val) return true;
148         }
149         return false;
150     }
151
152     public void trim() {
153         if(data != null && sizeOrData < data.length) {
154             int newCap = sizeOrData;
155             int[] tmp = new int[newCap];
156             System.arraycopy(data, 0, tmp, 0, newCap);
157             data = tmp;
158             sizeOrData = newCap;
159         }
160     }
161
162     @Override
163     public boolean add(Resource e) {
164         return add(((ResourceImpl)e).id);
165     }
166
167     @Override
168     public boolean addAll(Collection<? extends Resource> c) {
169         boolean ret = false;
170         for (Resource r : c) {
171                 if (add(r))
172                         ret = true;
173         }
174         return ret;
175     }
176
177     @Override
178     public void clear() {
179         sizeOrData = NO_DATA;
180         data = null;
181     }
182
183     @Override
184     public boolean contains(Object o) {
185         assert(o != null);
186         return contains(((ResourceImpl)o).id);
187     }
188
189     @Override
190     public boolean containsAll(Collection<?> c) {
191         for (Object o : c) {
192                 if (!contains(o))
193                         return false;
194         }
195         return true;
196     }
197
198     @Override
199     public Iterator<Resource> iterator() {
200
201         class ArraySetIterator implements Iterator<Resource> {
202
203             int next = 0;
204
205             @Override
206             public boolean hasNext() {
207                 return next < size();
208             }
209
210             @Override
211             public Resource next() {
212                 if(size() == 1) {
213                     next++;
214                     return new ResourceImpl(support, sizeOrData);
215                 } else {
216                     return new ResourceImpl(support, data[next++]);
217                 }
218             }
219
220             @Override
221             public void remove() {
222                 throw new UnsupportedOperationException();
223             }
224
225         }
226
227         return new ArraySetIterator();
228
229     }
230
231     @Override
232     public boolean remove(Object o) {
233         throw new UnsupportedOperationException();
234     }
235
236     @Override
237     public boolean removeAll(Collection<?> c) {
238         throw new UnsupportedOperationException();
239     }
240
241     @Override
242     public boolean retainAll(Collection<?> c) {
243         throw new UnsupportedOperationException();
244     }
245
246     @Override
247     public Object[] toArray() {
248         if(data != null) {
249             Object[] result = new Object[sizeOrData];
250             for(int i=0;i<sizeOrData;++i)
251                 result[i] = new ResourceImpl(support, data[i]);
252             return result;
253         }
254         else if(sizeOrData == NO_DATA)
255             return EMPTY_ARRAY;
256         else
257             return new Object[] { new ResourceImpl(support, sizeOrData) };
258     }
259
260     @Override
261     public <T> T[] toArray(T[] a) {
262         throw new UnsupportedOperationException();
263     }
264
265     @Override
266     public String toString() {
267         return "IntSet " + sizeOrData + " " + Arrays.toString(data);
268     }
269     
270     @Override
271     public boolean disjoint(Set<Resource> other) {
272         if(other instanceof ResourceSet) {
273             ResourceSet rs = (ResourceSet)other;
274             if(data == null) {
275                 return !rs.contains(sizeOrData);
276             } else {
277                 for(int i = 0;i < sizeOrData ; i++) 
278                     if(rs.contains(data[i])) return false;
279                 return true;
280             }
281         } else {
282             if(data == null) {
283                 return !other.contains(sizeOrData);
284             } else {
285                 for(int i = 0;i < sizeOrData ; i++) 
286                     if(other.contains(data[i])) return false;
287                 return true;
288             }
289         }
290     }
291
292     public void forEach(ReadGraphImpl graph, IntProcedure procedure) throws DatabaseException {
293         if (data != null) {
294             for (int i=0;i<sizeOrData;++i)
295                 procedure.execute(graph, data[i]);
296         } else if(sizeOrData == NO_DATA) {
297         } else {
298             procedure.execute(graph, sizeOrData);
299         }
300         procedure.finished(graph);
301     }
302
303 }