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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.db.procore.cluster;
\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
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
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
37 throw new DatabaseException("Illegal value to create TableIntArraySet.");
\r
38 table[newBase+i] = ints[i];
\r
40 for (int i=ints.length; i<LENGTH; ++i) {
\r
41 table[newBase+i] = 0;
\r
45 static boolean isArraySet(int[] table, int base) {
\r
46 return table[base + SIZE_OFFSET] < 0;
\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
61 for (i=0; i<REAL_SIZE; ++i) {
\r
62 if (0 == table[base+i])
\r
64 else if (aValue == table[base+i]) {
\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
82 * @return new base if object was actually added.
\r
84 static int addInt(int[] table, int base, final int object, IntAllocatorI allocator) {
\r
85 final int size = -table[base + SIZE_OFFSET];
\r
88 for (i=0; i<size; ++i) {
\r
89 if (object == table[base+i])
\r
91 else if (0 == table[base+i])
\r
95 assert(0 == table[base+i]);
\r
96 table[base+i] = object;
\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
108 static int removeInt(int[] table, int base, int object) {
\r
109 final int size = -table[base + SIZE_OFFSET];
\r
112 for (i=0; i<size; ++i)
\r
113 if (object == table[base+i])
\r
115 else if (0 == table[base+i])
\r
116 return i; // not found
\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
123 table[base + i] = table[base + end];
\r
124 table[base + end] = 0;
\r
128 static int removeIntLast(int[] table, int base)
\r
129 throws DatabaseException {
\r
130 final int size = getSize(table, base);
\r
132 throw new DatabaseException("Illegal call of TableIntArraySet.removeLastint");
\r
133 int t = table[base];
\r
138 static int getSize(int[] table, int base) {
\r
139 final int size = -table[base + SIZE_OFFSET];
\r
142 for (i=0; i<size; ++i)
\r
143 if (0 == table[base+i])
\r
148 static int getAllocatedSize(int[] table, int base) {
\r
149 final int size = -table[base + SIZE_OFFSET];
\r
151 return size + HeaderSize;
\r
154 static void foreachInt(final int[] table, final int base, ReadGraphImpl graph, AsyncMultiProcedure<Resource> procedure, Modifier modifier) throws DatabaseException {
\r
156 final int size = -table[base + SIZE_OFFSET];
\r
158 for (int i=0; i<size; ++i) {
\r
160 int pRef = table[base+i];
\r
163 int key = modifier.execute(pRef);
\r
164 procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), key));
\r
168 procedure.finished(graph);
\r
169 // graph.state.dec(0);
\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
175 final int size = -table[base + SIZE_OFFSET];
\r
177 for (int i=0; i<size; ++i) {
\r
179 int pRef = table[base+i];
\r
182 int key = modifier.execute(pRef);
\r
183 procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), key));
\r
187 procedure.finished(graph);
\r
188 // graph.state.dec(0);
\r
192 static int getSingleInt(final int[] table, final int base, Modifier modifier) throws DatabaseException {
\r
196 final int size = -table[base + SIZE_OFFSET];
\r
198 for (int i=0; i<size; ++i) {
\r
200 int pRef = table[base+i];
\r
203 int key = modifier.execute(pRef);
\r
204 if(result == 0) result = key;
\r
211 // if(result == -1) return 0;
\r
212 // else return result;
\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
220 for (int i=0; i<size; ++i) {
\r
221 int pRef = table[base+i];
\r
225 if (null == modifier)
\r
228 key = modifier.execute(pRef);
\r
229 if (procedure.execute(context, key))
\r
230 return true; // loop broken by procedure
\r
232 return false; // loop finished
\r