-/*******************************************************************************\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.impl;\r
-\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.impl.ClusterI.Procedure;\r
-import org.simantics.db.service.Bytes;\r
-\r
-interface TableFactoryI<TableType> {\r
- TableType newTable(int size);\r
- boolean isEqual(TableType t1, int t1Start, int size, TableType t2, int t2Start);\r
-}\r
-\r
-class ByteFactory implements TableFactoryI<byte[]> {\r
- @Override\r
- public byte[] newTable(int size) {\r
- return new byte[size];\r
- }\r
-\r
- @Override\r
- public boolean isEqual(byte[] t1, int start, int size, byte[] t2, int start2) {\r
- for (int i=0; i<size; ++i)\r
- if (t1[start + i] != t2[start2 + i])\r
- return false;\r
- return true;\r
- }\r
-}\r
-\r
-class IntFactory implements TableFactoryI<int[]> {\r
- @Override\r
- public int[] newTable(int size) {\r
- return new int[size];\r
- }\r
-\r
- @Override\r
- public boolean isEqual(int[] t1, int start, int size, int[] t2, int start2) {\r
- for (int i=0; i<size; ++i)\r
- if (t1[start + i] != t2[start2 + i])\r
- return false;\r
- return true;\r
- }\r
-}\r
-\r
-class LongFactory implements TableFactoryI<long[]> {\r
- @Override\r
- public long[] newTable(int size) {\r
- return new long[size];\r
- }\r
-\r
- @Override\r
- public boolean isEqual(long[] t1, int start, int size, long[] t2, int start2) {\r
- for (int i=0; i<size; ++i)\r
- if (t1[start + i] != t2[start2 + i])\r
- return false;\r
- return true;\r
- }\r
-}\r
-\r
-public abstract class Table<TableType> {\r
- private static final int INITIAL_SIZE = 100; // Initial size of the table. Must be greater or equal than header_size;\r
- private static final int INCREMENT_SIZE = 1000; // Minimum increment size of the table.\r
- protected static final int ZERO_SHIFT = 1; // Indexes are guaranteed not to be zero.\r
- final private TableHeader header;\r
- final private TableFactoryI<TableType> factory;\r
- final private TableSizeListener sizeListener;\r
- public int offset; // Offset of table in containing array.\r
- public TableType table;\r
- protected Table(TableFactoryI<TableType> factory, TableSizeListener sizeListener, int[] header, int headerBase) {\r
- this.factory = factory;\r
- this.sizeListener = sizeListener;\r
- this.header = new TableHeader(header, headerBase);\r
- this.offset = -ZERO_SHIFT;\r
- newTable(INITIAL_SIZE);\r
- this.header.setSize(0);\r
- this.header.setCount(0);\r
- this.header.setOffset(offset);\r
- }\r
-\r
-// final int size(Object bytes) {\r
-// if(bytes instanceof byte[]) return ((byte[])bytes).length;\r
-// if(bytes instanceof int[]) return ((int[])bytes).length;\r
-// if(bytes instanceof long[]) return ((long[])bytes).length;\r
-// return 0;\r
-// }\r
-\r
- protected Table(TableFactoryI<TableType> factory, TableSizeListener sizeListener, int[] header, int headerBase, TableType bytes) {\r
-// System.out.println("Table size=" + size(bytes) + " header = " + Arrays.toString(Arrays.copyOfRange(header, headerBase, headerBase + 4)));\r
- this.factory = factory;\r
- this.sizeListener = sizeListener;\r
- this.header = new TableHeader(header, headerBase);\r
- offset = this.header.getOffset();\r
- this.table = bytes;\r
- }\r
- /**\r
- * Create and initialize this with a new table.\r
- *\r
- * @param capacity of the table. How many elements the table can hold without allocating new space.\r
- * @param size of the table. How many elements have been used.\r
- * @param count of how many segments has been have been allocated.\r
- * @return old table.\r
- */\r
- final protected TableType createNewTable(int capacity, int size, int count) {\r
- TableType t = table;\r
- this.offset = -ZERO_SHIFT;\r
- newTable(capacity);\r
- sizeListener.resized();\r
- header.setSize(size);\r
- header.setCount(count);\r
- header.setOffset(offset);\r
- return t;\r
- }\r
- public final int getTableCapacity() {\r
- return header.getCapacity();\r
- }\r
- public final int getTableSize() {\r
- return header.getSize();\r
- }\r
- public final int getTableCount() {\r
- return header.getCount();\r
- }\r
- protected int convertRealIndexToTableIndex(int realIndex) {\r
- return realIndex - offset;\r
- }\r
- protected final int checkIndexAndGetRealIndex(int index, int size) {\r
- if (index < ZERO_SHIFT)\r
- throw new IllegalArgumentException("Underflow, index=" + index);\r
- if ((size > 0 && index - ZERO_SHIFT + size > header.getSize()))\r
- throw new IllegalArgumentException("Overflow, index=" + index + " size=" + size);\r
- return index + offset;\r
- }\r
- protected final int checkIndexAndGetRealIndexEx(int index, int size) {\r
- if (index < ZERO_SHIFT || size < 1)\r
- throw new IllegalArgumentException("Underflow, index=" + index + " size=" + size);\r
- if (index - ZERO_SHIFT + size < header.getSize())\r
- return index + offset;\r
- else if (index - ZERO_SHIFT + size == header.getSize())\r
- return -1;\r
- else\r
- throw new IllegalArgumentException("Underflow, index=" + index + " size=" + size);\r
- }\r
- final protected void getCopy(int index, byte[] to, int start, int size) {\r
- int realIndex = checkIndexAndGetRealIndex(index, size);\r
- if (size < 0)\r
- throw new IllegalArgumentException("Illgal table size " + size);\r
- System.arraycopy(table, realIndex, to, start, size);\r
- }\r
- final protected void getCopy(int index, char[] to, int start, int size) {\r
-// int realIndex = checkIndexAndGetRealIndex(index, size);\r
-// if (size < 0)\r
-// throw new IllegalArgumentException("Illgal table size " + size);\r
- byte[] bs = (byte[])table;\r
- start += index+offset+1;\r
- for(int i=0;i<size;i++) to[i] = (char)bs[start++];\r
-// System.arraycopy(table, realIndex, to, start, size);\r
- }\r
- final protected void setCopy(int index, int size, TableType from, int fromStartIndex) {\r
-// System.out.println("setCopy index=" + index + " size=" + size + "fromStartIndex=" + fromStartIndex + "from.length=" + ((byte[])from).length + "table.length=" + ((byte[])table).length);\r
- int realIndex = checkIndexAndGetRealIndex(index, size);\r
- System.arraycopy(from, fromStartIndex, table, realIndex, size);\r
- }\r
- final protected boolean isEqual(int index, TableType to, int toStartIndex, int toSize) {\r
- int realIndex = checkIndexAndGetRealIndex(index, toSize);\r
- return factory.isEqual(table, realIndex, toSize, to, toStartIndex);\r
- }\r
- /**\r
- * @param size of the element (how many table slots is allocated).\r
- * @return table index not the real index. To get real index use checkIndexAndGetRealIndex.\r
- */\r
- final protected int createNewElement(int size) {\r
- if (size < 0)\r
- throw new IllegalArgumentException("Illegal table size " + size);\r
- if (0 == size)\r
- return ZERO_SHIFT;\r
- int oldSize = header.getSize();\r
- int newSize = oldSize + size;\r
- if (newSize > header.getCapacity())\r
- realloc(newSize);\r
- header.setSize(newSize);\r
- header.setCount(header.getCount()+1);\r
- return ZERO_SHIFT + oldSize;\r
- }\r
- final protected void deleteOldElement(int index, int size) {\r
- checkIndexAndGetRealIndex(index, size);\r
- header.setCount(header.getCount()-1);\r
- }\r
- final protected TableHeader getHeader() {\r
- return header;\r
- }\r
- final protected int getTableBase() {\r
- return offset + ZERO_SHIFT;\r
- }\r
- final protected TableType getTable() {\r
- return table;\r
- }\r
- final protected int getExtra(int index) {\r
- return header.getExtra(index);\r
- }\r
- final protected void setExtra(int index, int value) {\r
- header.setExtra(index, value);\r
- }\r
- final private void realloc(int newSize) {\r
- int realCapacity = newSize + Math.max(INCREMENT_SIZE, newSize/10);\r
- TableType oldTable = table;\r
- newTable(realCapacity);\r
- sizeListener.resized();\r
- int oldBase = getTableBase();\r
- offset = -ZERO_SHIFT;\r
- header.setOffset(offset);\r
- int oldSize = header.getSize();\r
- // If zero can cause ArrayIndexOutOfBoundsException because oldBase\r
- // (index) can be out of bounds in this case and it is checked even\r
- // if olsSize is zero (i.e. number of copied bytes is zero).\r
- if (oldSize > 0) {\r
- System.arraycopy(oldTable, oldBase, table, 0, oldSize);\r
- }\r
- }\r
- final private void newTable(int capacity) {\r
- table = factory.newTable(capacity);\r
- header.setCapacity(capacity);\r
- }\r
- \r
- public <T> int store(T _ret, int retPos) {\r
- \r
- int off = retPos;\r
- \r
- if(table instanceof byte[]) {\r
- System.arraycopy(table, getTableBase(), _ret, retPos, getHeader().getSize());\r
- retPos += getHeader().getSize();\r
- } else if(table instanceof int[]) {\r
- int[] t = (int[])table;\r
- int[] ret = (int[])_ret;\r
- for(int i=getTableBase();i<getTableBase() + getHeader().getSize();i++) {\r
- int v = t[i];\r
- ret[retPos++] = v;\r
-// Bytes.writeLE(ret, retPos, v);\r
-// retPos += 4;\r
- }\r
- } else if(table instanceof long[]) {\r
- long[] t = (long[])table;\r
- long[] ret = (long[])_ret;\r
- for(int i=getTableBase();i<getTableBase() + getHeader().getSize();i++) {\r
- long v = t[i];\r
- ret[retPos++] = v;\r
-// Bytes.writeLE8(ret, retPos, v);\r
-// retPos += 8;\r
- }\r
- }\r
- getHeader().setOffset(off-1);\r
- getHeader().setCapacity(getHeader().getSize());\r
- return retPos;\r
- }\r
- \r
- public <T> int storeBytes(byte[] _ret, int off, int retPos) {\r
- \r
- //int off = retPos;\r
- \r
- if(table instanceof byte[]) {\r
- System.arraycopy(table, getTableBase(), _ret, retPos, getHeader().getSize());\r
- retPos += getHeader().getSize();\r
- } else if(table instanceof int[]) {\r
- int[] t = (int[])table;\r
- for(int i=getTableBase();i<getTableBase() + getHeader().getSize();i++) {\r
- int v = t[i];\r
-// ret[retPos++] = v;\r
- Bytes.writeLE(_ret, retPos, v);\r
- retPos += 4;\r
- }\r
- } else if(table instanceof long[]) {\r
- long[] t = (long[])table;\r
- for(int i=getTableBase();i<getTableBase() + getHeader().getSize();i++) {\r
- long v = t[i];\r
- Bytes.writeLE8(_ret, retPos, v);\r
- retPos += 8;\r
- }\r
- }\r
- \r
- getHeader().setOffset(off-1);\r
- getHeader().setCapacity(getHeader().getSize());\r
- return retPos;\r
- \r
- }\r
- \r
- public abstract <Context> boolean foreach(int setIndex, Procedure procedure, final Context context, final ClusterSupport support, Modifier modifier) throws DatabaseException;\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.impl;
+
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.impl.ClusterI.Procedure;
+import org.simantics.db.service.Bytes;
+
+interface TableFactoryI<TableType> {
+ TableType newTable(int size);
+ boolean isEqual(TableType t1, int t1Start, int size, TableType t2, int t2Start);
+}
+
+class ByteFactory implements TableFactoryI<byte[]> {
+ @Override
+ public byte[] newTable(int size) {
+ return new byte[size];
+ }
+
+ @Override
+ public boolean isEqual(byte[] t1, int start, int size, byte[] t2, int start2) {
+ for (int i=0; i<size; ++i)
+ if (t1[start + i] != t2[start2 + i])
+ return false;
+ return true;
+ }
+}
+
+class IntFactory implements TableFactoryI<int[]> {
+ @Override
+ public int[] newTable(int size) {
+ return new int[size];
+ }
+
+ @Override
+ public boolean isEqual(int[] t1, int start, int size, int[] t2, int start2) {
+ for (int i=0; i<size; ++i)
+ if (t1[start + i] != t2[start2 + i])
+ return false;
+ return true;
+ }
+}
+
+class LongFactory implements TableFactoryI<long[]> {
+ @Override
+ public long[] newTable(int size) {
+ return new long[size];
+ }
+
+ @Override
+ public boolean isEqual(long[] t1, int start, int size, long[] t2, int start2) {
+ for (int i=0; i<size; ++i)
+ if (t1[start + i] != t2[start2 + i])
+ return false;
+ return true;
+ }
+}
+
+public abstract class Table<TableType> {
+ private static final int INITIAL_SIZE = 100; // Initial size of the table. Must be greater or equal than header_size;
+ private static final int INCREMENT_SIZE = 1000; // Minimum increment size of the table.
+ protected static final int ZERO_SHIFT = 1; // Indexes are guaranteed not to be zero.
+ final private TableHeader header;
+ final private TableFactoryI<TableType> factory;
+ final private TableSizeListener sizeListener;
+ public int offset; // Offset of table in containing array.
+ public TableType table;
+ protected Table(TableFactoryI<TableType> factory, TableSizeListener sizeListener, int[] header, int headerBase) {
+ this.factory = factory;
+ this.sizeListener = sizeListener;
+ this.header = new TableHeader(header, headerBase);
+ this.offset = -ZERO_SHIFT;
+ newTable(INITIAL_SIZE);
+ this.header.setSize(0);
+ this.header.setCount(0);
+ this.header.setOffset(offset);
+ }
+
+// final int size(Object bytes) {
+// if(bytes instanceof byte[]) return ((byte[])bytes).length;
+// if(bytes instanceof int[]) return ((int[])bytes).length;
+// if(bytes instanceof long[]) return ((long[])bytes).length;
+// return 0;
+// }
+
+ protected Table(TableFactoryI<TableType> factory, TableSizeListener sizeListener, int[] header, int headerBase, TableType bytes) {
+// System.out.println("Table size=" + size(bytes) + " header = " + Arrays.toString(Arrays.copyOfRange(header, headerBase, headerBase + 4)));
+ this.factory = factory;
+ this.sizeListener = sizeListener;
+ this.header = new TableHeader(header, headerBase);
+ offset = this.header.getOffset();
+ this.table = bytes;
+ }
+ /**
+ * Create and initialize this with a new table.
+ *
+ * @param capacity of the table. How many elements the table can hold without allocating new space.
+ * @param size of the table. How many elements have been used.
+ * @param count of how many segments has been have been allocated.
+ * @return old table.
+ */
+ final protected TableType createNewTable(int capacity, int size, int count) {
+ TableType t = table;
+ this.offset = -ZERO_SHIFT;
+ newTable(capacity);
+ sizeListener.resized();
+ header.setSize(size);
+ header.setCount(count);
+ header.setOffset(offset);
+ return t;
+ }
+ public final int getTableCapacity() {
+ return header.getCapacity();
+ }
+ public final int getTableSize() {
+ return header.getSize();
+ }
+ public final int getTableCount() {
+ return header.getCount();
+ }
+ protected int convertRealIndexToTableIndex(int realIndex) {
+ return realIndex - offset;
+ }
+ protected final int checkIndexAndGetRealIndex(int index, int size) {
+ if (index < ZERO_SHIFT)
+ throw new IllegalArgumentException("Underflow, index=" + index);
+ if ((size > 0 && index - ZERO_SHIFT + size > header.getSize()))
+ throw new IllegalArgumentException("Overflow, index=" + index + " size=" + size);
+ return index + offset;
+ }
+ protected final int checkIndexAndGetRealIndexEx(int index, int size) {
+ if (index < ZERO_SHIFT || size < 1)
+ throw new IllegalArgumentException("Underflow, index=" + index + " size=" + size);
+ if (index - ZERO_SHIFT + size < header.getSize())
+ return index + offset;
+ else if (index - ZERO_SHIFT + size == header.getSize())
+ return -1;
+ else
+ throw new IllegalArgumentException("Underflow, index=" + index + " size=" + size);
+ }
+ final protected void getCopy(int index, byte[] to, int start, int size) {
+ int realIndex = checkIndexAndGetRealIndex(index, size);
+ if (size < 0)
+ throw new IllegalArgumentException("Illgal table size " + size);
+ System.arraycopy(table, realIndex, to, start, size);
+ }
+ final protected void getCopy(int index, char[] to, int start, int size) {
+// int realIndex = checkIndexAndGetRealIndex(index, size);
+// if (size < 0)
+// throw new IllegalArgumentException("Illgal table size " + size);
+ byte[] bs = (byte[])table;
+ start += index+offset+1;
+ for(int i=0;i<size;i++) to[i] = (char)bs[start++];
+// System.arraycopy(table, realIndex, to, start, size);
+ }
+ final protected void setCopy(int index, int size, TableType from, int fromStartIndex) {
+// System.out.println("setCopy index=" + index + " size=" + size + "fromStartIndex=" + fromStartIndex + "from.length=" + ((byte[])from).length + "table.length=" + ((byte[])table).length);
+ int realIndex = checkIndexAndGetRealIndex(index, size);
+ System.arraycopy(from, fromStartIndex, table, realIndex, size);
+ }
+ final protected boolean isEqual(int index, TableType to, int toStartIndex, int toSize) {
+ int realIndex = checkIndexAndGetRealIndex(index, toSize);
+ return factory.isEqual(table, realIndex, toSize, to, toStartIndex);
+ }
+ /**
+ * @param size of the element (how many table slots is allocated).
+ * @return table index not the real index. To get real index use checkIndexAndGetRealIndex.
+ */
+ final protected int createNewElement(int size) {
+ if (size < 0)
+ throw new IllegalArgumentException("Illegal table size " + size);
+ if (0 == size)
+ return ZERO_SHIFT;
+ int oldSize = header.getSize();
+ int newSize = oldSize + size;
+ if (newSize > header.getCapacity())
+ realloc(newSize);
+ header.setSize(newSize);
+ header.setCount(header.getCount()+1);
+ return ZERO_SHIFT + oldSize;
+ }
+ final protected void deleteOldElement(int index, int size) {
+ checkIndexAndGetRealIndex(index, size);
+ header.setCount(header.getCount()-1);
+ }
+ final protected TableHeader getHeader() {
+ return header;
+ }
+ final protected int getTableBase() {
+ return offset + ZERO_SHIFT;
+ }
+ final protected TableType getTable() {
+ return table;
+ }
+ final protected int getExtra(int index) {
+ return header.getExtra(index);
+ }
+ final protected void setExtra(int index, int value) {
+ header.setExtra(index, value);
+ }
+ final private void realloc(int newSize) {
+ int realCapacity = newSize + Math.max(INCREMENT_SIZE, newSize/10);
+ TableType oldTable = table;
+ newTable(realCapacity);
+ sizeListener.resized();
+ int oldBase = getTableBase();
+ offset = -ZERO_SHIFT;
+ header.setOffset(offset);
+ int oldSize = header.getSize();
+ // If zero can cause ArrayIndexOutOfBoundsException because oldBase
+ // (index) can be out of bounds in this case and it is checked even
+ // if olsSize is zero (i.e. number of copied bytes is zero).
+ if (oldSize > 0) {
+ System.arraycopy(oldTable, oldBase, table, 0, oldSize);
+ }
+ }
+ final private void newTable(int capacity) {
+ table = factory.newTable(capacity);
+ header.setCapacity(capacity);
+ }
+
+ public <T> int store(T _ret, int retPos) {
+
+ int off = retPos;
+
+ if(table instanceof byte[]) {
+ System.arraycopy(table, getTableBase(), _ret, retPos, getHeader().getSize());
+ retPos += getHeader().getSize();
+ } else if(table instanceof int[]) {
+ int[] t = (int[])table;
+ int[] ret = (int[])_ret;
+ for(int i=getTableBase();i<getTableBase() + getHeader().getSize();i++) {
+ int v = t[i];
+ ret[retPos++] = v;
+// Bytes.writeLE(ret, retPos, v);
+// retPos += 4;
+ }
+ } else if(table instanceof long[]) {
+ long[] t = (long[])table;
+ long[] ret = (long[])_ret;
+ for(int i=getTableBase();i<getTableBase() + getHeader().getSize();i++) {
+ long v = t[i];
+ ret[retPos++] = v;
+// Bytes.writeLE8(ret, retPos, v);
+// retPos += 8;
+ }
+ }
+ getHeader().setOffset(off-1);
+ getHeader().setCapacity(getHeader().getSize());
+ return retPos;
+ }
+
+ public <T> int storeBytes(byte[] _ret, int off, int retPos) {
+
+ //int off = retPos;
+
+ if(table instanceof byte[]) {
+ System.arraycopy(table, getTableBase(), _ret, retPos, getHeader().getSize());
+ retPos += getHeader().getSize();
+ } else if(table instanceof int[]) {
+ int[] t = (int[])table;
+ for(int i=getTableBase();i<getTableBase() + getHeader().getSize();i++) {
+ int v = t[i];
+// ret[retPos++] = v;
+ Bytes.writeLE(_ret, retPos, v);
+ retPos += 4;
+ }
+ } else if(table instanceof long[]) {
+ long[] t = (long[])table;
+ for(int i=getTableBase();i<getTableBase() + getHeader().getSize();i++) {
+ long v = t[i];
+ Bytes.writeLE8(_ret, retPos, v);
+ retPos += 8;
+ }
+ }
+
+ getHeader().setOffset(off-1);
+ getHeader().setCapacity(getHeader().getSize());
+ return retPos;
+
+ }
+
+ public abstract <Context> boolean foreach(int setIndex, Procedure procedure, final Context context, final ClusterSupport support, Modifier modifier) throws DatabaseException;
+
+}