@Override public int getMemory(Object obj) { VersionedValue v = (VersionedValue) obj; return valueType.getMemory(v.value) + 8; }
@Override public Object read(ByteBuffer buff) { Object[] array = new Object[arrayLength]; for (int i = 0; i < arrayLength; i++) { DataType t = elementTypes[i]; if (buff.get() == 1) { array[i] = t.read(buff); } } return array; }
@Override public void write(WriteBuffer buff, Object obj) { Object[] array = (Object[]) obj; for (int i = 0; i < arrayLength; i++) { DataType t = elementTypes[i]; Object o = array[i]; if (o == null) { buff.put((byte) 0); } else { buff.put((byte) 1); t.write(buff, o); } } }
/** * Compare two keys. * * @param a the first key * @param b the second key * @return -1 if the first key is smaller, 1 if bigger, 0 if equal */ int compare(Object a, Object b) { return keyType.compare(a, b); }
/** * Check whether the two values are equal. * * @param a the first value * @param b the second value * @return true if they are equal */ public boolean areValuesEqual(Object a, Object b) { if (a == b) { return true; } else if (a == null || b == null) { return false; } return valueType.compare(a, b) == 0; }
@Override public int getMemory(Object obj) { Object[] array = (Object[]) obj; int size = 0; for (int i = 0; i < arrayLength; i++) { DataType t = elementTypes[i]; Object o = array[i]; if (o != null) { size += t.getMemory(o); } } return size; }
@Override public void write(WriteBuffer buff, Object obj) { VersionedValue v = (VersionedValue) obj; buff.putVarLong(v.operationId); if (v.value == null) { buff.put((byte) 0); } else { buff.put((byte) 1); valueType.write(buff, v.value); } }
@Override public Object read(ByteBuffer buff) { long operationId = DataUtils.readVarLong(buff); Object value; if (buff.get() == 1) { value = valueType.read(buff); } else { value = null; } return new VersionedValue(operationId, value); }
@Override public int compare(Object aObj, Object bObj) { if (aObj == bObj) { return 0; } Object[] a = (Object[]) aObj; Object[] b = (Object[]) bObj; for (int i = 0; i < arrayLength; i++) { DataType t = elementTypes[i]; int comp = t.compare(a[i], b[i]); if (comp != 0) { return comp; } } return 0; }
@Override public int getMemory(Object obj) { DataType t = getType(obj); if (t == this) { return averageSize; } return t.getMemory(obj); }
@Override public void write(WriteBuffer buff, Object[] obj, int len, boolean key) { boolean fastPath = true; for (int i = 0; i < len; i++) { VersionedValue v = (VersionedValue) obj[i]; if (v.operationId != 0 || v.value == null) { fastPath = false; } } if (fastPath) { buff.put((byte) 0); for (int i = 0; i < len; i++) { VersionedValue v = (VersionedValue) obj[i]; valueType.write(buff, v.value); } } else { // slow path: // store op ids, and some entries may be null buff.put((byte) 1); for (int i = 0; i < len; i++) { write(buff, obj[i]); } } }
@Override public void read(ByteBuffer buff, Object[] obj, int len, boolean key) { if (buff.get() == 0) { // fast path (no op ids or null entries) for (int i = 0; i < len; i++) { obj[i] = new VersionedValue(0L, valueType.read(buff)); } } else { // slow path (some entries may be null) for (int i = 0; i < len; i++) { obj[i] = read(buff); } } }
@Override public int compare(Object aObj, Object bObj) { if (aObj == bObj) { return 0; } VersionedValue a = (VersionedValue) aObj; VersionedValue b = (VersionedValue) bObj; long comp = a.operationId - b.operationId; if (comp == 0) { return valueType.compare(a.value, b.value); } return Long.signum(comp); }
/** * Replace the value at an index in this page. * * @param index the index * @param value the new value * @return the old value */ public Object setValue(int index, Object value) { Object old = values[index]; // this is slightly slower: // values = Arrays.copyOf(values, values.length); values = values.clone(); DataType valueType = map.getValueType(); if(isPersistent()) { addMemory(valueType.getMemory(value) - valueType.getMemory(old)); } values[index] = value; return old; }
@Override public void write(WriteBuffer buff, Object obj) { DataType t = getType(obj); if (t != this) { t.write(buff, obj); return; } byte[] data = serialize(obj); // we say they are larger, because these objects // use quite a lot of disk space int size = data.length * 2; // adjust the average size // using an exponential moving average averageSize = (size + 15 * averageSize) / 16; buff.put((byte) TYPE_SERIALIZED_OBJECT).putVarInt(data.length) .put(data); }
@SuppressWarnings("unchecked") @Override public int compare(Object aObj, Object bObj) { if (aObj == bObj) { return 0; } DataType ta = getType(aObj); DataType tb = getType(bObj); if (ta != this || tb != this) { if (ta == tb) { return ta.compare(aObj, bObj); } return super.compare(aObj, bObj); } // TODO ensure comparable type (both may be comparable but not // with each other) if (aObj instanceof Comparable) { if (aObj.getClass().isAssignableFrom(bObj.getClass())) { return ((Comparable<Object>) aObj).compareTo(bObj); } } if (bObj instanceof Comparable) { if (bObj.getClass().isAssignableFrom(aObj.getClass())) { return -((Comparable<Object>) bObj).compareTo(aObj); } } byte[] a = serialize(aObj); byte[] b = serialize(bObj); return compareNotNull(a, b); }
/** * Replace the key at an index in this page. * * @param index the index * @param key the new key */ public void setKey(int index, Object key) { // this is slightly slower: // keys = Arrays.copyOf(keys, keys.length); keys = keys.clone(); if(isPersistent()) { Object old = keys[index]; DataType keyType = map.getKeyType(); int mem = keyType.getMemory(key); if (old != null) { mem -= keyType.getMemory(old); } addMemory(mem); } keys[index] = key; }
@Override public Object read(ByteBuffer buff) { Object[] array = new Object[arrayLength]; for (int i = 0; i < arrayLength; i++) { DataType t = elementTypes[i]; if (buff.get() == 1) { array[i] = t.read(buff); } } return array; }