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