/**
* Copyright The Apache Software Foundation
*
* 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 com.alibaba.wasp.util;
import com.alibaba.wasp.ReadModel;
import com.alibaba.wasp.conf.WaspConfiguration;
import org.apache.hadoop.conf.Configuration;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class Utils {
/**
* An 0-size byte array.
*/
public static final byte[] EMPTY_BYTES = {};
private static final HashMap<String, byte[]> RESOURCES = New.hashMap();
private Utils() {
// utility class
}
/**
* Create a new byte array and copy all the data. If the size of the byte
* array is zero, the same array is returned.
*
* @param b
* the byte array (may not be null)
* @return a new byte array
*/
public static byte[] cloneByteArray(byte[] b) {
if (b == null) {
return null;
}
int len = b.length;
if (len == 0) {
return EMPTY_BYTES;
}
byte[] copy = new byte[len];
System.arraycopy(b, 0, copy, 0, len);
return copy;
}
/**
* Get the system property. If the system property is not set, or if a
* security exception occurs, the default value is returned.
*
* @param key
* the key
* @param defaultValue
* the default value
* @return the value
*/
public static String getProperty(Configuration conf, String key,
String defaultValue) {
try {
return conf.get(key, defaultValue);
} catch (SecurityException se) {
return defaultValue;
}
}
/**
* Get the system property. If the system property is not set, or if a
* security exception occurs, the default value is returned.
*
* @param key
* the key
* @param defaultValue
* the default value
* @return the value
*/
public static int getProperty(Configuration conf, String key, int defaultValue) {
String s = getProperty(conf, key, null);
if (s != null) {
try {
return Integer.decode(s).intValue();
} catch (NumberFormatException e) {
// ignore
}
}
return defaultValue;
}
/**
* Get the system property. If the system property is not set, or if a
* security exception occurs, the default value is returned.
*
* @param key
* the key
* @param defaultValue
* the default value
* @return the value
*/
public static boolean getProperty(Configuration conf, String key,
boolean defaultValue) {
String s = getProperty(conf, key, null);
if (s != null) {
try {
return Boolean.parseBoolean(s);
} catch (NumberFormatException e) {
// ignore
}
}
return defaultValue;
}
/**
* Read a long value from the byte array at the given position. The most
* significant byte is read first.
*
* @param buff
* the byte array
* @param pos
* the position
* @return the value
*/
public static long readLong(byte[] buff, int pos) {
return (((long) readInt(buff, pos)) << 32)
+ (readInt(buff, pos + 4) & 0xffffffffL);
}
public static int readInt(byte[] buff, int pos) {
return (buff[pos++] << 24) + ((buff[pos++] & 0xff) << 16)
+ ((buff[pos++] & 0xff) << 8) + (buff[pos] & 0xff);
}
public static double readDouble(byte[] b) {
long l;
l = b[0];
l &= 0xff;
l |= ((long) b[1] << 8);
l &= 0xffff;
l |= ((long) b[2] << 16);
l &= 0xffffff;
l |= ((long) b[3] << 24);
l &= 0xffffffffl;
l |= ((long) b[4] << 32);
l &= 0xffffffffffl;
l |= ((long) b[5] << 40);
l &= 0xffffffffffffl;
l |= ((long) b[6] << 48);
l |= ((long) b[7] << 56);
return Double.longBitsToDouble(l);
}
/**
* Compare the contents of two byte arrays. If the content or length of the
* first array is smaller than the second array, -1 is returned. If the
* content or length of the second array is smaller than the first array, 1 is
* returned. If the contents and lengths are the same, 0 is returned.
*
* @param data1
* the first byte array (must not be null)
* @param data2
* the second byte array (must not be null)
* @return the result of the comparison (-1, 1 or 0)
*/
public static int compareNotNull(byte[] data1, byte[] data2) {
if (data1 == data2) {
return 0;
}
int len = Math.min(data1.length, data2.length);
for (int i = 0; i < len; i++) {
byte b = data1[i];
byte b2 = data2[i];
if (b != b2) {
return b > b2 ? 1 : -1;
}
}
return Integer.signum(data1.length - data2.length);
}
/**
* Calculate the hash code of the given byte array.
*
* @param value
* the byte array
* @return the hash code
*/
public static int getByteArrayHash(byte[] value) {
int len = value.length;
int h = len;
if (len < 50) {
for (int i = 0; i < len; i++) {
h = 31 * h + value[i];
}
} else {
int step = len / 16;
for (int i = 0; i < 4; i++) {
h = 31 * h + value[i];
h = 31 * h + value[--len];
}
for (int i = 4 + step; i < len; i += step) {
h = 31 * h + value[i];
}
}
return h;
}
public static float readFloat(byte[] values) {
int accum = 0;
for (int shiftBy = 0; shiftBy < values.length; shiftBy++) {
accum |= (values[shiftBy] & 0xff) << shiftBy * 8;
}
return Float.intBitsToFloat(accum);
}
/**
* Get a resource from the resource map.
*
* @param name
* the name of the resource
* @return the resource data
*/
public static byte[] getResource(String name) throws IOException {
byte[] data = RESOURCES.get(name);
if (data == null) {
data = loadResource(name);
RESOURCES.put(name, data);
}
return data == null ? EMPTY_BYTES : data;
}
private static byte[] loadResource(String name) throws IOException {
InputStream in = Utils.class.getResourceAsStream("data.zip");
if (in == null) {
in = Utils.class.getResourceAsStream(name);
if (in == null) {
return null;
}
return IOUtils.readBytesAndClose(in, 0);
}
ZipInputStream zipIn = new ZipInputStream(in);
try {
while (true) {
ZipEntry entry = zipIn.getNextEntry();
if (entry == null) {
break;
}
String entryName = entry.getName();
if (!entryName.startsWith("/")) {
entryName = "/" + entryName;
}
if (entryName.equals(name)) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copy(zipIn, out);
zipIn.closeEntry();
return out.toByteArray();
}
zipIn.closeEntry();
}
} catch (IOException e) {
// if this happens we have a real problem
e.printStackTrace();
} finally {
zipIn.close();
}
return null;
}
public static Properties convertConfigurationToProperties(Configuration conf) {
Properties properties = new Properties();
for (Map.Entry<String, String> configurationEntry : conf) {
properties
.put(configurationEntry.getKey(), configurationEntry.getValue());
}
return properties;
}
public static Configuration convertPropertiesToConfiguration(
Properties properties) {
Configuration conf = WaspConfiguration.create();
for (Map.Entry entry : properties.entrySet()) {
if (entry.getKey() instanceof String) {
Object value = properties.get(entry.getKey());
if (value instanceof String) {
conf.set((String) entry.getKey(), (String) value);
}
}
}
return conf;
}
public static ReadModel getReadModel(String readModel) {
if(StringUtils.isNullOrEmpty(readModel)) {
return ReadModel.SNAPSHOT;
}
for (ReadModel model : ReadModel.values()) {
if (readModel.equals(model)) {
return model;
}
}
return ReadModel.SNAPSHOT;
}
}