Util: Add sort methods that catch IAE

This commit is contained in:
zzz
2018-02-12 18:49:01 +00:00
parent 1826fcee0c
commit 6193e487c8
4 changed files with 61 additions and 12 deletions

View File

@ -1490,11 +1490,8 @@ public class I2PSnarkServlet extends BasicServlet {
Sorters.setPattern(Translate.getLanguage(_manager.util().getContext()));
else
Sorters.setPattern(null);
try {
Collections.sort(rv, Sorters.getComparator(sort, this));
} catch (IllegalArgumentException iae) {
// Java 7 TimSort - may be unstable
}
DataHelper.sort(rv, Sorters.getComparator(sort, this));
}
return rv;
}

View File

@ -34,6 +34,8 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.i2p.data.DataHelper;
/**
* Folder object manages a array Object[] to support
* paging and sorting.
@ -160,7 +162,7 @@ public class Folder<O extends Object> {
public synchronized void sort()
{
if (currentSorter != null && elements != null && elements.length > 1)
Arrays.sort( elements, currentSorter );
DataHelper.sort(elements, currentSorter);
}
/**

View File

@ -29,9 +29,12 @@ import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
@ -1997,4 +2000,54 @@ public class DataHelper {
cache.release(ba);
}
}
/**
* Same as Collections.sort(), but guaranteed not to throw an IllegalArgumentException if the
* sort is unstable. As of Java 7, TimSort will throw an IAE if the underlying sort order
* changes during the sort.
*
* This catches the IAE, retries once, and then returns.
* If an IAE is thrown twice, this method will return, with the list possibly unsorted.
*
* @param list the list to be sorted.
* @param c the comparator to determine the order of the list. A null value indicates that the elements' natural ordering should be used.
* @since 0.9.34
*/
public static <T> void sort(List<T> list, Comparator<? super T> c) {
try {
Collections.sort(list, c);
} catch (IllegalArgumentException iae1) {
try {
Thread.sleep(5);
} catch (InterruptedException ie) {}
try {
Collections.sort(list, c);
} catch (IllegalArgumentException iae2) {}
}
}
/**
* Same as Arrays.sort(), but guaranteed not to throw an IllegalArgumentException if the
* sort is unstable. As of Java 7, TimSort will throw an IAE if the underlying sort order
* changes during the sort.
*
* This catches the IAE, retries once, and then returns.
* If an IAE is thrown twice, this method will return, with the array possibly unsorted.
*
* @param a the array to be sorted.
* @param c the comparator to determine the order of the array. A null value indicates that the elements' natural ordering should be used.
* @since 0.9.34
*/
public static <T> void sort(T[] a, Comparator<? super T> c) {
try {
Arrays.sort(a, c);
} catch (IllegalArgumentException iae1) {
try {
Thread.sleep(5);
} catch (InterruptedException ie) {}
try {
Arrays.sort(a, c);
} catch (IllegalArgumentException iae2) {}
}
}
}

View File

@ -8,6 +8,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.data.i2np.I2NPMessage;
import net.i2p.data.router.RouterInfo;
@ -382,12 +383,8 @@ class BuildExecutor implements Runnable {
// to the front of the line sometimes, to prevent being "locked up"
// for several minutes.
boolean preferEmpty = _context.random().nextInt(4) != 0;
try {
Collections.sort(wanted, new TunnelPoolComparator(preferEmpty));
} catch (IllegalArgumentException iae) {
// Java 7 TimSort - see info in TunnelPoolComparator
continue;
}
DataHelper.sort(wanted, new TunnelPoolComparator(preferEmpty));
}
// force the loops to be short, since 3 consecutive tunnel build requests can take