org.apache.mnemonic.Utils.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.mnemonic.Utils.java

Source

/*
 * 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;
    }
}