-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.db.procore.cluster;\r
-\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.impl.ClusterI;\r
-import org.simantics.db.impl.IntAllocatorI;\r
-import org.simantics.db.impl.Modifier;\r
-import org.simantics.db.impl.ResourceImpl;\r
-import org.simantics.db.impl.graph.ReadGraphImpl;\r
-import org.simantics.db.procedure.AsyncContextMultiProcedure;\r
-import org.simantics.db.procedure.AsyncMultiProcedure;\r
-\r
-final class TableIntArraySet {\r
- public static final int HeaderSize = 1; \r
- private static final int SIZE_OFFSET = -1;\r
- static int create(final int[] ints, IntAllocatorI allocator)\r
- throws DatabaseException {\r
- final int LENGTH = ints.length*2;\r
- if (LENGTH <1)\r
- throw new DatabaseException("Illegal argument to create TableIntArraySet.");\r
- int newBase = allocator.allocate(LENGTH + HeaderSize) + HeaderSize;\r
- int[] table = allocator.getTable();\r
- table[newBase + SIZE_OFFSET] = -LENGTH;\r
- for (int i=0; i<ints.length; ++i) {\r
- if (0 == ints[i])\r
- throw new DatabaseException("Illegal value to create TableIntArraySet.");\r
- table[newBase+i] = ints[i];\r
- }\r
- for (int i=ints.length; i<LENGTH; ++i) {\r
- table[newBase+i] = 0;\r
- }\r
- return newBase;\r
- }\r
- static boolean isArraySet(int[] table, int base) {\r
- return table[base + SIZE_OFFSET] < 0;\r
- }\r
- static class Ints {\r
- int[] ints;\r
- boolean found;\r
- Ints() {\r
- this.ints = null;\r
- this.found = false;\r
- }\r
- }\r
- static Ints getIntsIfValueNotFound(int[] table, int base, int aValue) {\r
- final int REAL_SIZE = -table[base + SIZE_OFFSET];\r
- assert(REAL_SIZE > 0);\r
- Ints it = new Ints();\r
- int i;\r
- for (i=0; i<REAL_SIZE; ++i) {\r
- if (0 == table[base+i])\r
- break;\r
- else if (aValue == table[base+i]) {\r
- it.found = true;\r
- return it;\r
- }\r
- }\r
- int size = i;\r
- assert(size > 0);\r
- it.ints = new int[size+1];\r
- for (i=0; i<size; ++i)\r
- it.ints[i] = table[base+i];\r
- it.ints[i] = aValue;\r
- return it;\r
- }\r
- /**\r
- * @param table\r
- * @param base\r
- * @param object\r
- * @param allocator\r
- * @return new base if object was actually added.\r
- */\r
- static int addInt(int[] table, int base, final int object, IntAllocatorI allocator) {\r
- final int size = -table[base + SIZE_OFFSET];\r
- assert(size > 0);\r
- int i;\r
- for (i=0; i<size; ++i) {\r
- if (object == table[base+i])\r
- return 0;\r
- else if (0 == table[base+i])\r
- break;\r
- }\r
- if (i < size) {\r
- assert(0 == table[base+i]);\r
- table[base+i] = object;\r
- return base;\r
- }\r
- final int newSize = size + 1;\r
- int newBase = allocator.allocate(newSize + HeaderSize) + HeaderSize;\r
- int[] newTable = allocator.getTable();\r
- newTable[newBase + SIZE_OFFSET] = -newSize;\r
- System.arraycopy(table, base, newTable, newBase, size);\r
- newTable[newBase+size] = object;\r
- return newBase;\r
- } \r
- \r
- static int removeInt(int[] table, int base, int object) {\r
- final int size = -table[base + SIZE_OFFSET];\r
- assert(size > 0);\r
- int i;\r
- for (i=0; i<size; ++i)\r
- if (object == table[base+i])\r
- break;\r
- else if (0 == table[base+i])\r
- return i; // not found\r
- if (i == size)\r
- return i; // not found\r
- int end = size - 1;\r
- for (;end>i; --end)\r
- if (0 != table[base + end])\r
- break;\r
- table[base + i] = table[base + end];\r
- table[base + end] = 0;\r
- return end;\r
- }\r
-\r
- static int removeIntLast(int[] table, int base)\r
- throws DatabaseException {\r
- final int size = getSize(table, base);\r
- if (size != 1)\r
- throw new DatabaseException("Illegal call of TableIntArraySet.removeLastint");\r
- int t = table[base];\r
- table[base] = 0;\r
- return t;\r
- }\r
-\r
- static int getSize(int[] table, int base) {\r
- final int size = -table[base + SIZE_OFFSET];\r
- assert(size > 0);\r
- int i;\r
- for (i=0; i<size; ++i)\r
- if (0 == table[base+i])\r
- break;\r
- return i;\r
- }\r
- \r
- static int getAllocatedSize(int[] table, int base) {\r
- final int size = -table[base + SIZE_OFFSET];\r
- assert(size>0);\r
- return size + HeaderSize;\r
- }\r
- \r
- static void foreachInt(final int[] table, final int base, ReadGraphImpl graph, AsyncMultiProcedure<Resource> procedure, Modifier modifier) throws DatabaseException {\r
- \r
- final int size = -table[base + SIZE_OFFSET];\r
- assert(size>0);\r
- for (int i=0; i<size; ++i) {\r
-\r
- int pRef = table[base+i];\r
- if (0 == pRef)\r
- break;\r
- int key = modifier.execute(pRef);\r
- procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), key));\r
- \r
- }\r
- \r
- procedure.finished(graph);\r
-// graph.state.dec(0);\r
- \r
- }\r
-\r
- static <C> void foreachInt(final int[] table, final int base, ReadGraphImpl graph, C context, AsyncContextMultiProcedure<C, Resource> procedure, Modifier modifier) throws DatabaseException {\r
- \r
- final int size = -table[base + SIZE_OFFSET];\r
- assert(size>0);\r
- for (int i=0; i<size; ++i) {\r
-\r
- int pRef = table[base+i];\r
- if (0 == pRef)\r
- break;\r
- int key = modifier.execute(pRef);\r
- procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), key));\r
- \r
- }\r
- \r
- procedure.finished(graph);\r
-// graph.state.dec(0);\r
- \r
- }\r
- \r
- static int getSingleInt(final int[] table, final int base, Modifier modifier) throws DatabaseException {\r
-\r
- int result = 0;\r
- \r
- final int size = -table[base + SIZE_OFFSET];\r
- assert(size>0);\r
- for (int i=0; i<size; ++i) {\r
-\r
- int pRef = table[base+i];\r
- if (0 == pRef)\r
- break;\r
- int key = modifier.execute(pRef);\r
- if(result == 0) result = key;\r
- else result = -1;\r
- \r
- }\r
-\r
- return result;\r
- \r
-// if(result == -1) return 0;\r
-// else return result;\r
- \r
- }\r
-\r
- static <Context> boolean foreachInt(final int[] table, final int base\r
- , final ClusterI.ObjectProcedure<Context> procedure, final Context context, final Modifier modifier) throws DatabaseException {\r
- final int size = -table[base + SIZE_OFFSET];\r
- assert(size>0);\r
- for (int i=0; i<size; ++i) {\r
- int pRef = table[base+i];\r
- if (0 == pRef)\r
- break;\r
- int key;\r
- if (null == modifier)\r
- key = pRef;\r
- else\r
- key = modifier.execute(pRef);\r
- if (procedure.execute(context, key))\r
- return true; // loop broken by procedure\r
- }\r
- return false; // loop finished\r
- }\r
-}\r
-\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.procore.cluster;
+
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.impl.ClusterI;
+import org.simantics.db.impl.IntAllocatorI;
+import org.simantics.db.impl.Modifier;
+import org.simantics.db.impl.ResourceImpl;
+import org.simantics.db.impl.graph.ReadGraphImpl;
+import org.simantics.db.procedure.SyncContextMultiProcedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
+
+final class TableIntArraySet {
+ public static final int HeaderSize = 1;
+ private static final int SIZE_OFFSET = -1;
+ static int create(final int[] ints, IntAllocatorI allocator)
+ throws DatabaseException {
+ final int LENGTH = ints.length*2;
+ if (LENGTH <1)
+ throw new DatabaseException("Illegal argument to create TableIntArraySet.");
+ int newBase = allocator.allocate(LENGTH + HeaderSize) + HeaderSize;
+ int[] table = allocator.getTable();
+ table[newBase + SIZE_OFFSET] = -LENGTH;
+ for (int i=0; i<ints.length; ++i) {
+ if (0 == ints[i])
+ throw new DatabaseException("Illegal value to create TableIntArraySet.");
+ table[newBase+i] = ints[i];
+ }
+ for (int i=ints.length; i<LENGTH; ++i) {
+ table[newBase+i] = 0;
+ }
+ return newBase;
+ }
+ static boolean isArraySet(int[] table, int base) {
+ return table[base + SIZE_OFFSET] < 0;
+ }
+ static class Ints {
+ int[] ints;
+ boolean found;
+ Ints() {
+ this.ints = null;
+ this.found = false;
+ }
+ }
+ static Ints getIntsIfValueNotFound(int[] table, int base, int aValue) {
+ final int REAL_SIZE = -table[base + SIZE_OFFSET];
+ assert(REAL_SIZE > 0);
+ Ints it = new Ints();
+ int i;
+ for (i=0; i<REAL_SIZE; ++i) {
+ if (0 == table[base+i])
+ break;
+ else if (aValue == table[base+i]) {
+ it.found = true;
+ return it;
+ }
+ }
+ int size = i;
+ assert(size > 0);
+ it.ints = new int[size+1];
+ for (i=0; i<size; ++i)
+ it.ints[i] = table[base+i];
+ it.ints[i] = aValue;
+ return it;
+ }
+ /**
+ * @param table
+ * @param base
+ * @param object
+ * @param allocator
+ * @return new base if object was actually added.
+ */
+ static int addInt(int[] table, int base, final int object, IntAllocatorI allocator) {
+ final int size = -table[base + SIZE_OFFSET];
+ assert(size > 0);
+ int i;
+ for (i=0; i<size; ++i) {
+ if (object == table[base+i])
+ return 0;
+ else if (0 == table[base+i])
+ break;
+ }
+ if (i < size) {
+ assert(0 == table[base+i]);
+ table[base+i] = object;
+ return base;
+ }
+ final int newSize = size + 1;
+ int newBase = allocator.allocate(newSize + HeaderSize) + HeaderSize;
+ int[] newTable = allocator.getTable();
+ newTable[newBase + SIZE_OFFSET] = -newSize;
+ System.arraycopy(table, base, newTable, newBase, size);
+ newTable[newBase+size] = object;
+ return newBase;
+ }
+
+ static int removeInt(int[] table, int base, int object) {
+ final int size = -table[base + SIZE_OFFSET];
+ assert(size > 0);
+ int i;
+ for (i=0; i<size; ++i)
+ if (object == table[base+i])
+ break;
+ else if (0 == table[base+i])
+ return i; // not found
+ if (i == size)
+ return i; // not found
+ int end = size - 1;
+ for (;end>i; --end)
+ if (0 != table[base + end])
+ break;
+ table[base + i] = table[base + end];
+ table[base + end] = 0;
+ return end;
+ }
+
+ static int removeIntLast(int[] table, int base)
+ throws DatabaseException {
+ final int size = getSize(table, base);
+ if (size != 1)
+ throw new DatabaseException("Illegal call of TableIntArraySet.removeLastint");
+ int t = table[base];
+ table[base] = 0;
+ return t;
+ }
+
+ static int getSize(int[] table, int base) {
+ final int size = -table[base + SIZE_OFFSET];
+ assert(size > 0);
+ int i;
+ for (i=0; i<size; ++i)
+ if (0 == table[base+i])
+ break;
+ return i;
+ }
+
+ static int getAllocatedSize(int[] table, int base) {
+ final int size = -table[base + SIZE_OFFSET];
+ assert(size>0);
+ return size + HeaderSize;
+ }
+
+ static void foreachInt(final int[] table, final int base, ReadGraphImpl graph, SyncMultiProcedure<Resource> procedure, Modifier modifier) throws DatabaseException {
+
+ final int size = -table[base + SIZE_OFFSET];
+ assert(size>0);
+ for (int i=0; i<size; ++i) {
+
+ int pRef = table[base+i];
+ if (0 == pRef)
+ break;
+ int key = modifier.execute(pRef);
+ procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), key));
+
+ }
+
+ procedure.finished(graph);
+// graph.state.dec(0);
+
+ }
+
+ static <C> void foreachInt(final int[] table, final int base, ReadGraphImpl graph, C context, SyncContextMultiProcedure<C, Resource> procedure, Modifier modifier) throws DatabaseException {
+
+ final int size = -table[base + SIZE_OFFSET];
+ assert(size>0);
+ for (int i=0; i<size; ++i) {
+
+ int pRef = table[base+i];
+ if (0 == pRef)
+ break;
+ int key = modifier.execute(pRef);
+ procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), key));
+
+ }
+
+ procedure.finished(graph, context);
+// graph.state.dec(0);
+
+ }
+
+ static int getSingleInt(final int[] table, final int base, Modifier modifier) throws DatabaseException {
+
+ int result = 0;
+
+ final int size = -table[base + SIZE_OFFSET];
+ assert(size>0);
+ for (int i=0; i<size; ++i) {
+
+ int pRef = table[base+i];
+ if (0 == pRef)
+ break;
+ int key = modifier.execute(pRef);
+ if(result == 0) result = key;
+ else result = -1;
+
+ }
+
+ return result;
+
+// if(result == -1) return 0;
+// else return result;
+
+ }
+
+ static <Context> boolean foreachInt(final int[] table, final int base
+ , final ClusterI.ObjectProcedure<Context> procedure, final Context context, final Modifier modifier) throws DatabaseException {
+ final int size = -table[base + SIZE_OFFSET];
+ assert(size>0);
+ for (int i=0; i<size; ++i) {
+ int pRef = table[base+i];
+ if (0 == pRef)
+ break;
+ int key;
+ if (null == modifier)
+ key = pRef;
+ else
+ key = modifier.execute(pRef);
+ if (procedure.execute(context, key))
+ return true; // loop broken by procedure
+ }
+ return false; // loop finished
+ }
+}
+