X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.db.procore%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fprocore%2Fcluster%2FValueTableSmall.java;fp=bundles%2Forg.simantics.db.procore%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fprocore%2Fcluster%2FValueTableSmall.java;h=59eca5c8c97fb42a47b7ee02ec1152f685783f0b;hp=0000000000000000000000000000000000000000;hb=969bd23cab98a79ca9101af33334000879fb60c5;hpb=866dba5cd5a3929bbeae85991796acb212338a08 diff --git a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ValueTableSmall.java b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ValueTableSmall.java new file mode 100644 index 000000000..59eca5c8c --- /dev/null +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ValueTableSmall.java @@ -0,0 +1,170 @@ +/******************************************************************************* + * 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 java.util.Arrays; +import java.util.Map; +import java.util.TreeMap; + +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ValidationException; +import org.simantics.db.impl.ClusterI.ObjectProcedure; +import org.simantics.db.impl.ClusterI.Procedure; +import org.simantics.db.impl.ClusterSupport; +import org.simantics.db.impl.Modifier; +import org.simantics.db.impl.Table; +import org.simantics.db.impl.TableFactory; +import org.simantics.db.impl.TableSizeListener; + +public final class ValueTableSmall extends Table { + private static final boolean DEBUG = ClusterImpl.DEBUG; + public ValueTableSmall(TableSizeListener sizeListener, int[] header, int headerBase) { + super(TableFactory.getByteFactory(), sizeListener, header, headerBase); + } + public ValueTableSmall(TableSizeListener sizeListener, int[] header, int headerBase, byte[] bytes) { + super(TableFactory.getByteFactory(), sizeListener, header, headerBase, bytes); + } + private static final class IndexAndSize { + int index; // Real index (zero based) to start of value data. + short size; // Size of value data. + } + private IndexAndSize checkIndexAndGetRealIndex(int index) { + if (index < ZERO_SHIFT) // Index starts with ZERO_SHIFT. + throw new IllegalArgumentException("Underflow, index=" + index); + int tableSize = getTableSize(); + if (index >= tableSize) // Element size is at least two (one byte length and one byte data). + throw new IllegalArgumentException("Overflow, index=" + index); + int i = index + offset; + byte[] table = getTable(); + IndexAndSize is = new IndexAndSize(); + is.size = table[i++]; + if (is.size == 0) + throw new IllegalArgumentException("Removed, index=" + index); + if (is.size < 0) // two byte size + is.size = (short)(((is.size & 0x7F) << 8) | (table[i++] & 0xFF)); + is.index = i; + if (is.index + is.size > tableSize) // Element size too big. + throw new IllegalArgumentException("Illegal size, index=" + is.index + " size=" + is.size); + return is; + } + public byte[] getValue(int valueIndex) { + IndexAndSize is = checkIndexAndGetRealIndex(valueIndex); + byte[] value = new byte[is.size]; + System.arraycopy(table, is.index, value, 0, is.size); + if (DEBUG) + System.out.println("ValueTableSmall.getValue " + valueIndex + " " + Arrays.toString(value)); + return value; + } + char[] getString(int valueIndex) { + IndexAndSize is = checkIndexAndGetRealIndex(valueIndex); + final int size = is.size-1; + char[] t = new char[size]; + int start = is.index; + for(int i=0; i (1<<15)-1) + throw new IllegalArgumentException("Illegal internal value size=" + vsize + "."); + int size = vsize; + if (vsize > 0x7F) + size += 2; + else + size += 1; + int valueIndex = createNewElement(size); + int i = checkIndexAndGetRealIndex(valueIndex, 1); + if (vsize > 0x7F) { + table[i++] = (byte)((vsize >>> 8) | 1<<7); // msb + table[i++] = (byte)(vsize & 0xFF); // lsb + } else + table[i++] = (byte)vsize; + System.arraycopy(value, voffset, table, i, vsize); + return valueIndex; + } + void removeValue(int valueIndex) { + IndexAndSize is = checkIndexAndGetRealIndex(valueIndex); + int length = is.size; + int index = is.index; + if (is.size > 0x7F) { + length += 2; + index -= 2; + table[index+1] = 0; + } else { + length += 1; + index -= 1; + } + table[index] = 0; + deleteOldElement(valueIndex, length); + } +// boolean isEqual(int valueIndex, byte[] value, int voffset, int vsize) { +// return isEqual(valueIndex, value, 0, value.length); +// } + private TreeMap valueMap = + new TreeMap(); + + private int VALUE_SIZE = 0; + private int VALUE_OFFSET = 0; + public void checkValueInit() + throws DatabaseException { + valueMap.clear(); + final int s = getTableSize(); + final int c = getTableCapacity(); + if (s < 0 || s > c) + throw new ValidationException("Illegal value table size=" + s + " cap=" + c); + VALUE_SIZE = s; + VALUE_OFFSET = getTableBase() - ValueTableSmall.ZERO_SHIFT; + } + public void checkValue(int capacity, int index) + throws DatabaseException { + if (0 == capacity && 0 == index) + return; + if (capacity < 1) + throw new ValidationException("Illegal resource value capacity=" + capacity); + if (index < 1) + throw new ValidationException("Illegal resource value index=" + index); + if (VALUE_SIZE < capacity + index + VALUE_OFFSET) + throw new ValidationException("Illegal resource value c=" + capacity + + " i=" + index + " ts=" + VALUE_SIZE + " off=" + VALUE_OFFSET); + // Duplicate index is allowed because new index is created only if new size is greater than old. + Integer valueCap = valueMap.get(index); + if (null == valueCap) + valueMap.put(index, capacity); + else if (capacity > valueCap) + valueMap.put(index, capacity); + else + valueMap.put(index, valueCap); + } + public void checkValueFini() + throws DatabaseException { + int last = 0; + for (Map.Entry e : valueMap.entrySet()) { + int i = e.getKey(); + int c = e.getValue(); + int cur = VALUE_OFFSET + i; + if (last > cur) + throw new ValidationException("Index error with resource value c=" + c + + " i=" + i + " ts=" + VALUE_SIZE + " off=" + VALUE_OFFSET); + last = cur + c; + } + } + @Override + public boolean foreach(int setIndex, Procedure procedure, Context context, ClusterSupport support, Modifier modifier) throws DatabaseException { + throw new UnsupportedOperationException(); + } + +}