Java tutorial
/* * 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.mnemonic; import java.lang.reflect.Field; import java.nio.ByteBuffer; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.Random; import java.util.UUID; import sun.misc.Unsafe; import java.util.Iterator; import java.util.List; import java.util.ServiceLoader; import org.apache.commons.lang3.StringUtils; import org.apache.mnemonic.service.allocatorservice.VolatileMemoryAllocatorService; import org.apache.mnemonic.service.computingservice.GeneralComputingService; import org.apache.mnemonic.service.allocatorservice.NonVolatileMemoryAllocatorService; /** * <p> * Utilities for project. * </p> * */ @SuppressWarnings("restriction") public class Utils { public static final String ANSI_RESET = "\u001B[0m"; public static final String ANSI_BLACK = "\u001B[30m"; public static final String ANSI_RED = "\u001B[31m"; public static final String ANSI_GREEN = "\u001B[32m"; public static final String ANSI_YELLOW = "\u001B[33m"; public static final String ANSI_BLUE = "\u001B[34m"; public static final String ANSI_PURPLE = "\u001B[35m"; public static final String ANSI_CYAN = "\u001B[36m"; public static final String ANSI_WHITE = "\u001B[37m"; private static Unsafe m_unsafe = null; private static ServiceLoader<VolatileMemoryAllocatorService> m_vmasvcloader = null; private static ServiceLoader<NonVolatileMemoryAllocatorService> m_nvmasvcloader = null; private static ServiceLoader<GeneralComputingService> m_gcompsvcloader = null; /** * retrieve a volatile memory allocator service * * @param id * specify a name of allocator to retrieve * * @return the volatile memory allocator service instance */ public static VolatileMemoryAllocatorService getVolatileMemoryAllocatorService(String id) { return getVolatileMemoryAllocatorService(id, true); } /** * retrieve a volatile memory allocator service * * @param id * specify a name of allocator to retrieve * * @param allownvmsvc * specify whether allow to treat non-volatile memory allocator as * volatile one during searching * * @return the volatile memory allocator service instance */ public static VolatileMemoryAllocatorService getVolatileMemoryAllocatorService(String id, boolean allownvmsvc) { VolatileMemoryAllocatorService ret = null; if (null == m_vmasvcloader) { m_vmasvcloader = ServiceLoader.load(VolatileMemoryAllocatorService.class); } Iterator<VolatileMemoryAllocatorService> svcit = m_vmasvcloader.iterator(); VolatileMemoryAllocatorService svc = null; while (null == ret && svcit.hasNext()) { svc = svcit.next(); if (svc.getServiceId().equals(id)) { ret = svc; } } if (null == ret && allownvmsvc) { ret = getNonVolatileMemoryAllocatorService(id); } assert null != ret : "VolatileMemoryAllocatorService \'" + id + "\' not found!"; return ret; } /** * retrieve a non-volatile memory allocator service * * @param id * specify a name of allocator to retrieve * * @return the non-volatile memory allocator service instance */ public static NonVolatileMemoryAllocatorService getNonVolatileMemoryAllocatorService(String id) { NonVolatileMemoryAllocatorService ret = null; if (null == m_nvmasvcloader) { m_nvmasvcloader = ServiceLoader.load(NonVolatileMemoryAllocatorService.class); } Iterator<NonVolatileMemoryAllocatorService> svcit = m_nvmasvcloader.iterator(); NonVolatileMemoryAllocatorService svc = null; while (null == ret && svcit.hasNext()) { svc = svcit.next(); if (svc.getServiceId().equals(id)) { ret = svc; } } assert null != ret : "NonVolatileMemoryAllocatorService \'" + id + "\' not found!"; return ret; } /** * retrieve a durable general computing service * * @param id * specify a name of general computing to retrieve * * @return the durable general computing service instance */ public static GeneralComputingService getGeneralComputingService(String id) { GeneralComputingService ret = null; if (null == m_gcompsvcloader) { m_gcompsvcloader = ServiceLoader.load(GeneralComputingService.class); } Iterator<GeneralComputingService> svcit = m_gcompsvcloader.iterator(); GeneralComputingService svc = null; while (null == ret && svcit.hasNext()) { svc = svcit.next(); if (svc.getServiceId().equals(id)) { ret = svc; } } assert null != ret : "GeneralComputingService \'" + id + "\' not found!"; return ret; } /** * Generates a unique name that contains current timestamp. * * @param format * the template that is used to generate unique name. * * @return unique path name. */ public static String genUniquePathname(String format) { String ret = null; if (null != format && !format.isEmpty()) { ret = String.format(format, (new SimpleDateFormat("ddMMyy-hhmmss.SSS").format(new Date()))); } return ret; } /** * retrieve the usage of memory. * * @param timeout * specify a timeout for this operation * * @return the size of memory has been occupied */ public static long getMemoryUse(long timeout) { putOutTheGarbage(timeout); long totalMemory = Runtime.getRuntime().totalMemory(); putOutTheGarbage(timeout); long freeMemory = Runtime.getRuntime().freeMemory(); return (totalMemory - freeMemory); } /** * run garbage collections. */ private static void putOutTheGarbage(long timeout) { collectGarbage(timeout); collectGarbage(timeout); } /** * run a garbage collection. * * @param timeout * specify a timeout for this operation * */ public static void collectGarbage(long timeout) { try { System.gc(); Thread.sleep(timeout); System.runFinalization(); Thread.sleep(timeout); } catch (InterruptedException ex) { ex.printStackTrace(); } } /** * Retrieve an Unsafe object. * * @throws Exception * Error when get Unsafe object from runtime * * @return an unsafe object */ public static Unsafe getUnsafe() throws Exception { if (null == m_unsafe) { Field field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); m_unsafe = (sun.misc.Unsafe) field.get(null); } return m_unsafe; } /** * resize a bytebuffer with a new instance * * @param buf * specify a buf to resize * * @param size * specify the size for resizing * * @return the resized bytebuffer instance */ public static ByteBuffer resizeByteBuffer(ByteBuffer buf, long size) { ByteBuffer ret = ByteBuffer.allocateDirect((int) size); if (ret != null) { if (null != buf) { ret.put(buf); ret.flip(); } } return ret; } /** * create a new instance of Random using default fixed seed * * @return the instance of Random */ public static Random createRandom() { return createRandom(0L); } /** * create a new instance of Random * * @param rgenseed * specify a random seed * * @return the instance of Random */ public static Random createRandom(long rgenseed) { Random ret = new Random(); if (0L == rgenseed) { rgenseed = System.currentTimeMillis(); System.out.println("Random number generator seed is " + rgenseed); } else { System.out.println("Fixed Random number generator seed is " + rgenseed); } ret.setSeed(rgenseed); return ret; } /** * generate a random string with fixed length * * @return the random string */ public static String genRandomString() { return genRandomString(6); } /** * generate a random string * * @param len * specify the length of this random string * * @return the random string */ public static String genRandomString(int len) { return UUID.randomUUID().toString().replaceAll("-", "").toUpperCase().substring(0, len); } /** * assert the equality of two generic objects using compareTo() operator * * @param <T> * the type of comparable objects * * @param actual * specify a object to be compared * * @param expected * specify a object to be expected * * @return true if equal according to compareTo() */ public static <T extends Comparable<T>> boolean assertComparison(T actual, T expected) { boolean ret = false; if ((expected == null) && (actual == null)) { ret = true; } else if (expected != null) { ret = expected.compareTo(actual) == 0; } return ret; } /** * convert a long array to a initializer literal string. * * @param larr * specify a long array to be converted * * @return a literal string represent the initializer */ public static String toInitLiteral(long[] larr) { return Arrays.toString(larr).replaceAll("\\[", "{").replaceAll("\\]", "}"); } /** * convert a list of long array to a initializer literal string. * * @param llarr * specify a list of long array to be converted * * @return a literal string represent the initializer */ public static String toInitLiteral(List<long[]> llarr) { List<String> slist = new ArrayList<String>(); for (long[] larr : llarr) { slist.add(toInitLiteral(larr)); } return "{" + StringUtils.join(slist, ",") + "}"; } /** * retrieve a set of native field info from a list of object field info * according to the field id info. it forms a value info stack for native code * to use as one standardized parameter * * @param objstack * a stack of object info retrieved from * Durable.getNativeFieldInfo(), order matters * * @param fidinfostack * a stack of field id in the form of (next_fid, next_level_fid) * order follows objstack the last next_level_fid specifies the * value's fid. the last item of next_fid could be null if there is * no next node if it is null that means the last item is a object * instead of node * * @return the stack of native field info * */ public static List<long[]> getNativeParamForm(List<long[][]> objstack, long[][] fidinfostack) { List<long[]> ret = null; if (null == objstack || null == fidinfostack || fidinfostack.length != objstack.size()) { throw new IllegalArgumentException("Not the same depth"); } ret = new ArrayList<long[]>(); for (int idx = 0; idx < fidinfostack.length; ++idx) { ret.add(genNativeStackItem(objstack.get(idx), fidinfostack[idx], idx == fidinfostack.length - 1)); } return ret; } /** * convert list form of native parameters to array form * * @param npf * a list of native parameters * * @return the 2d array form of native parameter frame */ public static long[][] convertTo2DArrayForm(List<long[]> npf) { long[][] ret = null; if (null != npf && npf.size() > 0) { ret = npf.toArray(new long[npf.size()][]); } return ret; } /** * generate native form of object stack parameter frame. * * @param objstack * a stack of object info retrieved from * Durable.getNativeFieldInfo(), order matters * * @param fidinfostack * a stack of field id in the form of (next_fid, next_level_fid) * order follows objstack the last next_level_fid specifies the * value's fid. the last item of next_fid could be null if there is * no next node if it is null that means the last item is a object * instead of node * * @return the 2d array form of native parameter frame * * @see #getNativeParamForm(List, long[][]) * */ public static long[][] genNativeParamForm(List<long[][]> objstack, long[][] fidinfostack) { return convertTo2DArrayForm(getNativeParamForm(objstack, fidinfostack)); } /** * generate an item of native stack. * * @param oinfo * a object field info * * @param fidinfo * a pair of field id info * * @param allowfidnull * allow the first field id is null * * @return the native item */ public static long[] genNativeStackItem(long[][] oinfo, long[] fidinfo, boolean allowfidnull) { long[] ret = new long[4]; long fid; boolean found; if (fidinfo.length != 2) { throw new IllegalArgumentException("the length of field id array is not exactly 2"); } for (int idx = 0; idx < fidinfo.length; ++idx) { ret[idx * 2] = -1L; ret[idx * 2 + 1] = 0L; fid = fidinfo[idx]; if (fid <= 0) { if (allowfidnull && 0 == idx) { continue; } else { throw new IllegalArgumentException("the field id is not greater than 0"); } } found = false; for (long[] finfo : oinfo) { if (finfo.length != 3) { throw new IllegalArgumentException("the length of field array is not exactly 3"); } if (fid == finfo[0]) { ret[idx * 2] = finfo[1]; ret[idx * 2 + 1] = finfo[2]; found = true; } } if (!found) { throw new IllegalArgumentException("field id not found"); } } return ret; } }