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 2020-08-29 zzz
* i2ptunnel: Prevent creating bad alt destination when * i2ptunnel: Prevent creating bad alt destination when
tunnel is running tunnel is running

View File

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

View File

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

View File

@ -19,13 +19,13 @@ package net.i2p.router.crypto.ratchet;
class ContainerHelpers { class ContainerHelpers {
// This is Arrays.binarySearch(), but doesn't do any argument validation. // 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 lo = 0;
int hi = size - 1; int hi = size - 1;
while (lo <= hi) { while (lo <= hi) {
final int mid = (lo + hi) >>> 1; final int mid = (lo + hi) >>> 1;
final int midVal = array[mid]; final char midVal = array[mid];
if (midVal < value) { if (midVal < value) {
lo = mid + 1; 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; assert currentSize <= array.length;
if (currentSize + 1 > 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); System.arraycopy(array, 0, newArray, 0, currentSize);
array = newArray; 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; assert currentSize <= array.length;
if (currentSize + 1 <= array.length) { if (currentSize + 1 <= array.length) {
@ -106,7 +106,7 @@ final class GrowingArrayUtils {
return array; return array;
} }
int[] newArray = ArrayUtils.newUnpaddedIntArray(growSize(currentSize)); char[] newArray = ArrayUtils.newUnpaddedCharArray(growSize(currentSize));
System.arraycopy(array, 0, newArray, 0, index); System.arraycopy(array, 0, newArray, 0, index);
newArray[index] = element; newArray[index] = element;
System.arraycopy(array, index, newArray, index + 1, array.length - index); 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 * <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 * keys in ascending order. In the case of <code>valueAt(int)</code>, the
* values corresponding to the keys are returned in ascending order. * 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 { 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[] EMPTY_OBJECTS = new Object[0];
private static final Object DELETED = new Object(); private static final Object DELETED = new Object();
private boolean mGarbage = false; private boolean mGarbage = false;
private int[] mKeys; private char[] mKeys;
private Object[] mValues; private Object[] mValues;
private int mSize; private int mSize;
@ -72,11 +75,11 @@ class SparseArray<E> implements Cloneable {
*/ */
public SparseArray(int initialCapacity) { public SparseArray(int initialCapacity) {
if (initialCapacity == 0) { if (initialCapacity == 0) {
mKeys = EMPTY_INTS; mKeys = EMPTY_CHARS;
mValues = EMPTY_OBJECTS; mValues = EMPTY_OBJECTS;
} else { } else {
mValues = ArrayUtils.newUnpaddedObjectArray(initialCapacity); mValues = ArrayUtils.newUnpaddedObjectArray(initialCapacity);
mKeys = new int[mValues.length]; mKeys = new char[mValues.length];
} }
mSize = 0; mSize = 0;
} }
@ -106,10 +109,14 @@ class SparseArray<E> implements Cloneable {
/** /**
* Gets the Object mapped from the specified key, or the specified Object * Gets the Object mapped from the specified key, or the specified Object
* if no such mapping has been made. * if no such mapping has been made.
*
* @param key 0 MIN, 65535 MAX
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public E get(int key, E valueIfKeyNotFound) { 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) { if (i < 0 || mValues[i] == DELETED) {
return valueIfKeyNotFound; return valueIfKeyNotFound;
@ -120,9 +127,13 @@ class SparseArray<E> implements Cloneable {
/** /**
* Removes the mapping from the specified key, if there was any. * Removes the mapping from the specified key, if there was any.
*
* @param key 0 MIN, 65535 MAX
*/ */
public void delete(int key) { 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 (i >= 0) {
if (mValues[i] != DELETED) { 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. * Removes the mapping from the specified key, if there was any, returning the old value.
*
* @param key 0 MIN, 65535 MAX
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public E removeReturnOld(int key) { 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 (i >= 0) {
if (mValues[i] != DELETED) { if (mValues[i] != DELETED) {
@ -197,7 +212,7 @@ class SparseArray<E> implements Cloneable {
int n = mSize; int n = mSize;
int o = 0; int o = 0;
int[] keys = mKeys; char[] keys = mKeys;
Object[] values = mValues; Object[] values = mValues;
for (int i = 0; i < n; i++) { 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, * Adds a mapping from the specified key to the specified value,
* replacing the previous mapping from the specified key if there * replacing the previous mapping from the specified key if there
* was one. * was one.
*
* @param key 0 MIN, 65535 MAX
*/ */
public void put(int key, E value) { 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) { if (i >= 0) {
mValues[i] = value; mValues[i] = value;
@ -234,7 +253,7 @@ class SparseArray<E> implements Cloneable {
i = ~i; i = ~i;
if (i < mSize && mValues[i] == DELETED) { if (i < mSize && mValues[i] == DELETED) {
mKeys[i] = key; mKeys[i] = (char) key;
mValues[i] = value; mValues[i] = value;
return; return;
} }
@ -243,10 +262,10 @@ class SparseArray<E> implements Cloneable {
gc(); gc();
// Search again because indices may have changed. // 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); mValues = GrowingArrayUtils.insert(mValues, mSize, i, value);
mSize++; mSize++;
} }
@ -346,13 +365,17 @@ class SparseArray<E> implements Cloneable {
* Returns the index for which {@link #keyAt} would return the * Returns the index for which {@link #keyAt} would return the
* specified key, or a negative number if the specified * specified key, or a negative number if the specified
* key is not mapped. * key is not mapped.
*
* @param key 0 MIN, 65535 MAX
*/ */
public int indexOfKey(int key) { public int indexOfKey(int key) {
if (key < 0 || key > 65535)
return -1;
if (mGarbage) { if (mGarbage) {
gc(); 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 * Puts a key/value pair into the array, optimizing for the case where
* the key is greater than all existing keys in the array. * the key is greater than all existing keys in the array.
*
* @param key 0 MIN, 65535 MAX
*/ */
public void append(int key, E value) { public void append(int key, E value) {
if (key < 0 || key > 65535)
throw new IllegalArgumentException();
if (mSize != 0 && key <= mKeys[mSize - 1]) { if (mSize != 0 && key <= mKeys[mSize - 1]) {
put(key, value); put(key, value);
return; return;
@ -436,7 +463,7 @@ class SparseArray<E> implements Cloneable {
gc(); gc();
} }
mKeys = GrowingArrayUtils.append(mKeys, mSize, key); mKeys = GrowingArrayUtils.append(mKeys, mSize, (char) key);
mValues = GrowingArrayUtils.append(mValues, mSize, value); mValues = GrowingArrayUtils.append(mValues, mSize, value);
mSize++; mSize++;
} }