Unverified 提交 9c734857 authored 作者: Noel Grandin's avatar Noel Grandin 提交者: GitHub

Merge pull request #667 from LingMan/mathutils

Updates to MathUtils
......@@ -338,8 +338,15 @@ public class SysProperties {
* The maximum number of objects in the cache.
* This value must be a power of 2.
*/
public static final int OBJECT_CACHE_SIZE =
MathUtils.nextPowerOf2(Utils.getProperty("h2.objectCacheSize", 1024));
public static final int OBJECT_CACHE_SIZE;
static {
try {
OBJECT_CACHE_SIZE = MathUtils.nextPowerOf2(
Utils.getProperty("h2.objectCacheSize", 1024));
} catch (IllegalArgumentException e) {
throw new IllegalStateException("Invalid h2.objectCacheSize", e);
}
}
/**
* System property <code>h2.oldStyleOuterJoin</code>
......
......@@ -21,7 +21,6 @@ import org.h2.table.Column;
import org.h2.table.IndexColumn;
import org.h2.table.Table;
import org.h2.table.TableFilter;
import org.h2.util.MathUtils;
import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils;
import org.h2.value.Value;
......@@ -348,7 +347,7 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
if (isMultiVersion) {
int v1 = rowData.getVersion();
int v2 = compare.getVersion();
return MathUtils.compareInt(v2, v1);
return Integer.compare(v2, v1);
}
return 0;
}
......
......@@ -10,7 +10,6 @@ import org.h2.engine.SysProperties;
import org.h2.message.DbException;
import org.h2.result.Row;
import org.h2.result.SearchRow;
import org.h2.util.MathUtils;
/**
* The cursor implementation for the multi-version index.
......@@ -143,7 +142,7 @@ public class MultiVersionCursor implements Cursor {
// version would be compared as well
long k1 = deltaRow.getKey();
long k2 = baseRow.getKey();
compare = MathUtils.compareLong(k1, k2);
compare = Long.compare(k1, k2);
}
if (compare == 0) {
if (isDeleted) {
......
......@@ -5,7 +5,6 @@
*/
package org.h2.server.web;
import org.h2.util.MathUtils;
import org.h2.util.StringUtils;
/**
......@@ -61,7 +60,7 @@ public class ConnectionInfo implements Comparable<ConnectionInfo> {
@Override
public int compareTo(ConnectionInfo o) {
return -MathUtils.compareInt(lastAccess, o.lastAccess);
return -Integer.compare(lastAccess, o.lastAccess);
}
}
......@@ -16,7 +16,6 @@ import java.util.StringTokenizer;
import org.h2.message.DbException;
import org.h2.store.fs.FileUtils;
import org.h2.util.IOUtils;
import org.h2.util.MathUtils;
import org.h2.util.New;
import org.h2.util.StringUtils;
import org.h2.util.Tool;
......@@ -46,9 +45,9 @@ public class ConvertTraceFile extends Tool {
if (other == this) {
return 0;
}
int c = MathUtils.compareLong(other.time, time);
int c = Long.compare(other.time, time);
if (c == 0) {
c = MathUtils.compareInt(other.executeCount, executeCount);
c = Integer.compare(other.executeCount, executeCount);
if (c == 0) {
c = sql.compareTo(other.sql);
}
......
......@@ -51,11 +51,17 @@ public class CacheLRU implements Cache {
this.writer = writer;
this.fifo = fifo;
this.setMaxMemory(maxMemoryKb);
long tmpLen = MathUtils.nextPowerOf2(maxMemory / 64);
try {
// Since setMaxMemory() ensures that maxMemory is >=0,
// we don't have to worry about an underflow.
long tmpLen = maxMemory / 64;
if (tmpLen > Integer.MAX_VALUE) {
throw new IllegalStateException("do not support this much cache memory: " + maxMemoryKb + "kb");
throw new IllegalArgumentException();
}
this.len = MathUtils.nextPowerOf2((int) tmpLen);
} catch (IllegalArgumentException e) {
throw new IllegalStateException("This much cache memory is not supported: " + maxMemoryKb + "kb", e);
}
this.len = (int) tmpLen;
this.mask = len - 1;
clear();
}
......
......@@ -77,7 +77,7 @@ public abstract class CacheObject implements Comparable<CacheObject> {
@Override
public int compareTo(CacheObject other) {
return MathUtils.compareInt(getPos(), other.getPos());
return Integer.compare(getPos(), other.getPos());
}
public boolean isStream() {
......
......@@ -204,7 +204,7 @@ public class MathUtils {
* @param s the message to print
* @param t the stack trace
*/
static void warn(String s, Throwable t) {
private static void warn(String s, Throwable t) {
// not a fatal problem, but maybe reduced security
System.out.println("Warning: " + s);
if (t != null) {
......@@ -213,33 +213,27 @@ public class MathUtils {
}
/**
* Get the value that is equal or higher than this value, and that is a
* Get the value that is equal to or higher than this value, and that is a
* power of two.
*
* @param x the original value
* @return the next power of two value
* @throws IllegalArgumentException if x < 0 or x > 0x40000000
*/
public static int nextPowerOf2(int x) {
long i = 1;
while (i < x && i < (Integer.MAX_VALUE / 2)) {
i += i;
}
return (int) i;
}
/**
* Get the value that is equal or higher than this value, and that is a
* power of two.
*
* @param x the original value
* @return the next power of two value
*/
public static long nextPowerOf2(long x) {
long i = 1;
while (i < x && i < (Long.MAX_VALUE / 2)) {
i += i;
}
return i;
public static int nextPowerOf2(int x) throws IllegalArgumentException {
if (x == 0) {
return 1;
} else if (x < 0 || x > 0x40000000 ) {
throw new IllegalArgumentException("Argument out of range"
+ " [0x0-0x40000000]. Argument was: " + x);
}
x--;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return ++x;
}
/**
......@@ -260,30 +254,6 @@ public class MathUtils {
}
}
/**
* Compare two values. Returns -1 if the first value is smaller, 1 if
* bigger, and 0 if equal.
*
* @param a the first value
* @param b the second value
* @return the result
*/
public static int compareInt(int a, int b) {
return a == b ? 0 : a < b ? -1 : 1;
}
/**
* Compare two values. Returns -1 if the first value is smaller, 1 if
* bigger, and 0 if equal.
*
* @param a the first value
* @param b the second value
* @return the result
*/
public static int compareLong(long a, long b) {
return a == b ? 0 : a < b ? -1 : 1;
}
/**
* Get a cryptographically secure pseudo random long value.
*
......
......@@ -10,7 +10,6 @@ import java.sql.SQLException;
import org.h2.api.ErrorCode;
import org.h2.message.DbException;
import org.h2.util.MathUtils;
/**
* Implementation of the BYTE data type.
......@@ -106,7 +105,7 @@ public class ValueByte extends Value {
@Override
protected int compareSecure(Value o, CompareMode mode) {
ValueByte v = (ValueByte) o;
return MathUtils.compareInt(value, v.value);
return Integer.compare(value, v.value);
}
@Override
......
......@@ -12,7 +12,6 @@ import java.sql.SQLException;
import org.h2.api.ErrorCode;
import org.h2.message.DbException;
import org.h2.util.DateTimeUtils;
import org.h2.util.MathUtils;
import org.h2.util.StringUtils;
/**
......@@ -121,7 +120,7 @@ public class ValueDate extends Value {
@Override
protected int compareSecure(Value o, CompareMode mode) {
return MathUtils.compareLong(dateValue, ((ValueDate) o).dateValue);
return Long.compare(dateValue, ((ValueDate) o).dateValue);
}
@Override
......
......@@ -8,7 +8,6 @@ package org.h2.value;
import java.util.Locale;
import org.h2.api.ErrorCode;
import org.h2.message.DbException;
import org.h2.util.MathUtils;
public class ValueEnum extends ValueEnumBase {
private static enum Validation {
......@@ -57,7 +56,7 @@ public class ValueEnum extends ValueEnumBase {
@Override
protected int compareSecure(final Value v, final CompareMode mode) {
return MathUtils.compareInt(getInt(), v.getInt());
return Integer.compare(getInt(), v.getInt());
}
/**
......
......@@ -7,7 +7,6 @@ package org.h2.value;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.h2.util.MathUtils;
/**
* Base implementation of the ENUM data type.
......@@ -35,7 +34,7 @@ public class ValueEnumBase extends Value {
@Override
protected int compareSecure(final Value v, final CompareMode mode) {
return MathUtils.compareInt(getInt(), v.getInt());
return Integer.compare(getInt(), v.getInt());
}
@Override
......
......@@ -10,7 +10,6 @@ import java.sql.SQLException;
import org.h2.api.ErrorCode;
import org.h2.message.DbException;
import org.h2.util.MathUtils;
/**
* Implementation of the INT data type.
......@@ -140,7 +139,7 @@ public class ValueInt extends Value {
@Override
protected int compareSecure(Value o, CompareMode mode) {
ValueInt v = (ValueInt) o;
return MathUtils.compareInt(value, v.value);
return Integer.compare(value, v.value);
}
@Override
......
......@@ -12,7 +12,6 @@ import java.sql.SQLException;
import org.h2.api.ErrorCode;
import org.h2.message.DbException;
import org.h2.util.MathUtils;
/**
* Implementation of the BIGINT data type.
......@@ -171,7 +170,7 @@ public class ValueLong extends Value {
@Override
protected int compareSecure(Value o, CompareMode mode) {
ValueLong v = (ValueLong) o;
return MathUtils.compareLong(value, v.value);
return Long.compare(value, v.value);
}
@Override
......
......@@ -10,7 +10,6 @@ import java.sql.SQLException;
import org.h2.api.ErrorCode;
import org.h2.message.DbException;
import org.h2.util.MathUtils;
/**
* Implementation of the SMALLINT data type.
......@@ -106,7 +105,7 @@ public class ValueShort extends Value {
@Override
protected int compareSecure(Value o, CompareMode mode) {
ValueShort v = (ValueShort) o;
return MathUtils.compareInt(value, v.value);
return Integer.compare(value, v.value);
}
@Override
......
......@@ -11,7 +11,6 @@ import java.sql.Time;
import org.h2.api.ErrorCode;
import org.h2.message.DbException;
import org.h2.util.DateTimeUtils;
import org.h2.util.MathUtils;
import org.h2.util.StringUtils;
/**
......@@ -129,7 +128,7 @@ public class ValueTime extends Value {
@Override
protected int compareSecure(Value o, CompareMode mode) {
return MathUtils.compareLong(nanos, ((ValueTime) o).nanos);
return Long.compare(nanos, ((ValueTime) o).nanos);
}
@Override
......
......@@ -16,7 +16,6 @@ import org.h2.api.ErrorCode;
import org.h2.engine.Mode;
import org.h2.message.DbException;
import org.h2.util.DateTimeUtils;
import org.h2.util.MathUtils;
/**
* Implementation of the TIMESTAMP data type.
......@@ -310,11 +309,11 @@ public class ValueTimestamp extends Value {
@Override
protected int compareSecure(Value o, CompareMode mode) {
ValueTimestamp t = (ValueTimestamp) o;
int c = MathUtils.compareLong(dateValue, t.dateValue);
int c = Long.compare(dateValue, t.dateValue);
if (c != 0) {
return c;
}
return MathUtils.compareLong(timeNanos, t.timeNanos);
return Long.compare(timeNanos, t.timeNanos);
}
@Override
......
......@@ -14,7 +14,6 @@ import org.h2.api.ErrorCode;
import org.h2.api.TimestampWithTimeZone;
import org.h2.message.DbException;
import org.h2.util.DateTimeUtils;
import org.h2.util.MathUtils;
import org.h2.util.StringUtils;
/**
......@@ -310,14 +309,14 @@ public class ValueTimestampTimeZone extends Value {
b -= t.timeZoneOffsetMins;
// compare date
int c = MathUtils.compareLong(a, b);
int c = Long.compare(a, b);
if (c != 0) {
return c;
}
// compare time
long na = timeNanos - (ma * 1000L * 1000L * 1000L * 60L);
long nb = t.timeNanos - (mb * 1000L * 1000L * 1000L * 60L);
return MathUtils.compareLong(na, nb);
return Long.compare(na, nb);
}
@Override
......
......@@ -159,7 +159,7 @@ public class ValueUuid extends Value {
}
ValueUuid v = (ValueUuid) o;
if (high == v.high) {
return MathUtils.compareLong(low, v.low);
return Long.compare(low, v.low);
}
return high > v.high ? 1 : -1;
}
......
......@@ -5,10 +5,7 @@
*/
package org.h2.test.unit;
import java.math.BigInteger;
import java.util.Random;
import org.h2.test.TestBase;
import org.h2.test.utils.AssertThrows;
import org.h2.util.MathUtils;
/**
......@@ -28,8 +25,7 @@ public class TestMathUtils extends TestBase {
@Override
public void test() {
testRandom();
testReverse();
testFactorial();
testNextPowerOf2Int();
}
private void testRandom() {
......@@ -53,78 +49,17 @@ public class TestMathUtils extends TestBase {
assertTrue(data.length > 10);
}
private void testReverse() {
assertEquals(Integer.reverse(0), Integer.reverse(0));
assertEquals(Integer.reverse(Integer.MAX_VALUE),
Integer.reverse(Integer.MAX_VALUE));
assertEquals(Integer.reverse(Integer.MIN_VALUE),
Integer.reverse(Integer.MIN_VALUE));
assertEquals(Long.reverse(0), Long.reverse(0L));
assertEquals(Long.reverse(Long.MAX_VALUE), Long.reverse(Long.MAX_VALUE));
assertEquals(Long.reverse(Long.MIN_VALUE), Long.reverse(Long.MIN_VALUE));
for (int i = Integer.MIN_VALUE; i < 0; i += 1019) {
int x = Integer.reverse(i);
assertEquals(Integer.reverse(i), x);
}
for (int i = 0; i > 0; i += 1019) {
int x = Integer.reverse(i);
assertEquals(Integer.reverse(i), x);
}
for (long i = Long.MIN_VALUE; i < 0; i += 1018764321251L) {
long x = Long.reverse(i);
assertEquals(Long.reverse(i), x);
}
for (long i = 0; i > 0; i += 1018764321251L) {
long x = Long.reverse(i);
assertEquals(Long.reverse(i), x);
}
Random random = new Random(10);
for (int i = 0; i < 1000000; i++) {
long x = random.nextLong();
long r = Long.reverse(x);
assertEquals(Long.reverse(x), r);
int y = random.nextInt();
int s = Integer.reverse(y);
assertEquals(Integer.reverse(y), s);
}
}
private void testNextPowerOf2Int() {
// the largest power of two that fits into an integer
final int LARGEST_POW2 = 0x40000000;
int[] testValues = { 0, 1, 2, 3, 4, 12, 17, 500, 1023,
LARGEST_POW2-500, LARGEST_POW2 };
int[] resultValues = { 1, 1, 2, 4, 4, 16, 32, 512, 1024,
LARGEST_POW2, LARGEST_POW2 };
private void testFactorial() {
new AssertThrows(IllegalArgumentException.class) { @Override
public void test() {
factorial(-1);
}};
assertEquals("1", factorial(0).toString());
assertEquals("1", factorial(1).toString());
assertEquals("2", factorial(2).toString());
assertEquals("6", factorial(3).toString());
assertEquals("3628800", factorial(10).toString());
assertEquals("2432902008176640000", factorial(20).toString());
}
/**
* Calculate the factorial (n!) of a number.
* This implementation uses a naive multiplication loop, and
* is very slow for large n.
* For n = 1000, it takes about 10 ms.
* For n = 8000, it takes about 800 ms.
*
* @param n the number
* @return the factorial of n
*/
public static BigInteger factorial(int n) {
if (n < 0) {
throw new IllegalArgumentException(n + "<0");
} else if (n < 2) {
return BigInteger.ONE;
}
BigInteger x = new BigInteger("" + n);
BigInteger result = x;
for (int i = n - 1; i >= 2; i--) {
x = x.subtract(BigInteger.ONE);
result = result.multiply(x);
for (int i = 0; i < testValues.length; i++) {
assertEquals(resultValues[i], MathUtils.nextPowerOf2(testValues[i]));
}
return result;
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论