Ratchet: Change SparseArray from int to char to reduce space

This commit is contained in:
zzz
2020-09-02 13:48:30 +00:00
parent 273902f616
commit c745cc8aa1
6 changed files with 60 additions and 25 deletions

View File

@ -1,3 +1,11 @@
2020-09-02 zzz
* Installer: New Ed25519 destinations for postman's servers
* Router:
- Prep for router encryption types (Proposal 156 WIP)
- Randomize SSU intro key
- Reduce next key threshold for ratchet
- Change ratchet SparseArray from int to char to reduce space
2020-08-29 zzz
* i2ptunnel: Prevent creating bad alt destination when
tunnel is running

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */
public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 1;
public final static long BUILD = 2;
/** for example "-test" */
public final static String EXTRA = "";

View File

@ -24,8 +24,8 @@ class ArrayUtils {
private ArrayUtils() { /* cannot be instantiated */ }
public static int[] newUnpaddedIntArray(int minLen) {
return new int[minLen];
public static char[] newUnpaddedCharArray(int minLen) {
return new char[minLen];
}
public static Object[] newUnpaddedObjectArray(int minLen) {

View File

@ -19,13 +19,13 @@ package net.i2p.router.crypto.ratchet;
class ContainerHelpers {
// This is Arrays.binarySearch(), but doesn't do any argument validation.
static int binarySearch(int[] array, int size, int value) {
static int binarySearch(char[] array, int size, char value) {
int lo = 0;
int hi = size - 1;
while (lo <= hi) {
final int mid = (lo + hi) >>> 1;
final int midVal = array[mid];
final char midVal = array[mid];
if (midVal < value) {
lo = mid + 1;

View File

@ -51,13 +51,13 @@ final class GrowingArrayUtils {
}
/**
* Primitive int version of {@link #append(Object[], int, Object)}.
* Primitive char version of {@link #append(Object[], int, Object)}.
*/
public static int[] append(int[] array, int currentSize, int element) {
public static char[] append(char[] array, int currentSize, char element) {
assert currentSize <= array.length;
if (currentSize + 1 > array.length) {
int[] newArray = ArrayUtils.newUnpaddedIntArray(growSize(currentSize));
char[] newArray = ArrayUtils.newUnpaddedCharArray(growSize(currentSize));
System.arraycopy(array, 0, newArray, 0, currentSize);
array = newArray;
}
@ -95,9 +95,9 @@ final class GrowingArrayUtils {
}
/**
* Primitive int version of {@link #insert(Object[], int, int, Object)}.
* Primitive char version of {@link #insert(Object[], int, int, Object)}.
*/
public static int[] insert(int[] array, int currentSize, int index, int element) {
public static char[] insert(char[] array, int currentSize, int index, char element) {
assert currentSize <= array.length;
if (currentSize + 1 <= array.length) {
@ -106,7 +106,7 @@ final class GrowingArrayUtils {
return array;
}
int[] newArray = ArrayUtils.newUnpaddedIntArray(growSize(currentSize));
char[] newArray = ArrayUtils.newUnpaddedCharArray(growSize(currentSize));
System.arraycopy(array, 0, newArray, 0, index);
newArray[index] = element;
System.arraycopy(array, index, newArray, index + 1, array.length - index);

View File

@ -45,14 +45,17 @@ package net.i2p.router.crypto.ratchet;
* <code>keyAt(int)</code> with ascending values of the index returns the
* keys in ascending order. In the case of <code>valueAt(int)</code>, the
* values corresponding to the keys are returned in ascending order.
*
* I2P - as of 0.9.48, changed to use chars for the index, max value 65535
*
*/
class SparseArray<E> implements Cloneable {
private static final int[] EMPTY_INTS = new int[0];
private static final char[] EMPTY_CHARS = new char[0];
private static final Object[] EMPTY_OBJECTS = new Object[0];
private static final Object DELETED = new Object();
private boolean mGarbage = false;
private int[] mKeys;
private char[] mKeys;
private Object[] mValues;
private int mSize;
@ -72,11 +75,11 @@ class SparseArray<E> implements Cloneable {
*/
public SparseArray(int initialCapacity) {
if (initialCapacity == 0) {
mKeys = EMPTY_INTS;
mKeys = EMPTY_CHARS;
mValues = EMPTY_OBJECTS;
} else {
mValues = ArrayUtils.newUnpaddedObjectArray(initialCapacity);
mKeys = new int[mValues.length];
mKeys = new char[mValues.length];
}
mSize = 0;
}
@ -106,10 +109,14 @@ class SparseArray<E> implements Cloneable {
/**
* Gets the Object mapped from the specified key, or the specified Object
* if no such mapping has been made.
*
* @param key 0 MIN, 65535 MAX
*/
@SuppressWarnings("unchecked")
public E get(int key, E valueIfKeyNotFound) {
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
if (key < 0 || key > 65535)
return valueIfKeyNotFound;
int i = ContainerHelpers.binarySearch(mKeys, mSize, (char) key);
if (i < 0 || mValues[i] == DELETED) {
return valueIfKeyNotFound;
@ -120,9 +127,13 @@ class SparseArray<E> implements Cloneable {
/**
* Removes the mapping from the specified key, if there was any.
*
* @param key 0 MIN, 65535 MAX
*/
public void delete(int key) {
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
if (key < 0 || key > 65535)
return;
int i = ContainerHelpers.binarySearch(mKeys, mSize, (char) key);
if (i >= 0) {
if (mValues[i] != DELETED) {
@ -134,10 +145,14 @@ class SparseArray<E> implements Cloneable {
/**
* Removes the mapping from the specified key, if there was any, returning the old value.
*
* @param key 0 MIN, 65535 MAX
*/
@SuppressWarnings("unchecked")
public E removeReturnOld(int key) {
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
if (key < 0 || key > 65535)
return null;
int i = ContainerHelpers.binarySearch(mKeys, mSize, (char) key);
if (i >= 0) {
if (mValues[i] != DELETED) {
@ -197,7 +212,7 @@ class SparseArray<E> implements Cloneable {
int n = mSize;
int o = 0;
int[] keys = mKeys;
char[] keys = mKeys;
Object[] values = mValues;
for (int i = 0; i < n; i++) {
@ -224,9 +239,13 @@ class SparseArray<E> implements Cloneable {
* Adds a mapping from the specified key to the specified value,
* replacing the previous mapping from the specified key if there
* was one.
*
* @param key 0 MIN, 65535 MAX
*/
public void put(int key, E value) {
int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
if (key < 0 || key > 65535)
throw new IllegalArgumentException();
int i = ContainerHelpers.binarySearch(mKeys, mSize, (char) key);
if (i >= 0) {
mValues[i] = value;
@ -234,7 +253,7 @@ class SparseArray<E> implements Cloneable {
i = ~i;
if (i < mSize && mValues[i] == DELETED) {
mKeys[i] = key;
mKeys[i] = (char) key;
mValues[i] = value;
return;
}
@ -243,10 +262,10 @@ class SparseArray<E> implements Cloneable {
gc();
// Search again because indices may have changed.
i = ~ContainerHelpers.binarySearch(mKeys, mSize, key);
i = ~ContainerHelpers.binarySearch(mKeys, mSize, (char) key);
}
mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, key);
mKeys = GrowingArrayUtils.insert(mKeys, mSize, i, (char) key);
mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);
mSize++;
}
@ -346,13 +365,17 @@ class SparseArray<E> implements Cloneable {
* Returns the index for which {@link #keyAt} would return the
* specified key, or a negative number if the specified
* key is not mapped.
*
* @param key 0 MIN, 65535 MAX
*/
public int indexOfKey(int key) {
if (key < 0 || key > 65535)
return -1;
if (mGarbage) {
gc();
}
return ContainerHelpers.binarySearch(mKeys, mSize, key);
return ContainerHelpers.binarySearch(mKeys, mSize, (char) key);
}
/**
@ -425,8 +448,12 @@ class SparseArray<E> implements Cloneable {
/**
* Puts a key/value pair into the array, optimizing for the case where
* the key is greater than all existing keys in the array.
*
* @param key 0 MIN, 65535 MAX
*/
public void append(int key, E value) {
if (key < 0 || key > 65535)
throw new IllegalArgumentException();
if (mSize != 0 && key <= mKeys[mSize - 1]) {
put(key, value);
return;
@ -436,7 +463,7 @@ class SparseArray<E> implements Cloneable {
gc();
}
mKeys = GrowingArrayUtils.append(mKeys, mSize, key);
mKeys = GrowingArrayUtils.append(mKeys, mSize, (char) key);
mValues = GrowingArrayUtils.append(mValues, mSize, value);
mSize++;
}