org.apache.solr.util.hll.NumberUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of solr-core Show documentation
Show all versions of solr-core Show documentation
Apache Solr (module: core)
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.util.hll;
/** A collection of utilities to work with numbers. */
class NumberUtil {
// loge(2) (log-base e of 2)
public static final double LOGE_2 = 0.6931471805599453;
// ************************************************************************
/**
* Computes the log2
(log-base-two) of the specified value.
*
* @param value the double
for which the log2
is desired.
* @return the log2
of the specified value
*/
public static double log2(final double value) {
// REF: http://en.wikipedia.org/wiki/Logarithmic_scale (conversion of bases)
return Math.log(value) / LOGE_2;
}
// ========================================================================
// the hex characters
private static final char[] HEX = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
// ------------------------------------------------------------------------
/**
* Converts the specified array of byte
s into a string of hex characters (low
* byte
first).
*
* @param bytes the array of byte
s that are to be converted. This cannot be
* null
though it may be empty.
* @param offset the offset in bytes
at which the bytes will be taken. This cannot be
* negative and must be less than bytes.length - 1
.
* @param count the number of bytes to be retrieved from the specified array. This cannot be
* negative. If greater than bytes.length - offset
then that value is used.
* @return a string of at most count
characters that represents the specified byte
* array in hex. This will never be null
though it may be empty if bytes
*
is empty or count
is zero.
* @throws IllegalArgumentException if offset
is greater than or equal to
* bytes.length
.
* @see #fromHex(String, int, int)
*/
public static String toHex(final byte[] bytes, final int offset, final int count) {
if (offset >= bytes.length)
throw new IllegalArgumentException(
"Offset is greater than the length ("
+ offset
+ " >= "
+ bytes.length
+ ").") /*by contract*/;
final int byteCount = Math.min((bytes.length - offset), count);
final int upperBound = byteCount + offset;
final char[] chars = new char[byteCount * 2 /*two chars per byte*/];
int charIndex = 0;
for (int i = offset; i < upperBound; i++) {
final byte value = bytes[i];
chars[charIndex++] = HEX[(value >>> 4) & 0x0F];
chars[charIndex++] = HEX[value & 0x0F];
}
return new String(chars);
}
/**
* Converts the specified array of hex characters into an array of byte
s (low
* byte
first).
*
* @param string the string of hex characters to be converted into byte
s. This cannot
* be null
though it may be blank.
* @param offset the offset in the string at which the characters will be taken. This cannot be
* negative and must be less than string.length() - 1
.
* @param count the number of characters to be retrieved from the specified string. This cannot be
* negative and must be divisible by two (since there are two characters per byte
* ).
* @return the array of byte
s that were converted from the specified string (in the
* specified range). This will never be null
though it may be empty if
* string
is empty or count
is zero.
* @throws IllegalArgumentException if offset
is greater than or equal to
* string.length()
or if count
is not divisible by two.
* @see #toHex(byte[], int, int)
*/
public static byte[] fromHex(final String string, final int offset, final int count) {
if (offset >= string.length())
throw new IllegalArgumentException(
"Offset is greater than the length ("
+ offset
+ " >= "
+ string.length()
+ ").") /*by contract*/;
if ((count & 0x01) != 0)
throw new IllegalArgumentException(
"Count is not divisible by two (" + count + ").") /*by contract*/;
final int charCount = Math.min((string.length() - offset), count);
final int upperBound = offset + charCount;
final byte[] bytes = new byte[charCount >>> 1 /*aka /2*/];
int byteIndex = 0 /*beginning*/;
for (int i = offset; i < upperBound; i += 2) {
bytes[byteIndex++] =
(byte) (((digit(string.charAt(i)) << 4) | digit(string.charAt(i + 1))) & 0xFF);
}
return bytes;
}
// ------------------------------------------------------------------------
/**
* @param character a hex character to be converted to a byte
. This cannot be a
* character other than [a-fA-F0-9].
* @return the value of the specified character. This will be a value 0
through
* 15
.
* @throws IllegalArgumentException if the specified character is not in [a-fA-F0-9]
*/
private static final int digit(final char character) {
switch (character) {
case '0':
return 0;
case '1':
return 1;
case '2':
return 2;
case '3':
return 3;
case '4':
return 4;
case '5':
return 5;
case '6':
return 6;
case '7':
return 7;
case '8':
return 8;
case '9':
return 9;
case 'a':
case 'A':
return 10;
case 'b':
case 'B':
return 11;
case 'c':
case 'C':
return 12;
case 'd':
case 'D':
return 13;
case 'e':
case 'E':
return 14;
case 'f':
case 'F':
return 15;
default:
throw new IllegalArgumentException(
"Character is not in [a-fA-F0-9] ('" + character + "').");
}
}
}