]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/TableIntArraySet.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.procore / src / org / simantics / db / procore / cluster / TableIntArraySet.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.db.procore.cluster;\r
13 \r
14 import org.simantics.db.Resource;\r
15 import org.simantics.db.exception.DatabaseException;\r
16 import org.simantics.db.impl.ClusterI;\r
17 import org.simantics.db.impl.IntAllocatorI;\r
18 import org.simantics.db.impl.Modifier;\r
19 import org.simantics.db.impl.ResourceImpl;\r
20 import org.simantics.db.impl.graph.ReadGraphImpl;\r
21 import org.simantics.db.procedure.AsyncContextMultiProcedure;\r
22 import org.simantics.db.procedure.AsyncMultiProcedure;\r
23 \r
24 final class TableIntArraySet {\r
25     public static final int HeaderSize = 1; \r
26     private static final int SIZE_OFFSET = -1;\r
27     static int create(final int[] ints, IntAllocatorI allocator)\r
28     throws DatabaseException {\r
29         final int LENGTH = ints.length*2;\r
30         if (LENGTH <1)\r
31             throw new DatabaseException("Illegal argument to create TableIntArraySet.");\r
32         int newBase = allocator.allocate(LENGTH + HeaderSize) + HeaderSize;\r
33         int[] table = allocator.getTable();\r
34         table[newBase + SIZE_OFFSET] = -LENGTH;\r
35         for (int i=0; i<ints.length; ++i) {\r
36             if (0 == ints[i])\r
37                 throw new DatabaseException("Illegal value to create TableIntArraySet.");\r
38             table[newBase+i] = ints[i];\r
39         }\r
40         for (int i=ints.length; i<LENGTH; ++i) {\r
41             table[newBase+i] = 0;\r
42         }\r
43         return newBase;\r
44     }\r
45     static boolean isArraySet(int[] table, int base) {\r
46         return table[base + SIZE_OFFSET] < 0;\r
47     }\r
48     static class Ints {\r
49         int[] ints;\r
50         boolean found;\r
51         Ints() {\r
52             this.ints = null;\r
53             this.found = false;\r
54         }\r
55     }\r
56     static Ints getIntsIfValueNotFound(int[] table, int base, int aValue) {\r
57         final int REAL_SIZE = -table[base + SIZE_OFFSET];\r
58         assert(REAL_SIZE > 0);\r
59         Ints it = new Ints();\r
60         int i;\r
61         for (i=0; i<REAL_SIZE; ++i) {\r
62             if (0 == table[base+i])\r
63                 break;\r
64             else if (aValue == table[base+i]) {\r
65                 it.found = true;\r
66                 return it;\r
67             }\r
68         }\r
69         int size = i;\r
70         assert(size > 0);\r
71         it.ints = new int[size+1];\r
72         for (i=0; i<size; ++i)\r
73             it.ints[i] = table[base+i];\r
74         it.ints[i] = aValue;\r
75         return it;\r
76     }\r
77     /**\r
78      * @param table\r
79      * @param base\r
80      * @param object\r
81      * @param allocator\r
82      * @return new base if object was actually added.\r
83      */\r
84     static int addInt(int[] table, int base, final int object, IntAllocatorI allocator) {\r
85         final int size = -table[base + SIZE_OFFSET];\r
86         assert(size > 0);\r
87         int i;\r
88         for (i=0; i<size; ++i) {\r
89             if (object == table[base+i])\r
90                 return 0;\r
91             else if (0 == table[base+i])\r
92                 break;\r
93         }\r
94         if (i < size) {\r
95             assert(0 == table[base+i]);\r
96             table[base+i] = object;\r
97             return base;\r
98         }\r
99         final int newSize = size + 1;\r
100         int newBase = allocator.allocate(newSize + HeaderSize) + HeaderSize;\r
101         int[] newTable = allocator.getTable();\r
102         newTable[newBase + SIZE_OFFSET] = -newSize;\r
103         System.arraycopy(table, base, newTable, newBase, size);\r
104         newTable[newBase+size] = object;\r
105         return newBase;\r
106     }       \r
107     \r
108     static int removeInt(int[] table, int base, int object) {\r
109         final int size = -table[base + SIZE_OFFSET];\r
110         assert(size > 0);\r
111         int i;\r
112         for (i=0; i<size; ++i)\r
113             if (object == table[base+i])\r
114                 break;\r
115             else if (0 == table[base+i])\r
116                 return i; // not found\r
117         if (i == size)\r
118             return i; // not found\r
119         int end = size - 1;\r
120         for (;end>i; --end)\r
121                 if (0 != table[base + end])\r
122                         break;\r
123         table[base + i] = table[base + end];\r
124         table[base + end] = 0;\r
125         return end;\r
126     }\r
127 \r
128     static int removeIntLast(int[] table, int base)\r
129     throws DatabaseException {\r
130         final int size = getSize(table, base);\r
131         if (size != 1)\r
132             throw new DatabaseException("Illegal call of TableIntArraySet.removeLastint");\r
133         int t = table[base];\r
134         table[base] = 0;\r
135         return t;\r
136     }\r
137 \r
138     static int getSize(int[] table, int base) {\r
139         final int size = -table[base + SIZE_OFFSET];\r
140         assert(size > 0);\r
141         int i;\r
142         for (i=0; i<size; ++i)\r
143             if (0 == table[base+i])\r
144                 break;\r
145         return i;\r
146     }\r
147     \r
148     static int getAllocatedSize(int[] table, int base) {\r
149         final int size = -table[base + SIZE_OFFSET];\r
150         assert(size>0);\r
151         return size + HeaderSize;\r
152     }\r
153     \r
154     static void foreachInt(final int[] table, final int base, ReadGraphImpl graph, AsyncMultiProcedure<Resource> procedure, Modifier modifier) throws DatabaseException {\r
155         \r
156         final int size = -table[base + SIZE_OFFSET];\r
157         assert(size>0);\r
158         for (int i=0; i<size; ++i) {\r
159 \r
160                 int pRef = table[base+i];\r
161             if (0 == pRef)\r
162                 break;\r
163             int key = modifier.execute(pRef);\r
164             procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), key));\r
165             \r
166         }\r
167         \r
168                 procedure.finished(graph);\r
169 //              graph.state.dec(0);\r
170         \r
171     }\r
172 \r
173     static <C> void foreachInt(final int[] table, final int base, ReadGraphImpl graph, C context, AsyncContextMultiProcedure<C, Resource> procedure, Modifier modifier) throws DatabaseException {\r
174         \r
175         final int size = -table[base + SIZE_OFFSET];\r
176         assert(size>0);\r
177         for (int i=0; i<size; ++i) {\r
178 \r
179                 int pRef = table[base+i];\r
180             if (0 == pRef)\r
181                 break;\r
182             int key = modifier.execute(pRef);\r
183             procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), key));\r
184             \r
185         }\r
186         \r
187                 procedure.finished(graph);\r
188 //              graph.state.dec(0);\r
189         \r
190     }\r
191     \r
192     static int getSingleInt(final int[] table, final int base, Modifier modifier) throws DatabaseException {\r
193 \r
194         int result = 0;\r
195         \r
196         final int size = -table[base + SIZE_OFFSET];\r
197         assert(size>0);\r
198         for (int i=0; i<size; ++i) {\r
199 \r
200                 int pRef = table[base+i];\r
201             if (0 == pRef)\r
202                 break;\r
203             int key = modifier.execute(pRef);\r
204             if(result == 0) result = key;\r
205             else result = -1;\r
206             \r
207         }\r
208 \r
209         return result;\r
210         \r
211 //        if(result == -1) return 0;\r
212 //        else return result;\r
213         \r
214     }\r
215 \r
216     static <Context> boolean foreachInt(final int[] table, final int base\r
217                 , final ClusterI.ObjectProcedure<Context> procedure, final Context context, final Modifier modifier) throws DatabaseException {\r
218         final int size = -table[base + SIZE_OFFSET];\r
219         assert(size>0);\r
220         for (int i=0; i<size; ++i) {\r
221             int pRef = table[base+i];\r
222             if (0 == pRef)\r
223                 break;\r
224             int key;\r
225             if (null == modifier)\r
226                 key = pRef;\r
227             else\r
228                 key = modifier.execute(pRef);\r
229             if (procedure.execute(context, key))\r
230                 return true; // loop broken by procedure\r
231         }\r
232         return false; // loop finished\r
233     }\r
234 }\r
235 \r