All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.persistit.util.Util Maven / Gradle / Ivy

There is a newer version: 3.3.0
Show newest version
/**
 * Copyright © 2005-2012 Akiban Technologies, Inc.  All rights reserved.
 * 
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * This program may also be available under different license terms.
 * For more information, see www.akiban.com or contact [email protected].
 * 
 * Contributors:
 * Akiban Technologies, Inc.
 */

package com.persistit.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Pattern;

import com.persistit.KeyState;
import com.persistit.Persistit;
import com.persistit.ValueState;
import com.persistit.exception.AppendableIOException;
import com.persistit.exception.PersistitInterruptedException;

/**
 * @author pbeaman
 */
public class Util {
    final static byte[] NULLS = new byte[1024];

    final static String SPACES = "                                                                    ";
    private final static String UTF8 = "UTF-8";
    public final static String NEW_LINE = System.getProperty("line.separator");
    private final static String REGEX_QUOTE = "^$*+?()[].";

    public final static long NS_PER_S = 1000000000L;
    public final static long MS_PER_S = 1000L;
    public final static long NS_PER_MS = 1000000L;

    public final static char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
            'E', 'F' };

    public static int getByte(final byte[] bytes, final int index) {
        return (bytes[index + 0] & 0xFF);
    }

    public static int getShort(final byte[] bytes, final int index) {
        if (Persistit.BIG_ENDIAN) {
            return (bytes[index + 1] & 0xFF) | (bytes[index + 0]) << 8;
        } else {
            return (bytes[index + 0] & 0xFF) | (bytes[index + 1]) << 8;
        }
    }

    public static int getChar(final byte[] bytes, final int index) {
        if (Persistit.BIG_ENDIAN) {
            return (bytes[index + 1] & 0xFF) | (bytes[index + 0] & 0xFF) << 8;
        } else {
            return (bytes[index + 0] & 0xFF) | (bytes[index + 1] & 0xFF) << 8;
        }
    }

    public static int getInt(final byte[] bytes, final int index) {
        if (Persistit.BIG_ENDIAN) {
            return (bytes[index + 3] & 0xFF) | (bytes[index + 2] & 0xFF) << 8 | (bytes[index + 1] & 0xFF) << 16
                    | (bytes[index + 0] & 0xFF) << 24;
        } else {
            return (bytes[index + 0] & 0xFF) | (bytes[index + 1] & 0xFF) << 8 | (bytes[index + 2] & 0xFF) << 16
                    | (bytes[index + 3] & 0xFF) << 24;
        }
    }

    public static long getLong(final byte[] bytes, final int index) {
        if (Persistit.BIG_ENDIAN) {
            return (bytes[index + 7] & 0xFF) | (long) (bytes[index + 6] & 0xFF) << 8
                    | (long) (bytes[index + 5] & 0xFF) << 16 | (long) (bytes[index + 4] & 0xFF) << 24
                    | (long) (bytes[index + 3] & 0xFF) << 32 | (long) (bytes[index + 2] & 0xFF) << 40
                    | (long) (bytes[index + 1] & 0xFF) << 48 | (long) (bytes[index + 0] & 0xFF) << 56;
        } else {
            return (bytes[index + 0] & 0xFF) | (long) (bytes[index + 1] & 0xFF) << 8
                    | (long) (bytes[index + 2] & 0xFF) << 16 | (long) (bytes[index + 3] & 0xFF) << 24
                    | (long) (bytes[index + 4] & 0xFF) << 32 | (long) (bytes[index + 5] & 0xFF) << 40
                    | (long) (bytes[index + 6] & 0xFF) << 48 | (long) (bytes[index + 7] & 0xFF) << 56;
        }
    }

    public static void putByte(final byte[] bytes, final int index, final int value) {
        bytes[index + 0] = (byte) (value);
    }

    public static void putShort(final byte[] bytes, final int index, final int value) {
        if (Persistit.BIG_ENDIAN) {
            bytes[index + 1] = (byte) (value);
            bytes[index + 0] = (byte) (value >>> 8);
        } else {
            bytes[index + 0] = (byte) (value);
            bytes[index + 1] = (byte) (value >>> 8);
        }
    }

    public static void putChar(final byte[] bytes, final int index, final int value) {
        if (Persistit.BIG_ENDIAN) {
            bytes[index + 1] = (byte) (value);
            bytes[index + 0] = (byte) (value >>> 8);
        } else {
            bytes[index + 0] = (byte) (value);
            bytes[index + 1] = (byte) (value >>> 8);
        }
    }

    public static void putInt(final byte[] bytes, final int index, final int value) {
        if (Persistit.BIG_ENDIAN) {
            bytes[index + 3] = (byte) (value);
            bytes[index + 2] = (byte) (value >>> 8);
            bytes[index + 1] = (byte) (value >>> 16);
            bytes[index + 0] = (byte) (value >>> 24);
        } else {
            bytes[index + 0] = (byte) (value);
            bytes[index + 1] = (byte) (value >>> 8);
            bytes[index + 2] = (byte) (value >>> 16);
            bytes[index + 3] = (byte) (value >>> 24);
        }
    }

    public static void putLong(final byte[] bytes, final int index, final long value) {
        if (Persistit.BIG_ENDIAN) {
            bytes[index + 7] = (byte) (value);
            bytes[index + 6] = (byte) (value >>> 8);
            bytes[index + 5] = (byte) (value >>> 16);
            bytes[index + 4] = (byte) (value >>> 24);
            bytes[index + 3] = (byte) (value >>> 32);
            bytes[index + 2] = (byte) (value >>> 40);
            bytes[index + 1] = (byte) (value >>> 48);
            bytes[index + 0] = (byte) (value >>> 56);
        } else {
            bytes[index + 0] = (byte) (value);
            bytes[index + 1] = (byte) (value >>> 8);
            bytes[index + 2] = (byte) (value >>> 16);
            bytes[index + 3] = (byte) (value >>> 24);
            bytes[index + 4] = (byte) (value >>> 32);
            bytes[index + 5] = (byte) (value >>> 40);
            bytes[index + 6] = (byte) (value >>> 48);
            bytes[index + 7] = (byte) (value >>> 56);
        }
    }

    public static int putBytes(final byte[] bytes, final int index, final byte[] value) {
        System.arraycopy(value, 0, bytes, index, value.length);
        return value.length;
    }

    public static boolean changeBytes(final byte[] bytes, final int index, final byte[] value) {
        final boolean same = equalsByteSubarray(bytes, index, value);
        if (same) {
            return false;
        } else {
            putBytes(bytes, index, value);
            return true;
        }
    }

    public static boolean changeByte(final byte[] bytes, final int index, final byte value) {
        if (getByte(bytes, index) == value) {
            return false;
        } else {
            putByte(bytes, index, value);
            return true;
        }
    }

    public static boolean changeChar(final byte[] bytes, final int index, final char value) {
        if (getChar(bytes, index) == value) {
            return false;
        } else {
            putChar(bytes, index, value);
            return true;
        }
    }

    public static boolean changeShort(final byte[] bytes, final int index, final short value) {
        if (getShort(bytes, index) == value) {
            return false;
        } else {
            putShort(bytes, index, value);
            return true;
        }
    }

    public static boolean changeInt(final byte[] bytes, final int index, final int value) {
        if (getInt(bytes, index) == value) {
            return false;
        } else {
            putInt(bytes, index, value);
            return true;
        }
    }

    public static boolean changeLong(final byte[] bytes, final int index, final long value) {
        if (getLong(bytes, index) == value) {
            return false;
        } else {
            putLong(bytes, index, value);
            return true;
        }
    }

    public static String format(final String s, final int width, final boolean right) {
        final int pad = width - s.length();
        if (pad < 0)
            return s.substring(0, width - 1) + "&";
        if (pad == 0)
            return s;
        if (right)
            return SPACES.substring(0, pad) + s;
        else
            return s + SPACES.substring(0, pad);
    }

    public static String format(final int i) {
        return format(i, 10);
    }

    public static String format(final long i) {
        return format(i, 22);
    }

    public static String format(final long i, final int width) {
        return format(Long.toString(i), width, true);
    }

    public static String abridge(final String s, final int maxLength) {
        if (s.length() > maxLength) {
            return s.substring(0, maxLength - 3) + "...";
        } else {
            return s;
        }
    }

    public static boolean equalsByteSubarray(final byte[] source, final int next, final byte[] target) {
        return equalsByteSubarray(source, next, target, 0, target.length);
    }

    public static boolean equalsByteSubarray(final byte[] source, final int soffset, final byte[] target,
            final int toffset, final int length) {
        for (int index = 0; index < length; index++) {
            if (source[soffset + index] != target[toffset + index])
                return false;
        }
        return true;
    }

    public static void fill(final StringBuilder sb, final long value, final int width) {
        fill(sb, Long.toString(value), width);
    }

    public static void fill(final StringBuilder sb, final String s, final int width) {
        for (int i = s.length(); i < width; i++)
            sb.append(' ');
        sb.append(s);
    }

    public static String dump(final KeyState ks) {
        final byte[] bytes = ks.getBytes();
        return dump(bytes, 0, bytes.length);
    }

    public static String dump(final ValueState vs) {
        final byte[] bytes = vs.getEncodedBytes();
        return dump(bytes, 0, bytes.length);
    }

    public static String dump(final byte[] b, final int offset, final int size) {
        final StringBuilder sb = new StringBuilder();
        final StringBuilder sb2 = new StringBuilder();
        for (int m = 0; m < size - offset; m += 16) {
            sb2.setLength(0);
            hex(sb, m, 4);
            sb.append(": ");
            for (int i = 0; i < 16; i++) {
                sb.append(" ");
                if (i % 8 == 0)
                    sb.append(" ");
                final int j = m + i;
                if (j < size - offset) {
                    hex(sb, b[j + offset], 2);
                    final char c = (char) (b[j + offset] & 0xFF);
                    if (c >= 32 && c < 127)
                        sb2.append(c);
                    else
                        sb2.append(".");
                } else
                    sb.append("  ");
            }
            sb.append("   ");
            sb.append(sb2.toString());
            sb.append(NEW_LINE);
        }
        return sb.toString();
    }

    public static String dump(final char[] c, final int offset, final int size) {
        final StringBuilder sb = new StringBuilder();
        final StringBuilder sb2 = new StringBuilder();
        for (int m = 0; m < size - offset; m += 8) {
            sb2.setLength(0);
            hex(sb, m, 4);
            sb.append(":");
            for (int i = 0; i < 8; i++) {
                sb.append("  ");
                if (i % 4 == 0)
                    sb.append(" ");
                final int j = m + i;
                if (j < size - offset) {
                    hex(sb, c[j + offset], 4);
                    if (c[j + offset] >= 32 && c[j] < 127)
                        sb2.append(c[j]);
                    else
                        sb2.append(".");
                } else
                    sb.append("    ");
            }
            sb.append("    ");
            sb.append(sb2.toString());
            sb.append(NEW_LINE);
        }
        return sb.toString();
    }

    public static String hexDump(final byte[] b) {
        return hexDump(b, 0, b.length);
    }

    public static String hexDump(final byte[] b, final int offset, final int length) {
        final StringBuilder sb = new StringBuilder();
        final StringBuilder sb2 = new StringBuilder();
        sb2.setLength(0);
        for (int i = offset; i < offset + length; i++) {
            sb.append(" ");
            hex(sb, b[i], 2);
            final char c = (char) (b[i] & 0xFF);
            if (c >= 32 && c < 127)
                sb2.append(c);
            else
                sb2.append(".");
        }
        sb.append(" / ");
        sb.append(sb2.toString());
        return sb.toString();
    }

    public static Appendable hex(final Appendable sb, final long value, final int length) {
        for (int i = length - 1; i >= 0; i--) {
            append(sb, HEX_DIGITS[(int) (value >> (i * 4)) & 0xF]);
        }
        return sb;
    }

    public static byte[] stringToBytes(final String s) {
        if (s == null)
            return new byte[0];
        try {
            return s.getBytes(UTF8);
        } catch (final UnsupportedEncodingException e) {
            return s.getBytes();
        }
    }

    public static boolean isValidName(final String s) {
        if (s == null || s.length() == 0)
            return false;
        if (!Character.isJavaIdentifierStart(s.charAt(0)))
            return false;
        for (int i = 1; i < s.length(); i++) {
            if (!Character.isJavaIdentifierPart(s.charAt(i)))
                return false;
        }
        return true;
    }

    public static String bytesToHex(final byte[] bytes) {
        final StringBuilder sb = new StringBuilder();
        bytesToHex(sb, bytes, 0, bytes.length);
        return sb.toString();
    }

    public static void bytesToHex(final Appendable sb, final byte[] bytes, final int offset, int length) {
        length += offset;
        for (int i = offset; i < length; i++) {
            append(sb, HEX_DIGITS[(bytes[i] >>> 4) & 0x0F]);
            append(sb, HEX_DIGITS[(bytes[i] >>> 0) & 0x0F]);
        }
    }

    public static byte[] hexToBytes(final String hex) {
        int count = 0;
        for (int i = 0; i < hex.length(); i++) {
            final int c = hex.charAt(i);
            if (c == '/' || c == '}')
                break;
            if (c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F') {
                count++;
            } else if (c != ' ' && c != '\t' && c != '\r' && c != '\n') {
                throw new IllegalArgumentException();
            }
        }
        if ((count % 2) == 1)
            throw new IllegalArgumentException();
        final byte[] result = new byte[count / 2];
        int t = 0;
        count = 0;

        for (int i = 0; i < hex.length(); i++) {
            final int c = hex.charAt(i);

            if (c == '/' || c == '}')
                break;

            if (c >= '0' && c <= '9') {
                t = t * 16 + c - '0';
            } else if (c >= 'a' && c <= 'f') {
                t = t * 16 + c - 'a' + 10;
            } else if (c >= 'A' && c <= 'F') {
                t = t * 16 + c - 'A' + 10;
            } else
                continue;

            count++;
            if ((count % 2) == 0) {
                result[(count / 2) - 1] = (byte) t;
                t = 0;
            }
        }
        return result;
    }

    public static String replaceFileSuffix(final String name, final String suffix) {
        //
        // If suffix is a full path, return it.
        //
        if (suffix.indexOf('/') >= 0 || suffix.indexOf('\\') > 0)
            return suffix;
        //
        // Find final file separator
        //
        int p = name.lastIndexOf('/');
        p = Math.max(p, name.lastIndexOf('\\'));
        //
        // Just replace the extension - i.e., the part of the path name to the
        // right of the period.
        //
        if (suffix.startsWith(".")) {
            final int q = name.lastIndexOf('.');
            if (q > p)
                p = q - 1;
        }
        if (p > 0)
            return name.substring(0, p + 1) + suffix;
        else
            return name + suffix;
    }

    public static void clearBytes(final byte[] bytes, final int from, final int to) {
        for (int offset = from; offset < to; offset += NULLS.length) {
            int count = to - offset;
            if (count > NULLS.length)
                count = NULLS.length;
            System.arraycopy(NULLS, 0, bytes, offset, count);
        }
    }

    public static void appendQuotedString(final Appendable sb, final String s, final int start, final int length) {
        final int end = Math.min(start + length, s.length());
        for (int index = start; index < end; index++) {
            appendQuotedChar(sb, s.charAt(index));
        }
    }

    public static void append(final Appendable sb, final char c) {
        try {
            sb.append(c);
        } catch (final IOException e) {
            throw new AppendableIOException(e);
        }
    }

    public static void append(final Appendable sb, final CharSequence s) {
        try {
            sb.append(s);
        } catch (final IOException e) {
            throw new AppendableIOException(e);
        }
    }

    public static void appendQuotedChar(final Appendable sb, final int c) {
        int q = 0;
        if (c == '\b')
            q = 'b';
        else if (c == '\n')
            q = 'n';
        else if (c == '\r')
            q = 'r';
        else if (c == '\t')
            q = 't';
        else if (c == '\"' || c == '\\')
            q = c;
        if (q != 0) {
            append(sb, '\\');
            append(sb, (char) q);
        } else if (c >= 127 || c < 20) {
            append(sb, '\\');
            append(sb, 'u');
            Util.hex(sb, c, 4);
        } else
            append(sb, (char) c);
    }

    public static String date(final long t) {
        if (t == 0) {
            return "none";
        } else {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(t));
        }
    }

    public static void println(final String template, final Object... args) {
        System.out.println(String.format(template, args));
    }

    /**
     * Utility method to determine whether a subarray of bytes in a byte-array
     * source matches the byte-array in target.
     * 
     * @param source
     *            The source byte array
     * @param offset
     *            The offset of the sub-array within the source.
     * @param target
     *            The target byte array
     * @return true if the byte subarrays are equal
     */
    public static boolean bytesEqual(final byte[] source, final int offset, final byte[] target) {
        for (int index = 0; index < target.length; index++) {
            if (source[index + offset] != target[index]) {
                return false;
            }
        }
        return true;
    }

    public static void sleep(final long millis) throws PersistitInterruptedException {
        try {
            Thread.sleep(millis);
        } catch (final InterruptedException ie) {
            throw new PersistitInterruptedException(ie);
        }
    }

    public static void spinSleep() throws PersistitInterruptedException {
        sleep(1);
    }

    public static String toString(final Object object) {
        return object == null ? null : object.toString();
    }

    public static int rangeCheck(final int value, final int min, final int max) {
        if (value >= min && value <= max) {
            return value;
        }
        if (min == Integer.MIN_VALUE) {
            throw new IllegalArgumentException(String.format("Value must be less than or equals to %,d: %,d", max,
                    value));
        }
        if (max == Integer.MAX_VALUE) {
            throw new IllegalArgumentException(String.format("Value must be greater than or equal to %,d: %,d", min,
                    value));
        } else {
            throw new IllegalArgumentException(String.format("Value must be between %d and %d, inclusive: ", min, max,
                    value));
        }
    }

    public static long rangeCheck(final long value, final long min, final long max) {
        if (value >= min && value <= max) {
            return value;
        }
        if (min == Long.MIN_VALUE) {
            throw new IllegalArgumentException(String.format("Value must be less than or equals to %,d: %,d", max,
                    value));
        }
        if (max == Long.MAX_VALUE) {
            throw new IllegalArgumentException(String.format("Value must be greater than or equal to %,d: %,d", min,
                    value));
        } else {
            throw new IllegalArgumentException(String.format("Value must be between %d and %d, inclusive: ", min, max,
                    value));
        }
    }

    public static float rangeCheck(final float value, final float min, final float max) {
        if (value >= min && value <= max) {
            return value;
        }
        if (min == Float.MIN_VALUE) {
            throw new IllegalArgumentException(String.format("Value must be less than or equals to %,f: %,f", max,
                    value));
        }
        if (max == Float.MAX_VALUE) {
            throw new IllegalArgumentException(String.format("Value must be greater than or equal to %,f: %,f", min,
                    value));
        } else {
            throw new IllegalArgumentException(String.format("Value must be between %f and %f, inclusive: ", min, max,
                    value));
        }
    }

    public static Pattern pattern(final String s, final boolean caseInsensitive) {
        final StringBuilder sb = new StringBuilder();
        if (s == null) {
            sb.append(".*");
        } else {
            for (int index = 0; index < s.length(); index++) {
                final char c = s.charAt(index);
                if (c == '*') {
                    sb.append(".*");
                } else if (c == '?') {
                    sb.append(".");
                } else if (REGEX_QUOTE.indexOf(c) != -1) {
                    sb.append('\\');
                    sb.append(c);
                } else {
                    sb.append(c);
                }
            }
        }
        return Pattern.compile(sb.toString(), caseInsensitive ? Pattern.CASE_INSENSITIVE : 0);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy