-/*******************************************************************************\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.exception.DatabaseException;\r
-import org.simantics.db.impl.ClusterI;\r
-import org.simantics.db.impl.IntAllocatorI;\r
-import org.simantics.db.impl.Modifier;\r
-\r
-final class TableIntArraySet2 {\r
- public static final int HeaderSize = 1; \r
- private static final int SIZE_OFFSET = -1;\r
- static int create(final int[] keys, final int[] vals, IntAllocatorI allocator)\r
- throws DatabaseException {\r
- final int LENGTH = keys.length;\r
- if (LENGTH < 1 || LENGTH != vals.length)\r
- throw new DatabaseException("Illegal argument to create TableIntArraySet2.");\r
- int newBase = allocator.allocate(LENGTH*2 + HeaderSize) + HeaderSize;\r
- int[] table = allocator.getTable();\r
- table[newBase + SIZE_OFFSET] = -LENGTH;\r
- for (int i=0; i<LENGTH; ++i) {\r
- if (0 == keys[i])\r
- throw new DatabaseException("Illegal value to create TableIntArraySet2.");\r
- table[newBase + i*2] = keys[i];\r
- table[newBase + i*2 + 1] = vals[i];\r
- }\r
- return newBase;\r
- }\r
- static boolean isArraySet(int[] table, int base) {\r
- return table[base + SIZE_OFFSET] < 0;\r
- }\r
- static class Tables {\r
- int[] keys;\r
- int[] vals;\r
- public Tables() {\r
- this.keys = null;\r
- this.vals = null;\r
- }\r
- }\r
- static Tables getInts(int[] table, int base) {\r
- final int REAL_SIZE = -table[base + SIZE_OFFSET];\r
- assert(REAL_SIZE > 0);\r
- Tables t = new Tables();\r
- int i;\r
- for (i=0; i<REAL_SIZE; ++i) {\r
- int k = table[base + i*2];\r
- if (0 == k)\r
- break;\r
- }\r
- final int size = i;\r
- assert(size > 0);\r
- t.keys = new int[size];\r
- t.vals = new int[size];\r
- for (i=0; i<size; ++i){\r
- t.keys[i] = table[base + i*2];\r
- t.vals[i] = table[base + i*2 + 1];\r
- }\r
- return t;\r
- }\r
- static int get(int[] table, int base, int aKey) {\r
- final int REAL_SIZE = -table[base + SIZE_OFFSET];\r
- assert(REAL_SIZE > 0);\r
- for (int i=0; i<REAL_SIZE; ++i, base += 2) {\r
- if (0 == table[base])\r
- return 0;\r
- else if (aKey == table[base]) {\r
- return table[base + 1];\r
- }\r
- }\r
- return 0;\r
- }\r
- /**\r
- * @param table\r
- * @param base\r
- * @param key\r
- * @param allocator\r
- * @return new base if object was actually added.\r
- */\r
- static int addInt(int[] table, int base, final int key, int val, 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 (key == table[base + i*2]) {\r
- if (val == table[base + i*2 + 1])\r
- return 0;\r
- else {\r
- table[base + i*2 + 1] = val;\r
- return base;\r
- }\r
- } else if (0 == table[base + i*2])\r
- break;\r
- }\r
- if (i < size) {\r
- assert(0 == table[base + i*2]);\r
- table[base + i*2] = key;\r
- table[base + i*2 + 1] = val;\r
- return base;\r
- }\r
- final int newSize = size + 1;\r
- int newBase = allocator.allocate(newSize*2 + HeaderSize) + HeaderSize;\r
- int[] newTable = allocator.getTable();\r
- newTable[newBase + SIZE_OFFSET] = -newSize;\r
- System.arraycopy(table, base, newTable, newBase, size*2);\r
- newTable[newBase + size*2] = key;\r
- newTable[newBase + size*2 + 1] = val;\r
- return newBase;\r
- } \r
- \r
- static boolean removeInt(int[] table, int base, int key) {\r
- final int size = -table[base + SIZE_OFFSET];\r
- assert(size > 0);\r
- int i;\r
- for (i=0; i<size; ++i)\r
- if (key == table[base + i*2])\r
- break;\r
- else if (0 == table[base + i*2])\r
- return false; // not found\r
- if (i == size)\r
- return false; // not found\r
- int end = size - 1;\r
- for (;end>i; --end)\r
- if (0 != table[base + end*2])\r
- break;\r
- table[base + i*2] = table[base + end*2];\r
- table[base + i*2 + 1] = table[base + end*2 + 1];\r
- table[base + end*2] = 0;\r
- table[base + end*2 + 1] = 0;\r
- return true;\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*2])\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 <Context> boolean foreachInt(final int[] table, final int base\r
- , final ClusterI.PredicateProcedure<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*2];\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, table[base + i*2 + 1]))\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.exception.DatabaseException;
+import org.simantics.db.impl.ClusterI;
+import org.simantics.db.impl.IntAllocatorI;
+import org.simantics.db.impl.Modifier;
+
+final class TableIntArraySet2 {
+ public static final int HeaderSize = 1;
+ private static final int SIZE_OFFSET = -1;
+ static int create(final int[] keys, final int[] vals, IntAllocatorI allocator)
+ throws DatabaseException {
+ final int LENGTH = keys.length;
+ if (LENGTH < 1 || LENGTH != vals.length)
+ throw new DatabaseException("Illegal argument to create TableIntArraySet2.");
+ int newBase = allocator.allocate(LENGTH*2 + HeaderSize) + HeaderSize;
+ int[] table = allocator.getTable();
+ table[newBase + SIZE_OFFSET] = -LENGTH;
+ for (int i=0; i<LENGTH; ++i) {
+ if (0 == keys[i])
+ throw new DatabaseException("Illegal value to create TableIntArraySet2.");
+ table[newBase + i*2] = keys[i];
+ table[newBase + i*2 + 1] = vals[i];
+ }
+ return newBase;
+ }
+ static boolean isArraySet(int[] table, int base) {
+ return table[base + SIZE_OFFSET] < 0;
+ }
+ static class Tables {
+ int[] keys;
+ int[] vals;
+ public Tables() {
+ this.keys = null;
+ this.vals = null;
+ }
+ }
+ static Tables getInts(int[] table, int base) {
+ final int REAL_SIZE = -table[base + SIZE_OFFSET];
+ assert(REAL_SIZE > 0);
+ Tables t = new Tables();
+ int i;
+ for (i=0; i<REAL_SIZE; ++i) {
+ int k = table[base + i*2];
+ if (0 == k)
+ break;
+ }
+ final int size = i;
+ assert(size > 0);
+ t.keys = new int[size];
+ t.vals = new int[size];
+ for (i=0; i<size; ++i){
+ t.keys[i] = table[base + i*2];
+ t.vals[i] = table[base + i*2 + 1];
+ }
+ return t;
+ }
+ static int get(int[] table, int base, int aKey) {
+ final int REAL_SIZE = -table[base + SIZE_OFFSET];
+ assert(REAL_SIZE > 0);
+ for (int i=0; i<REAL_SIZE; ++i, base += 2) {
+ if (0 == table[base])
+ return 0;
+ else if (aKey == table[base]) {
+ return table[base + 1];
+ }
+ }
+ return 0;
+ }
+ /**
+ * @param table
+ * @param base
+ * @param key
+ * @param allocator
+ * @return new base if object was actually added.
+ */
+ static int addInt(int[] table, int base, final int key, int val, IntAllocatorI allocator) {
+ final int size = -table[base + SIZE_OFFSET];
+ assert(size > 0);
+ int i;
+ for (i=0; i<size; ++i) {
+ if (key == table[base + i*2]) {
+ if (val == table[base + i*2 + 1])
+ return 0;
+ else {
+ table[base + i*2 + 1] = val;
+ return base;
+ }
+ } else if (0 == table[base + i*2])
+ break;
+ }
+ if (i < size) {
+ assert(0 == table[base + i*2]);
+ table[base + i*2] = key;
+ table[base + i*2 + 1] = val;
+ return base;
+ }
+ final int newSize = size + 1;
+ int newBase = allocator.allocate(newSize*2 + HeaderSize) + HeaderSize;
+ int[] newTable = allocator.getTable();
+ newTable[newBase + SIZE_OFFSET] = -newSize;
+ System.arraycopy(table, base, newTable, newBase, size*2);
+ newTable[newBase + size*2] = key;
+ newTable[newBase + size*2 + 1] = val;
+ return newBase;
+ }
+
+ static boolean removeInt(int[] table, int base, int key) {
+ final int size = -table[base + SIZE_OFFSET];
+ assert(size > 0);
+ int i;
+ for (i=0; i<size; ++i)
+ if (key == table[base + i*2])
+ break;
+ else if (0 == table[base + i*2])
+ return false; // not found
+ if (i == size)
+ return false; // not found
+ int end = size - 1;
+ for (;end>i; --end)
+ if (0 != table[base + end*2])
+ break;
+ table[base + i*2] = table[base + end*2];
+ table[base + i*2 + 1] = table[base + end*2 + 1];
+ table[base + end*2] = 0;
+ table[base + end*2 + 1] = 0;
+ return true;
+ }
+
+ 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*2])
+ break;
+ return i;
+ }
+
+ static int getAllocatedSize(int[] table, int base) {
+ final int size = -table[base + SIZE_OFFSET];
+ assert(size>0);
+ return size + HeaderSize;
+ }
+
+ static <Context> boolean foreachInt(final int[] table, final int base
+ , final ClusterI.PredicateProcedure<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*2];
+ if (0 == pRef)
+ break;
+ int key;
+ if (null == modifier)
+ key = pRef;
+ else
+ key = modifier.execute(pRef);
+ if (procedure.execute(context, key, table[base + i*2 + 1]))
+ return true; // loop broken by procedure
+ }
+ return false; // loop finished
+ }
+}
+