You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mnemonic.apache.org by ga...@apache.org on 2016/04/05 21:51:52 UTC
[4/7] incubator-mnemonic git commit: MNEMONIC-5 MNEMONIC-6 #resolve
refactored package names
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/8e83efe5/core/src/main/java/com/intel/bigdatamem/OutOfPersistentMemory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/intel/bigdatamem/OutOfPersistentMemory.java b/core/src/main/java/com/intel/bigdatamem/OutOfPersistentMemory.java
deleted file mode 100644
index 08ef84a..0000000
--- a/core/src/main/java/com/intel/bigdatamem/OutOfPersistentMemory.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.intel.bigdatamem;
-
-/**
- * this is an exception that should be throw once out of persistent memory
- *
- */
-
-public class OutOfPersistentMemory extends RuntimeException {
-
- private static final long serialVersionUID = -6315943783592441148L;
-
- public OutOfPersistentMemory(String s) {
- super(s);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/8e83efe5/core/src/main/java/com/intel/bigdatamem/PMAddressTranslator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/intel/bigdatamem/PMAddressTranslator.java b/core/src/main/java/com/intel/bigdatamem/PMAddressTranslator.java
deleted file mode 100644
index 60337f9..0000000
--- a/core/src/main/java/com/intel/bigdatamem/PMAddressTranslator.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.intel.bigdatamem;
-
-
-/**
- * translate persistent memory address for allocator
- *
- */
-public interface PMAddressTranslator {
-
- /**
- * calculate the portable address
- *
- * @param addr
- * the address to be calculated
- *
- * @return the portable address
- */
- public long getPortableAddress(long addr);
-
- /**
- * calculate the effective address
- *
- * @param addr
- * the address to be calculated
- *
- * @return the effective address
- */
- public long getEffectiveAddress(long addr);
-
- /**
- * get the base address
- *
- * @return the base address
- */
- public long getBaseAddress();
-
- /**
- * set the base address for calculation
- *
- * @param addr
- * the base address
- *
- */
- public long setBaseAddress(long addr);
-}
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/8e83efe5/core/src/main/java/com/intel/bigdatamem/Reclaim.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/intel/bigdatamem/Reclaim.java b/core/src/main/java/com/intel/bigdatamem/Reclaim.java
deleted file mode 100644
index 33b978f..0000000
--- a/core/src/main/java/com/intel/bigdatamem/Reclaim.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.intel.bigdatamem;
-
-/**
- * an interface to reclaim its memory resource.
- *
- */
-public interface Reclaim<MRES> {
-
- /**
- * reclaim specified resources.
- *
- * @param mres
- * a resource to be reclaimed
- *
- * @param size
- * the size of resource, it will be set as null if unknown
- *
- * @return <tt>true</tt> if this resource has been reclaimed by this
- * callback. <tt>false</tt> if this resource needs to be claimed by
- * default reclaimer
- */
- public boolean reclaim(MRES mres, Long size);
-}
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/8e83efe5/core/src/main/java/com/intel/bigdatamem/RetrieveNonVolatileEntityError.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/intel/bigdatamem/RetrieveNonVolatileEntityError.java b/core/src/main/java/com/intel/bigdatamem/RetrieveNonVolatileEntityError.java
deleted file mode 100644
index 3e8b0c0..0000000
--- a/core/src/main/java/com/intel/bigdatamem/RetrieveNonVolatileEntityError.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.intel.bigdatamem;
-
-/**
- *
- *
- */
-
-
-public class RetrieveNonVolatileEntityError extends RuntimeException {
-
- /**
- *
- */
- private static final long serialVersionUID = 3985459401986971131L;
-
- public RetrieveNonVolatileEntityError(String s) {
- super(s);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/8e83efe5/core/src/main/java/com/intel/bigdatamem/SysMemAllocator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/intel/bigdatamem/SysMemAllocator.java b/core/src/main/java/com/intel/bigdatamem/SysMemAllocator.java
deleted file mode 100644
index ab85917..0000000
--- a/core/src/main/java/com/intel/bigdatamem/SysMemAllocator.java
+++ /dev/null
@@ -1,305 +0,0 @@
-package com.intel.bigdatamem;
-
-import java.lang.reflect.*;
-import java.nio.ByteBuffer;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.flowcomputing.commons.resgc.*;
-
-import sun.misc.Unsafe;
-import sun.misc.Cleaner;
-
-/**
- * manage a system memory pool as a internal volatile allocator
- *
- */
-@SuppressWarnings("restriction")
-public class SysMemAllocator extends CommonAllocator<SysMemAllocator> {
-
- private boolean m_activegc = true;
- private long m_gctimeout = 100;
- private Unsafe m_unsafe = null;
- private AtomicLong currentMemory = new AtomicLong(0L);
- private long maxStoreCapacity = 0L;
- private Map<Long, Long> m_chunksize = new ConcurrentHashMap<Long, Long>();
-
-
- /**
- * Constructor, it initialize and allocate a memory pool from Java off-heap
- * with specified capacity.
- *
- * @param capacity
- * specify the capacity of a system memory pool
- *
- * @param isnew
- * a place holder, always specify it as true
- *
- * @throws Exception
- * fail to retrieve Unsafe object
- *
- */
- public SysMemAllocator(long capacity, boolean isnew) throws Exception {
- m_unsafe = Utils.getUnsafe();
- maxStoreCapacity = capacity;
- /**
- * create a resource collector to release specified bytebuffer that backed
- * by Java off-heap.
- */
- m_bufcollector = new ResCollector<MemBufferHolder<SysMemAllocator>, ByteBuffer>(
- new ResReclaim<ByteBuffer>() {
- @Override
- public synchronized void reclaim(ByteBuffer mres) {
- Long sz = Long.valueOf(mres.capacity());
- boolean cb_reclaimed = false;
- if (null != m_bufferreclaimer) {
- cb_reclaimed = m_bufferreclaimer.reclaim(mres, sz);
- }
- if (!cb_reclaimed) {
- try {
- Field cleanerField;
- cleanerField = mres.getClass().getDeclaredField(
- "cleaner");
- cleanerField.setAccessible(true);
- Cleaner cleaner = (Cleaner) cleanerField.get(mres);
- cleaner.clean();
- } catch (NoSuchFieldException | SecurityException
- | IllegalArgumentException | IllegalAccessException e) {
- e.printStackTrace();
- }
- mres = null;
- }
- currentMemory.addAndGet(-sz);
- }
- });
-
- /**
- * create a resource collector to release specified chunk that backed by
- * Java off-heap.
- */
- m_chunkcollector = new ResCollector<MemChunkHolder<SysMemAllocator>, Long>(
- new ResReclaim<Long>() {
- @Override
- public synchronized void reclaim(Long mres) {
- // System.out.println(String.format("Reclaim: %X ...", mres));
- Long sz = m_chunksize.remove(mres);
- boolean cb_reclaimed = false;
- if (null != m_chunkreclaimer) {
- cb_reclaimed = m_chunkreclaimer.reclaim(mres, sz);
- }
- if (!cb_reclaimed) {
- m_unsafe.freeMemory(mres);
- mres = null;
- }
- if (null != sz) {
- currentMemory.addAndGet(-sz);
- }
- }
- });
- }
-
- /**
- * enable active garbage collection. the GC will be forced to collect garbages when
- * there is no more space for current allocation request.
- *
- * @param timeout
- * the timeout is used to yield for GC performing
- *
- * @return this allocator
- */
- @Override
- public SysMemAllocator enableActiveGC(long timeout) {
- m_activegc = true;
- m_gctimeout = timeout;
- return this;
- }
-
- /**
- * disable active garbage collection.
- *
- * @return this allocator
- */
- @Override
- public SysMemAllocator disableActiveGC() {
- m_activegc = false;
- return this;
- }
-
- /**
- * release the memory pool and close it.
- *
- */
- @Override
- public void close() {
- super.close();
- }
-
- /**
- * force to synchronize uncommitted data to backed memory pool
- * (this is a placeholder).
- *
- */
- @Override
- public void sync() {
- }
-
- /**
- * re-size a specified chunk on its backed memory pool.
- *
- * @param mholder
- * the holder of memory chunk. it can be
- * null.
- *
- * @param size
- * specify a new size of memory chunk
- *
- * @return the resized memory chunk handler
- */
- @Override
- public MemChunkHolder<SysMemAllocator> resizeChunk(MemChunkHolder<SysMemAllocator> mholder, long size){
- MemChunkHolder<SysMemAllocator> ret = null;
- boolean ac = null != mholder.getRefId();
- if (size > 0) {
- if (currentMemory.get() + size > maxStoreCapacity) {
- if (m_activegc) {
- forceGC();
- }
- }
- if (currentMemory.get() + size <= maxStoreCapacity) {
- Long addr = m_unsafe.reallocateMemory(mholder.get(), size);
- if (0 != addr) {
- mholder.clear();
- mholder.destroy();
- ret = new MemChunkHolder<SysMemAllocator>(this, addr, size);
- if (ac) {
- m_chunkcollector.register(ret);
- }
- }
- }
- }
- return ret;
- }
-
- /**
- * resize a specified buffer on its backed memory pool.
- *
- * @param mholder
- * the holder of memory buffer. it can be
- * null.
- *
- * @param size
- * specify a new size of memory chunk
- *
- * @return the resized memory buffer handler
- *
- */
- @Override
- public MemBufferHolder<SysMemAllocator> resizeBuffer(MemBufferHolder<SysMemAllocator> mholder, long size) {
- MemBufferHolder<SysMemAllocator> ret = null;
- boolean ac = null != mholder.getRefId();
- if (size > 0) {
- int bufpos = mholder.get().position();
- int buflimit = mholder.get().limit();
- if (currentMemory.get() + size > maxStoreCapacity) {
- if (m_activegc) {
- forceGC();
- }
- }
- if (currentMemory.get() + size <= maxStoreCapacity) {
- ByteBuffer buf = Utils.resizeByteBuffer(mholder.get(), size);
- if (null != buf) {
- mholder.clear();
- mholder.destroy();
- buf.position(bufpos <= size ? bufpos : 0);
- buf.limit(buflimit <= size ? buflimit : (int)size);
- ret = new MemBufferHolder<SysMemAllocator>(this, buf);
- if (ac) {
- m_bufcollector.register(ret);
- }
- }
- }
- }
- return ret;
- }
-
- /**
- * create a memory chunk that is managed by its holder.
- *
- * @param size
- * specify the size of memory chunk
- *
- * @param autoreclaim
- * specify whether or not to reclaim this
- * chunk automatically
- *
- * @return a holder contains a memory chunk
- */
- @Override
- public MemChunkHolder<SysMemAllocator> createChunk(long size, boolean autoreclaim) {
- MemChunkHolder<SysMemAllocator> ret = null;
- Long addr = null;
- if (currentMemory.get() + size > maxStoreCapacity) {
- if (m_activegc) {
- forceGC();
- }
- }
- if (currentMemory.get() + size <= maxStoreCapacity) {
- addr = m_unsafe.allocateMemory(size);
- }
- if (null != addr && 0 != addr) {
- ret = new MemChunkHolder<SysMemAllocator>(this, addr, size);
- ret.setCollector(m_chunkcollector);
- if (autoreclaim) {
- m_chunkcollector.register(ret);
- }
- m_chunksize.put(addr, size);
- currentMemory.getAndAdd(size);
- }
- return ret;
- }
-
- /**
- * create a memory buffer that is managed by its holder.
- *
- * @param size
- * specify the size of memory buffer
- *
- * @return a holder contains a memory buffer
- */
- @Override
- public MemBufferHolder<SysMemAllocator> createBuffer(long size, boolean autoreclaim) {
- MemBufferHolder<SysMemAllocator> ret = null;
- ByteBuffer bb = null;
- if (currentMemory.get() + size > maxStoreCapacity) {
- if (m_activegc) {
- forceGC();
- }
- }
- if (currentMemory.get() + size <= maxStoreCapacity) {
- bb = ByteBuffer.allocateDirect((int) size);
- }
- if (null != bb) {
- ret = new MemBufferHolder<SysMemAllocator>(this, bb);
- ret.setCollector(m_bufcollector);
- if (autoreclaim) {
- m_bufcollector.register(ret);
- }
- currentMemory.getAndAdd(size);
- }
- return ret;
- }
-
- /**
- * force to perform GC that is used to release unused backed memory
- * resources.
- */
- private void forceGC() {
- System.gc();
- try {
- Thread.sleep(m_gctimeout);
- } catch (Exception ex) {
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/8e83efe5/core/src/main/java/com/intel/bigdatamem/Utils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/intel/bigdatamem/Utils.java b/core/src/main/java/com/intel/bigdatamem/Utils.java
deleted file mode 100644
index 14a895a..0000000
--- a/core/src/main/java/com/intel/bigdatamem/Utils.java
+++ /dev/null
@@ -1,384 +0,0 @@
-package com.intel.bigdatamem;
-
-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.ServiceConfigurationError;
-import java.util.ServiceLoader;
-import com.intel.mnemonic.service.allocatorservice.VolatileMemoryAllocatorService;
-import com.intel.mnemonic.service.allocatorservice.NonVolatileMemoryAllocatorService;
-
-/**
- * <p>
- * Utilities for project.
- * </p>
- *
- */
-@SuppressWarnings("restriction")
-public class Utils {
- private static long fSLEEP_INTERVAL = 100;
-
- 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;
-
- /**
- * 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;
- }
-
- /**
- * 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.
- *
- * @return the size of memory has been occupied
- */
- public static long getMemoryUse() {
- putOutTheGarbage();
- long totalMemory = Runtime.getRuntime().totalMemory();
- putOutTheGarbage();
- long freeMemory = Runtime.getRuntime().freeMemory();
- return (totalMemory - freeMemory);
- }
-
- /**
- * run garbage collections.
- */
- private static void putOutTheGarbage() {
- collectGarbage();
- collectGarbage();
- }
-
- /**
- * run a garbage collection.
- */
- public static void collectGarbage() {
- try {
- System.gc();
- Thread.sleep(fSLEEP_INTERVAL);
- System.runFinalization();
- Thread.sleep(fSLEEP_INTERVAL);
- } 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 "{" + String.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 = new ArrayList<long[]>();
- if (null == objstack ||
- null == fidinfostack ||
- fidinfostack.length != objstack.size()) {
- throw new IllegalArgumentException("Not the same depth");
- }
- for (int idx = 0; idx < fidinfostack.length; ++idx) {
- ret.add(genNativeStackItem(objstack.get(idx), fidinfostack[idx],
- idx == fidinfostack.length - 1));
- }
- return ret;
- }
-
- /**
- * 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] = 0;
- ret[idx*2 + 1] = 0;
- 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;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/8e83efe5/core/src/main/java/com/intel/mnemonic/service/allocatorservice/NonVolatileMemoryAllocatorService.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/intel/mnemonic/service/allocatorservice/NonVolatileMemoryAllocatorService.java b/core/src/main/java/com/intel/mnemonic/service/allocatorservice/NonVolatileMemoryAllocatorService.java
deleted file mode 100644
index 81cc3c8..0000000
--- a/core/src/main/java/com/intel/mnemonic/service/allocatorservice/NonVolatileMemoryAllocatorService.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package com.intel.mnemonic.service.allocatorservice;
-
-import org.flowcomputing.commons.primitives.*;
-import java.nio.ByteBuffer;
-
-public interface NonVolatileMemoryAllocatorService extends VolatileMemoryAllocatorService {
-
- /**
- * retrieve a bytebuffer from its handler
- *
- * @param id
- * the identifier of backed memory pool
- *
- * @param handler
- * the handler of a nonvolatile bytebuffer
- *
- * @return the nonvolatile bytebuffer
- *
- */
- public ByteBuffer retrieveByteBuffer(long id, long handler);
-
- /**
- * retrieve the size of a nonvolatile memory object
- *
- * @param id
- * the identifier of backed memory pool
- *
- * @param handler
- * the handler of a nonvolatile object
- *
- * @return the size of nonvolatile object
- *
- */
- public long retrieveSize(long id, long handler);
-
- /**
- * get the handler of a nonvolatile bytebuffer
- *
- * @param id
- * the identifier of backed memory pool
- *
- * @param buf
- * the nonvolatile bytebuffer
- *
- * @return the handler of this specified nonvolatile bytebuffer
- *
- */
- public long getByteBufferHandler(long id, ByteBuffer buf);
-
- /**
- * set a handler to a key.
- *
- * @param id
- * the identifier of backed memory pool
- *
- * @param key
- * the key to set this handler
- *
- * @param handler
- * the handler
- */
- public void setHandler(long id, long key, long handler);
-
- /**
- * get a handler from specified key.
- *
- * @param id
- * the identifier of backed memory pool
- *
- * @param key
- * the key to get its handler
- *
- * @return the handler of the specified key
- */
- public long getHandler(long id, long key);
-
- /**
- * return the number of available keys to use.
- *
- * @param id
- * the identifier of backed memory pool
- *
- * @return the number of keys
- */
- public long handlerCapacity(long id);
-
- /**
- * return the base address of this persistent memory pool.
- *
- * @param id
- * the identifier of backed memory pool
- *
- * @return the base address of this pmem pool
- */
- public long getBaseAddress(long id);
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/8e83efe5/core/src/main/java/com/intel/mnemonic/service/allocatorservice/VolatileMemoryAllocatorService.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/com/intel/mnemonic/service/allocatorservice/VolatileMemoryAllocatorService.java b/core/src/main/java/com/intel/mnemonic/service/allocatorservice/VolatileMemoryAllocatorService.java
deleted file mode 100644
index e800872..0000000
--- a/core/src/main/java/com/intel/mnemonic/service/allocatorservice/VolatileMemoryAllocatorService.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package com.intel.mnemonic.service.allocatorservice;
-
-import org.flowcomputing.commons.primitives.*;
-import java.nio.ByteBuffer;
-
-public interface VolatileMemoryAllocatorService {
-
- /**
- * Provide the service identifier for this allocator
- *
- * @return the service identifer of this allocator
- */
- public String getServiceId();
-
- /**
- * Initialize a memory pool through native interface backed by native
- * library.
- *
- * @param capacity
- * the capacity of memory pool
- *
- * @param uri
- * the location of memory pool will be created
- *
- * @param isnew
- * a place holder, always specify it as true
- *
- * @return the identifier of created memory pool
- */
- public long init(long capacity, String uri, boolean isnew);
-
- /**
- * close the memory pool through native interface.
- *
- */
- public void close(long id);
-
-
- /**
- * force to synchronize uncommitted data to backed memory pool through
- * native interface.
- */
- public void sync(long id);
-
- /**
- * allocate specified size of memory block from backed memory pool.
- *
- * @param id
- * the identifier of backed memory pool
- *
- * @param size
- * specify size of memory block to be allocated
- *
- * @return the address of allocated memory block from native memory pool
- */
- public long allocate(long id, long size, boolean initzero);
-
- /**
- * reallocate a specified size of memory block from backed memory pool.
- *
- * @param id
- * the identifier of backed memory pool
- *
- * @param address
- * the address of previous allocated memory block. it can be
- * null.
- *
- * @param size
- * specify new size of memory block to be reallocated
- *
- * @return the address of reallocated memory block from native memory pool
- */
- public long reallocate(long id, long address, long size, boolean initzero);
-
- /**
- * free a memory block by specify its address into backed memory pool.
- *
- * @param id
- * the identifier of backed memory pool
- *
- * @param address
- * the address of allocated memory block.
- */
- public void free(long id, long address);
-
- /**
- * create a ByteBuffer object which backed buffer is coming from backed
- * native memory pool.
- *
- * @param id
- * the identifier of backed memory pool
- *
- * @param size
- * the size of backed buffer that is managed by created
- * ByteBuffer object.
- *
- * @return a created ByteBuffer object with a backed native memory block
- */
- public ByteBuffer createByteBuffer(long id, long size);
-
- /**
- * resize a ByteBuffer object which backed buffer is coming from backed
- * native memory pool.
- * NOTE: the ByteBuffer object will be renewed and lost metadata e.g. position, mark and etc.
- *
- * @param id
- * the identifier of backed memory pool
- *
- * @param bytebuf
- * the specified ByteBuffer object to be destroyed
- *
- * @param size
- * the new size of backed buffer that is managed by created
- * ByteBuffer object.
- *
- * @return a created ByteBuffer object with a backed native memory block
- */
- public ByteBuffer resizeByteBuffer(long id, ByteBuffer bytebuf, long size);
-
- /**
- * destroy a native memory block backed ByteBuffer object.
- *
- * @param id
- * the identifier of backed memory pool
- *
- * @param bytebuf
- * the specified ByteBuffer object to be destroyed
- */
- public void destroyByteBuffer(long id, ByteBuffer bytebuf);
-}
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/8e83efe5/core/src/main/java/org/apache/mnemonic/Allocatable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/mnemonic/Allocatable.java b/core/src/main/java/org/apache/mnemonic/Allocatable.java
new file mode 100644
index 0000000..76ec38d
--- /dev/null
+++ b/core/src/main/java/org/apache/mnemonic/Allocatable.java
@@ -0,0 +1,102 @@
+package org.apache.mnemonic;
+
+/**
+ * an interface to allocate memory resources from any underlying memory kind
+ * of storage.
+ *
+ */
+public interface Allocatable<A extends CommonAllocator<A>> {
+
+ /**
+ * create a memory chunk that is managed by its holder.
+ *
+ * @param size
+ * specify the size of memory chunk
+ *
+ * @param autoreclaim
+ * specify whether or not to reclaim this
+ * chunk automatically
+ *
+ * @return a holder contains a memory chunk
+ */
+ public MemChunkHolder<A> createChunk(long size, boolean autoreclaim);
+
+ /**
+ * create a memory chunk that is managed by its holder.
+ *
+ * @param size
+ * specify the size of memory chunk
+ *
+ * @return a holder contains a memory chunk
+ */
+ public MemChunkHolder<A> createChunk(long size);
+
+ /**
+ * create a memory buffer that is managed by its holder.
+ *
+ * @param size
+ * specify the size of memory buffer
+ *
+ * @param autoreclaim
+ * specify whether or not to reclaim this
+ * buffer automatically
+ *
+ * @return a holder contains a memory buffer
+ */
+ public MemBufferHolder<A> createBuffer(long size, boolean autoreclaim);
+
+ /**
+ * create a memory buffer that is managed by its holder.
+ *
+ * @param size
+ * specify the size of memory buffer
+ *
+ * @return a holder contains a memory buffer
+ */
+ public MemBufferHolder<A> createBuffer(long size);
+
+ /**
+ * register a memory chunk for auto-reclaim
+ *
+ * @param mholder
+ * specify a chunk holder to register
+ */
+ public void registerChunkAutoReclaim(MemChunkHolder<A> mholder);
+
+ /**
+ * register a memory buffer for auto-reclaim
+ *
+ * @param mholder
+ * specify a buffer holder to register
+ */
+ public void registerBufferAutoReclaim(MemBufferHolder<A> mholder);
+
+ /**
+ * resize a memory chunk.
+ *
+ * @param mholder
+ * specify a chunk holder for resizing
+ *
+ * @param size
+ * specify a new size of this memory chunk
+ *
+ * @return the resized memory chunk holder
+ *
+ */
+ public MemChunkHolder<A> resizeChunk(MemChunkHolder<A> mholder, long size);
+
+ /**
+ * resize a memory buffer.
+ *
+ * @param mholder
+ * specify a buffer holder for resizing
+ *
+ * @param size
+ * specify a new size of this memory buffer
+ *
+ * @return the resized memory buffer holder
+ *
+ */
+ public MemBufferHolder<A> resizeBuffer(MemBufferHolder<A> mholder, long size);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/8e83efe5/core/src/main/java/org/apache/mnemonic/Allocator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/mnemonic/Allocator.java b/core/src/main/java/org/apache/mnemonic/Allocator.java
new file mode 100644
index 0000000..c887b07
--- /dev/null
+++ b/core/src/main/java/org/apache/mnemonic/Allocator.java
@@ -0,0 +1,39 @@
+package org.apache.mnemonic;
+
+/**
+ * an interface to manage the lifecycle of memory allocator
+ *
+ */
+public interface Allocator<A extends CommonAllocator<A>> extends Allocatable<A> {
+
+ /**
+ * release the underlying memory pool and close it.
+ *
+ */
+ public void close();
+
+ /**
+ * sync. dirty data to underlying memory-like device
+ *
+ */
+ public void sync();
+
+ /**
+ * enable active garbage collection. the GC will be forced to collect garbages when
+ * there is no more space for current allocation request.
+ *
+ * @param timeout
+ * the timeout is used to yield for GC performing
+ *
+ * @return this allocator
+ */
+ public A enableActiveGC(long timeout);
+
+ /**
+ * disable active garbage collection.
+ *
+ * @return this allocator
+ */
+ public A disableActiveGC();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/8e83efe5/core/src/main/java/org/apache/mnemonic/AnnotatedNonVolatileEntityClass.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/mnemonic/AnnotatedNonVolatileEntityClass.java b/core/src/main/java/org/apache/mnemonic/AnnotatedNonVolatileEntityClass.java
new file mode 100644
index 0000000..68a7a3d
--- /dev/null
+++ b/core/src/main/java/org/apache/mnemonic/AnnotatedNonVolatileEntityClass.java
@@ -0,0 +1,977 @@
+package org.apache.mnemonic;
+
+import java.io.IOException;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.processing.*;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import sun.misc.Unsafe;
+
+import com.squareup.javapoet.*;
+import com.squareup.javapoet.MethodSpec.Builder;
+
+/**
+ * this class managed to generate generic non-volatile concrete object and their corresponding factory.
+ *
+ */
+public class AnnotatedNonVolatileEntityClass {
+ protected class MethodInfo {
+ public ExecutableElement elem;
+ public MethodSpec.Builder specbuilder;
+ public TypeName rettype;
+ }
+ protected class FieldInfo {
+ public FieldSpec.Builder specbuilder;
+ public TypeName type;
+ public long id;
+ public String name;
+ public String efproxiesname;
+ public String gftypesname;
+ public long fieldoff;
+ public long fieldsize;
+ }
+
+ protected final String FACTORYNAMESUFFIX = "Factory";
+ protected final String PMEMNAMEPREFIX = "NonVolatile_";
+ protected final String FIELDNAMESUFFIX = String.format("_field_%s", Utils.genRandomString());
+ protected final String ALLOCATORFIELDNAME = String.format("alloc_%s", Utils.genRandomString());
+ protected final String AUTORECLAIMFIELDNAME = String.format("autoreclaim_%s", Utils.genRandomString());
+ protected final String UNSAFEFIELDNAME = String.format("unsafe_%s", Utils.genRandomString());
+ protected final String HOLDERFIELDNAME = String.format("holder_%s", Utils.genRandomString());
+ protected final String ALLOCTYPENAME = String.format("ALLOC_PMem3C93D24F59");
+
+ private Types m_typeutils;
+ private Elements m_elemutils;
+ private Messager m_msgr;
+ private TypeElement m_elem;
+
+ private String m_factoryname;
+ private String m_entityname;
+
+ private long m_holdersize;
+
+ private String m_packagename;
+
+ private TypeName m_alloctypename = TypeVariableName.get(ALLOCTYPENAME);
+ private TypeName m_factoryproxystypename = TypeName.get(EntityFactoryProxy[].class);
+ private TypeName m_gfieldstypename = TypeName.get(GenericField.GType[].class);
+ private TypeVariableName m_alloctypevarname = TypeVariableName.get(ALLOCTYPENAME,
+ ParameterizedTypeName.get(ClassName.get(CommonPersistAllocator.class), TypeVariableName.get(ALLOCTYPENAME)));
+
+ private Map<String, MethodInfo> m_gettersinfo = new HashMap<String, MethodInfo>();
+ private Map<String, MethodInfo> m_settersinfo = new HashMap<String, MethodInfo>();
+ private Map<String, FieldInfo> m_dynfieldsinfo = new HashMap<String, FieldInfo>();
+ private Map<String, FieldInfo> m_fieldsinfo = new HashMap<String, FieldInfo>();
+
+ private Map<String, MethodInfo> m_durablemtdinfo = new HashMap<String, MethodInfo>();
+ private Map<String, MethodInfo> m_entitymtdinfo = new HashMap<String, MethodInfo>();
+
+ private long computeTypeSize(TypeMirror type) {
+ long ret;
+ switch (type.getKind()) {
+ case BYTE:
+ ret = 1L;
+ break;
+ case BOOLEAN:
+ ret = 1L;
+ break;
+ case CHAR:
+ ret = 2L;
+ break;
+ case DOUBLE:
+ ret = 8L;
+ break;
+ case FLOAT:
+ ret = 4L;
+ break;
+ case SHORT:
+ ret = 2L;
+ break;
+ case INT:
+ ret = 4L;
+ break;
+ case LONG:
+ ret = 8L;
+ break;
+ default:
+ ret = 8L;
+ }
+ return ret;
+ }
+
+ private boolean isUnboxPrimitive(TypeName tn) {
+ TypeName n = tn;
+ try {
+ n = tn.unbox();
+ } catch(UnsupportedOperationException ex) {}
+ return n.isPrimitive();
+ }
+
+ private TypeName unboxTypeName(TypeName tn) {
+ TypeName n = tn;
+ try {
+ n = tn.unbox();
+ } catch(UnsupportedOperationException ex) {}
+ return n;
+ }
+
+ public AnnotatedNonVolatileEntityClass(TypeElement classElement, Types typeUtils, Elements elementUtils,
+ Messager messager) {
+ m_elem = classElement;
+ m_typeutils = typeUtils;
+ m_elemutils = elementUtils;
+ m_msgr = messager;
+
+ m_packagename = m_elemutils.getPackageOf(m_elem).getQualifiedName().toString();
+
+ m_factoryname = String.format("%s%s", m_elem.getSimpleName(), FACTORYNAMESUFFIX);
+ m_entityname = String.format("%s%s_%s", PMEMNAMEPREFIX, m_elem.getSimpleName(), Utils.genRandomString());
+
+ m_durablemtdinfo.put("cancelAutoReclaim", new MethodInfo());
+ m_durablemtdinfo.put("registerAutoReclaim", new MethodInfo());
+ m_durablemtdinfo.put("getNonVolatileHandler", new MethodInfo());
+ m_durablemtdinfo.put("autoReclaim", new MethodInfo());
+ m_durablemtdinfo.put("destroy", new MethodInfo());
+ m_durablemtdinfo.put("getNativeFieldInfo", new MethodInfo());
+
+ m_entitymtdinfo.put("initializeNonVolatileEntity", new MethodInfo());
+ m_entitymtdinfo.put("createNonVolatileEntity", new MethodInfo());
+ m_entitymtdinfo.put("restoreNonVolatileEntity", new MethodInfo());
+
+ }
+
+ public void prepareProcessing() throws AnnotationProcessingException {
+ MethodInfo methodinfo = null;
+ FieldInfo fieldinfo;
+ String methodname;
+ long fieldoff = 0;
+ TypeElement intf_durable = m_elemutils.getTypeElement(Durable.class.getCanonicalName());
+ TypeElement intf_entity = m_elemutils.getTypeElement(MemoryNonVolatileEntity.class.getCanonicalName());
+ // System.err.printf("<><><><><> %s ======\n", intf_entity.toString());
+
+ boolean valid = false;
+ for (TypeMirror tm : m_elem.getInterfaces()) {
+ if (tm.toString().equals(Durable.class.getCanonicalName())) {
+ valid = true;
+ break;
+ }
+ }
+ if (!valid) {
+ throw new AnnotationProcessingException(m_elem, "Not implemented Durable Interface by %s.",
+ m_elem.getSimpleName().toString());
+ }
+
+ fieldinfo = new FieldInfo();
+ fieldinfo.name = String.format("m_unsafe_%s",
+ Utils.genRandomString());
+ fieldinfo.type = TypeName.get(m_elemutils.getTypeElement(Unsafe.class.getCanonicalName()).asType());
+ fieldinfo.specbuilder = FieldSpec.builder(fieldinfo.type,
+ fieldinfo.name, Modifier.PRIVATE);
+ m_fieldsinfo.put("unsafe", fieldinfo);
+
+ fieldinfo = new FieldInfo();
+ fieldinfo.name = String.format("m_holder_%s",
+ Utils.genRandomString());
+ fieldinfo.type = ParameterizedTypeName.get(ClassName.get(MemChunkHolder.class), m_alloctypename);
+ fieldinfo.specbuilder = FieldSpec.builder(fieldinfo.type,
+ fieldinfo.name, Modifier.PRIVATE);
+ m_fieldsinfo.put("holder", fieldinfo);
+
+ fieldinfo = new FieldInfo();
+ fieldinfo.name = String.format("m_autoreclaim_%s",
+ Utils.genRandomString());
+ fieldinfo.type = TypeName.get(m_typeutils.getPrimitiveType(TypeKind.BOOLEAN));
+ fieldinfo.specbuilder = FieldSpec.builder(fieldinfo.type,
+ fieldinfo.name, Modifier.PRIVATE, Modifier.VOLATILE);
+ m_fieldsinfo.put("autoreclaim", fieldinfo);
+
+ fieldinfo = new FieldInfo();
+ fieldinfo.name = String.format("m_allocator_%s",
+ Utils.genRandomString());
+ fieldinfo.type = m_alloctypename;
+ fieldinfo.specbuilder = FieldSpec.builder(fieldinfo.type,
+ fieldinfo.name, Modifier.PRIVATE);
+ m_fieldsinfo.put("allocator", fieldinfo);
+
+ fieldinfo = new FieldInfo();
+ fieldinfo.name = String.format("m_factoryproxy_%s",
+ Utils.genRandomString());
+ fieldinfo.type = m_factoryproxystypename;
+ fieldinfo.specbuilder = FieldSpec.builder(fieldinfo.type,
+ fieldinfo.name, Modifier.PRIVATE);
+ m_fieldsinfo.put("factoryproxy", fieldinfo);
+
+ fieldinfo = new FieldInfo();
+ fieldinfo.name = String.format("m_genericfield_%s",
+ Utils.genRandomString());
+ fieldinfo.type = m_gfieldstypename;
+ fieldinfo.specbuilder = FieldSpec.builder(fieldinfo.type,
+ fieldinfo.name, Modifier.PRIVATE);
+ m_fieldsinfo.put("genericfield", fieldinfo);
+
+ for (Element elem : m_elem.getEnclosedElements()) {
+ if (elem.getKind() == ElementKind.METHOD) {
+ methodname = elem.getSimpleName().toString();
+ // System.err.printf("=========== %s ======\n", methodname);
+ NonVolatileGetter pgetter = elem.getAnnotation(NonVolatileGetter.class);
+ if (pgetter != null) {
+ if (!elem.getModifiers().contains(Modifier.ABSTRACT)) {
+ throw new AnnotationProcessingException(elem,
+ "%s annotated with NonVolatileGetter is not abstract.", methodname);
+ }
+ if (null != elem.getAnnotation(NonVolatileSetter.class)) {
+ throw new AnnotationProcessingException(elem, "%s is annotated with NonVolatileSetter as well.",
+ methodname);
+ }
+ if (!methodname.startsWith("get")) {
+ throw new AnnotationProcessingException(elem, "%s does not comply name convention of getter.",
+ methodname);
+ }
+ methodinfo = new MethodInfo();
+ methodinfo.elem = (ExecutableElement) elem;
+ methodinfo.specbuilder = MethodSpec.overriding(methodinfo.elem);
+ methodinfo.rettype = TypeName.get(methodinfo.elem.getReturnType());
+ m_gettersinfo.put(methodname.substring(3), methodinfo);
+ fieldinfo = new FieldInfo();
+ fieldinfo.type = methodinfo.rettype;
+ if (fieldinfo.type.toString().equals(String.class.getCanonicalName())) {
+ fieldinfo.type = ParameterizedTypeName.get(ClassName.get(MemBufferHolder.class), m_alloctypename);
+ }
+ if (fieldinfo.type instanceof TypeVariableName) {
+ fieldinfo.type = ParameterizedTypeName.get(ClassName.get(GenericField.class), m_alloctypename, fieldinfo.type);
+ }
+ fieldinfo.name = String.format("m_%s_%s",
+ methodname.substring(3).toLowerCase(),
+ Utils.genRandomString());
+ fieldinfo.specbuilder = FieldSpec.builder(fieldinfo.type,
+ fieldinfo.name, Modifier.PRIVATE);
+ fieldinfo.fieldsize = computeTypeSize(methodinfo.elem.getReturnType());
+ fieldinfo.fieldoff = fieldoff;
+ fieldoff += fieldinfo.fieldsize;
+ fieldinfo.efproxiesname = pgetter.EntityFactoryProxies();
+ fieldinfo.gftypesname = pgetter.GenericFieldTypes();
+ fieldinfo.id = pgetter.Id();
+ m_dynfieldsinfo.put(methodname.substring(3), fieldinfo);
+
+ }
+ if (null != elem.getAnnotation(NonVolatileSetter.class)) {
+ if (!elem.getModifiers().contains(Modifier.ABSTRACT)) {
+ throw new AnnotationProcessingException(elem,
+ "%s annotated with NonVolatileSetter is not abstract.", methodname);
+ }
+ if (!methodname.startsWith("set")) {
+ throw new AnnotationProcessingException(elem, "%s does not comply name convention of setter.",
+ methodname);
+ }
+ methodinfo = new MethodInfo();
+ methodinfo.elem = (ExecutableElement) elem;
+ methodinfo.specbuilder = MethodSpec.overriding(methodinfo.elem);
+ m_settersinfo.put(methodname.substring(3), methodinfo);
+ }
+ // if (!methodinfo.elem.getThrownTypes().contains(m_elemutils.getTypeElement(RetrieveNonVolatileEntityError.class.getCanonicalName()).asType())) {
+ // throw new AnnotationProcessingException(methodinfo.elem, "%s must throw out %s.",
+ // methodname, RetrieveNonVolatileEntityError.class.getName());
+ // }
+ }
+ }
+
+ m_holdersize = fieldoff;
+
+ // MethodInfo minfo = null;
+ for (String name : m_settersinfo.keySet()) {
+ if (!m_gettersinfo.containsKey(name)) {
+ throw new AnnotationProcessingException(null, "%s has no getter.", name);
+ }
+ // if (m_dynfieldsinfo.get(name).type.toString().equals(String.class.getCanonicalName())) {
+ // minfo = m_settersinfo.get(name);
+ // if (!minfo.elem.getThrownTypes().contains(m_elemutils.getTypeElement(OutOfPersistentMemory.class.getCanonicalName()).asType())) {
+ // throw new AnnotationProcessingException(minfo.elem, "%s must throw out %s.",
+ // gsetterName(name, false), OutOfPersistentMemory.class.getName());
+ // }
+ // }
+ }
+
+ // for (String name : m_dynfieldsinfo.keySet()) {
+ // if (!isUnboxPrimitive(m_dynfieldsinfo.get(name).type)) {
+ // if (m_gettersinfo.containsKey(name)) {
+ // minfo = m_gettersinfo.get(name);
+ // if (!minfo.elem.getThrownTypes().contains(m_elemutils.getTypeElement(RetrieveNonVolatileEntityError.class.getCanonicalName()).asType())) {
+ // throw new AnnotationProcessingException(minfo.elem, "%s must throw out %s.",
+ // gsetterName(name, true), RetrieveNonVolatileEntityError.class.getName());
+ // }
+ // }
+ // if (m_settersinfo.containsKey(name)) {
+ // minfo = m_settersinfo.get(name);
+ // if (!minfo.elem.getThrownTypes().contains(m_elemutils.getTypeElement(RetrieveNonVolatileEntityError.class.getCanonicalName()).asType())) {
+ // throw new AnnotationProcessingException(minfo.elem, "%s must throw out %s.",
+ // gsetterName(name, false), RetrieveNonVolatileEntityError.class.getName());
+ // }
+ // }
+ // }
+ // }
+
+ for (Element elem : intf_durable.getEnclosedElements()) {
+ if (elem.getKind() == ElementKind.METHOD) {
+ methodname = elem.getSimpleName().toString();
+ if (m_durablemtdinfo.containsKey(methodname)) {
+ // System.err.printf("**++++++++++ %s ======\n", methodname);
+ methodinfo = m_durablemtdinfo.get(methodname);
+ methodinfo.elem = (ExecutableElement) elem;
+ methodinfo.specbuilder = MethodSpec.overriding(methodinfo.elem);
+ }
+ }
+ }
+
+ for (Element elem : intf_entity.getEnclosedElements()) {
+ if (elem.getKind() == ElementKind.METHOD) {
+ methodname = elem.getSimpleName().toString();
+ if (m_entitymtdinfo.containsKey(methodname)) {
+ // System.err.printf("**------- %s ======\n", elem.toString());
+ methodinfo = m_entitymtdinfo.get(methodname);
+ methodinfo.elem = (ExecutableElement) elem;
+ methodinfo.specbuilder = overriding(methodinfo.elem, ALLOCTYPENAME);
+
+ }
+ }
+ }
+ genNFieldInfo();
+ }
+
+ protected String transTypeToUnsafeMethod(TypeName tname, boolean isget) throws AnnotationProcessingException {
+ String ret = null;
+ if (isUnboxPrimitive(tname)) {
+ TypeName tn = unboxTypeName(tname);
+ if (tn.equals(TypeName.BOOLEAN)) ret = isget ? "getByte" : "putByte";
+ if (tn.equals(TypeName.BYTE)) ret = isget ? "getByte" : "putByte";
+ if (tn.equals(TypeName.CHAR)) ret = isget ? "getChar" : "putChar";
+ if (tn.equals(TypeName.DOUBLE)) ret = isget ? "getDouble" : "putDouble";
+ if (tn.equals(TypeName.FLOAT)) ret = isget ? "getFloat" : "putFloat";
+ if (tn.equals(TypeName.INT)) ret = isget ? "getInt" : "putInt";
+ if (tn.equals(TypeName.LONG)) ret = isget ? "getLong" : "putLong";
+ if (tn.equals(TypeName.SHORT)) ret = isget ? "getShort" : "putShort";
+ } else {
+ ret = isget ? "getAddress" : "putAddress";
+ }
+ if (null == ret) {
+ throw new AnnotationProcessingException(null, "%s is not supported by getters or setters.",
+ tname.toString());
+ }
+ return ret;
+ }
+
+ protected String getIntialValueLiteral(TypeName tname) throws AnnotationProcessingException {
+ String ret = null;
+ if (isUnboxPrimitive(tname)) {
+ TypeName tn = unboxTypeName(tname);
+ if (tn.equals(TypeName.BOOLEAN)) ret = "false";
+ if (tn.equals(TypeName.BYTE)) ret = "(byte)0";
+ if (tn.equals(TypeName.CHAR)) ret = "(char)0";
+ if (tn.equals(TypeName.DOUBLE)) ret = "(double)0.0";
+ if (tn.equals(TypeName.FLOAT)) ret = "(float)0.0";
+ if (tn.equals(TypeName.INT)) ret = "(int)0";
+ if (tn.equals(TypeName.LONG)) ret = "(long)0";
+ if (tn.equals(TypeName.SHORT)) ret = "(short)0";
+ } else {
+ ret = null;
+ }
+ if (null == ret) {
+ throw new AnnotationProcessingException(null, "%s is not supported to determine the inital value.",
+ tname.toString());
+ }
+ return ret;
+ }
+
+ private int getFactoryProxyIndex(TypeName gtname) throws AnnotationProcessingException {
+ int ret = -1;
+ boolean found = false;
+ if (gtname instanceof TypeVariableName) {
+ for (TypeParameterElement tpe : m_elem.getTypeParameters()) {
+ ++ret;
+ if (tpe.toString().equals(gtname.toString())) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ throw new AnnotationProcessingException(null, "%s type is not found during factory proxy query.",
+ gtname.toString());
+ }
+ } else {
+ throw new AnnotationProcessingException(null, "%s type is not generic type for factory proxy query.",
+ gtname.toString());
+ }
+ return ret;
+ }
+
+ protected void genNFieldInfo() {
+ FieldInfo dynfieldinfo, fieldinfo;
+ List<long[]> finfo = new ArrayList<long[]>();
+ for (String name : m_gettersinfo.keySet()) {
+ dynfieldinfo = m_dynfieldsinfo.get(name);
+ if (dynfieldinfo.id > 0) {
+ finfo.add(new long[]{dynfieldinfo.id, dynfieldinfo.fieldoff, dynfieldinfo.fieldsize});
+ }
+ }
+
+ fieldinfo = new FieldInfo();
+ fieldinfo.name = String.format("m_nfieldinfo_%s",
+ Utils.genRandomString());
+ fieldinfo.type = ArrayTypeName.of(ArrayTypeName.of(TypeName.LONG));
+ String initlstr = Utils.toInitLiteral(finfo);
+ fieldinfo.specbuilder = FieldSpec.builder(fieldinfo.type,
+ fieldinfo.name, Modifier.PRIVATE, Modifier.STATIC).initializer("$1L", initlstr);
+ m_fieldsinfo.put("nfieldinfo", fieldinfo);
+ }
+
+ protected void buildGettersSpecs(TypeSpec.Builder typespecbuilder) throws AnnotationProcessingException {
+ MethodInfo methodinfo;
+ TypeName ftname;
+ String unsafename = m_fieldsinfo.get("unsafe").name;
+ String holdername = m_fieldsinfo.get("holder").name;
+ String allocname = m_fieldsinfo.get("allocator").name;
+ String autoreclaimname = m_fieldsinfo.get("autoreclaim").name;
+ String factoryproxyname = m_fieldsinfo.get("factoryproxy").name;
+ String genericfieldname = m_fieldsinfo.get("genericfield").name;
+ FieldInfo dynfieldinfo;
+ CodeBlock.Builder code;
+ String codefmt;
+ for (String name : m_gettersinfo.keySet()) {
+ code = CodeBlock.builder();
+ methodinfo = m_gettersinfo.get(name);
+ dynfieldinfo = m_dynfieldsinfo.get(name);
+ ftname = m_dynfieldsinfo.get(name).type;
+ if (isUnboxPrimitive(ftname)) {
+ if (unboxTypeName(ftname).equals(TypeName.BOOLEAN)) {
+ codefmt = "return 1 == $1N.$4L($2N.get() + $3L)";
+ } else {
+ codefmt = "return $1N.$4L($2N.get() + $3L)";
+ }
+ code.addStatement(codefmt, unsafename, holdername, dynfieldinfo.fieldoff, transTypeToUnsafeMethod(ftname, true));
+ } else {
+ if(methodinfo.rettype.toString().equals(String.class.getCanonicalName())) {
+ code.beginControlFlow("if (null == $1N)", dynfieldinfo.name);
+ code.addStatement("long phandler = $1N.getAddress($2N.get() + $3L)",
+ unsafename, holdername, dynfieldinfo.fieldoff);
+ code.beginControlFlow("if (0L != phandler)");
+ code.addStatement("$1N = $2N.retrieveBuffer(phandler, $3N)",
+ dynfieldinfo.name, allocname, autoreclaimname);
+ code.beginControlFlow("if (null == $1N)", dynfieldinfo.name);
+ code.addStatement("throw new RetrieveNonVolatileEntityError(\"Retrieve String Buffer Failure.\")");
+ code.endControlFlow();
+ code.endControlFlow();
+ code.endControlFlow();
+ code.addStatement("return null == $1N ? null : $1N.get().asCharBuffer().toString()",
+ dynfieldinfo.name);
+ } else if (dynfieldinfo.type.toString().startsWith(GenericField.class.getCanonicalName())) {
+ code.beginControlFlow("if (null == $1N)", dynfieldinfo.name);
+ code.addStatement("$1T proxy = null", TypeName.get(EntityFactoryProxy.class));
+ code.addStatement("$1T gftype = null", TypeName.get(GenericField.GType.class));
+ code.addStatement("int gfpidx = $1L", getFactoryProxyIndex(methodinfo.rettype));
+ code.beginControlFlow("if (null != $1N && $1N.length > gfpidx)", factoryproxyname);
+ code.addStatement("proxy = $1L[gfpidx]", factoryproxyname);
+ code.endControlFlow();
+ code.beginControlFlow("if (null != $1N && $1N.length > gfpidx)", genericfieldname);
+ code.addStatement("gftype = $1L[gfpidx]", genericfieldname);
+ code.nextControlFlow("else");
+ code.addStatement("throw new RetrieveNonVolatileEntityError(\"No Generic Field Type Info.\")");
+ code.endControlFlow();
+ code.addStatement("$1N = new $2T(proxy, gftype, $8L, $9L, $3N, $4N, $5N, $6N.get() + $7L)",
+ dynfieldinfo.name, dynfieldinfo.type,
+ allocname, unsafename, autoreclaimname, holdername, dynfieldinfo.fieldoff,
+ dynfieldinfo.efproxiesname, dynfieldinfo.gftypesname);
+ code.endControlFlow();
+ code.addStatement("return $1N.get()", dynfieldinfo.name);
+ } else {
+ code.beginControlFlow("if (null == $1N)", dynfieldinfo.name);
+ code.addStatement("long phandler = $1N.getAddress($2N.get() + $3L)",
+ unsafename, holdername, dynfieldinfo.fieldoff);
+ code.beginControlFlow("if (0L != phandler)");
+ code.addStatement("$1N = $4N.restore($2N, $5L, $6L, phandler, $3N)",
+ dynfieldinfo.name, allocname, autoreclaimname,
+ String.format("%s%s", m_typeutils.asElement(methodinfo.elem.getReturnType()).getSimpleName(), FACTORYNAMESUFFIX),
+ dynfieldinfo.efproxiesname, dynfieldinfo.gftypesname);
+ code.endControlFlow();
+ code.endControlFlow();
+ code.addStatement("return $1N", dynfieldinfo.name);
+ }
+ }
+ typespecbuilder.addMethod(methodinfo.specbuilder.addCode(code.build()).build());
+ }
+ }
+
+ protected String gsetterName(String name, boolean isget) {
+ return String.format("%s%s", isget ? "get" : "set", name); //Character.toUpperCase(name.charAt(0)) + name.substring(1));
+ }
+
+ protected void buildSettersSpecs(TypeSpec.Builder typespecbuilder) throws AnnotationProcessingException {
+ MethodInfo methodinfo;
+ TypeName ftname, valtname;
+ String unsafename = m_fieldsinfo.get("unsafe").name;
+ String holdername = m_fieldsinfo.get("holder").name;
+ String allocname = m_fieldsinfo.get("allocator").name;
+ String autoreclaimname = m_fieldsinfo.get("autoreclaim").name;
+ String factoryproxyname = m_fieldsinfo.get("factoryproxy").name;
+ String genericfieldname = m_fieldsinfo.get("genericfield").name;
+ FieldInfo dynfieldinfo;
+ CodeBlock.Builder code;
+ VariableElement arg0;
+ VariableElement arg1;
+ String codefmt;
+ for (String name : m_settersinfo.keySet()) {
+ code = CodeBlock.builder();
+ methodinfo = m_settersinfo.get(name);
+ dynfieldinfo = m_dynfieldsinfo.get(name);
+ ftname = m_dynfieldsinfo.get(name).type;
+ valtname = m_gettersinfo.get(name).rettype;
+ arg0 = methodinfo.elem.getParameters().get(0);
+ if (!TypeName.get(arg0.asType()).equals(valtname)) {
+ throw new AnnotationProcessingException(null, "%s has inconsistent value type with its getter/setter.",
+ name);
+ }
+ if (isUnboxPrimitive(ftname)) {
+ if (unboxTypeName(ftname).equals(TypeName.BOOLEAN)) {
+ codefmt = "$1N.$4L($2N.get() + $3L, $5L?1:0)";
+ } else {
+ codefmt = "$1N.$4L($2N.get() + $3L, $5L)";
+ }
+ code.addStatement(codefmt, unsafename, holdername, dynfieldinfo.fieldoff, transTypeToUnsafeMethod(ftname, false), arg0);
+ } else {
+ try {
+ arg1 = methodinfo.elem.getParameters().get(1);
+ if (!TypeName.BOOLEAN.equals(TypeName.get(arg1.asType()))) {
+ throw new AnnotationProcessingException(null, "the second parameter of %s's setter is not boolean type.",
+ name);
+ }
+ } catch (IndexOutOfBoundsException ex) {
+ throw new AnnotationProcessingException(null, "%s's setter has no second parameters for non primitive type.",
+ name);
+ }
+ if(valtname.toString().equals(String.class.getCanonicalName())) {
+ code.beginControlFlow("if ($1L && null != $2L())", arg1, gsetterName(name, true));
+ code.addStatement("$1N.destroy()", dynfieldinfo.name);
+ code.addStatement("$1N = null", dynfieldinfo.name);
+ code.addStatement("$1N.putAddress($2N.get() + $3L, 0L)",
+ unsafename, holdername, dynfieldinfo.fieldoff);
+ code.endControlFlow();
+ code.beginControlFlow("if (null == $1L)", arg0);
+ code.addStatement("$1N.putLong($2N.get() + $3L, 0L)",
+ unsafename, holdername, dynfieldinfo.fieldoff);
+ code.nextControlFlow("else");
+ code.addStatement("$1N = $2N.createBuffer($3L.length() * 2, $4N)",
+ dynfieldinfo.name, allocname, arg0, autoreclaimname);
+ code.beginControlFlow("if (null == $1N)", dynfieldinfo.name);
+ code.addStatement("throw new OutOfPersistentMemory(\"Create Non-Volatile String Error!\")");
+ code.endControlFlow();
+ code.addStatement("$1N.get().asCharBuffer().put($2L)", dynfieldinfo.name, arg0);
+ code.addStatement("$1N.putLong($2N.get() + $3L, $4N.getBufferHandler($5N))",
+ unsafename, holdername, dynfieldinfo.fieldoff, allocname, dynfieldinfo.name);
+ code.endControlFlow();
+ } else if (dynfieldinfo.type.toString().startsWith(GenericField.class.getCanonicalName())) {
+ code.beginControlFlow("if (null == $1N)", dynfieldinfo.name);
+ code.addStatement("$1T proxy = null", TypeName.get(EntityFactoryProxy.class));
+ code.addStatement("$1T gftype = null", TypeName.get(GenericField.GType.class));
+ code.addStatement("int gfpidx = $1L", getFactoryProxyIndex(valtname));
+ code.beginControlFlow("if (null != $1N && $1N.length > gfpidx)", factoryproxyname);
+ code.addStatement("proxy = $1L[gfpidx]", factoryproxyname);
+ code.endControlFlow();
+ code.beginControlFlow("if (null != $1N && $1N.length > gfpidx)", genericfieldname);
+ code.addStatement("gftype = $1L[gfpidx]", genericfieldname);
+ code.nextControlFlow("else");
+ code.addStatement("throw new RetrieveNonVolatileEntityError(\"No Generic Field Type Info.\")");
+ code.endControlFlow();
+ code.addStatement("$1N = new $2T(proxy, gftype, $8L, $9L, $3N, $4N, $5N, $6N.get() + $7L)",
+ dynfieldinfo.name, dynfieldinfo.type,
+ allocname, unsafename, autoreclaimname, holdername, dynfieldinfo.fieldoff,
+ dynfieldinfo.efproxiesname, dynfieldinfo.gftypesname);
+ code.endControlFlow();
+ code.beginControlFlow("if (null != $1L)", dynfieldinfo.name);
+ code.addStatement("$1N.set($2L, $3L)", dynfieldinfo.name, arg0, arg1);
+ code.nextControlFlow("else");
+ code.addStatement("throw new RetrieveNonVolatileEntityError(\"GenericField is null!\")");
+ code.endControlFlow();
+ } else {
+ code.beginControlFlow("if ($1L && null != $2L())", arg1, gsetterName(name, true));
+ code.addStatement("$1N.destroy()", dynfieldinfo.name);
+ code.addStatement("$1N = null", dynfieldinfo.name);
+ code.addStatement("$1N.putAddress($2N.get() + $3L, 0L)",
+ unsafename, holdername, dynfieldinfo.fieldoff);
+ code.endControlFlow();
+ code.addStatement("$1N = $2L", dynfieldinfo.name, arg0);
+ code.addStatement("$1N.putLong($2N.get() + $3L, null == $4N ? 0L : $4N.getNonVolatileHandler())",
+ unsafename, holdername, dynfieldinfo.fieldoff, dynfieldinfo.name);
+ }
+ }
+ typespecbuilder.addMethod(methodinfo.specbuilder.addCode(code.build()).build());
+ }
+ }
+
+ protected void buildDurableMethodSpecs(TypeSpec.Builder typespecbuilder) throws AnnotationProcessingException {
+ MethodInfo methodinfo;
+ CodeBlock.Builder code;
+ FieldInfo dynfieldinfo;
+ String holdername = m_fieldsinfo.get("holder").name;
+ String allocname = m_fieldsinfo.get("allocator").name;
+ String autoreclaimname = m_fieldsinfo.get("autoreclaim").name;
+ for (String name : m_durablemtdinfo.keySet()) {
+ methodinfo = m_durablemtdinfo.get(name);
+ code = CodeBlock.builder();
+ switch(name) {
+ case "cancelAutoReclaim" :
+ code.addStatement("$1N.cancelAutoReclaim()", holdername);
+ for (String fname : m_dynfieldsinfo.keySet()) {
+ dynfieldinfo = m_dynfieldsinfo.get(fname);
+ if (!isUnboxPrimitive(dynfieldinfo.type)) {
+ code.beginControlFlow("if (null != $1N)", dynfieldinfo.name);
+ code.addStatement("$1N.cancelAutoReclaim()", dynfieldinfo.name);
+ code.endControlFlow();
+ }
+ }
+ code.addStatement("$1N = false", autoreclaimname);
+ break;
+ case "registerAutoReclaim" :
+ code.addStatement("$1N.registerAutoReclaim()", holdername);
+ for (String fname : m_dynfieldsinfo.keySet()) {
+ dynfieldinfo = m_dynfieldsinfo.get(fname);
+ if (!isUnboxPrimitive(dynfieldinfo.type)) {
+ code.beginControlFlow("if (null != $1N)", dynfieldinfo.name);
+ code.addStatement("$1N.registerAutoReclaim()", dynfieldinfo.name);
+ code.endControlFlow();
+ }
+ }
+ code.addStatement("$1N = true", autoreclaimname);
+ break;
+ case "getNonVolatileHandler" :
+ code.addStatement("return $1N.getChunkHandler($2N)", allocname, holdername);
+ break;
+ case "autoReclaim" :
+ code.addStatement("return $1N", autoreclaimname);
+ break;
+ case "destroy" :
+ code.addStatement("$1N.destroy()", holdername);
+ for (String fname : m_dynfieldsinfo.keySet()) {
+ dynfieldinfo = m_dynfieldsinfo.get(fname);
+ if (!isUnboxPrimitive(dynfieldinfo.type)) {
+ code.beginControlFlow("if (null != $1N)", dynfieldinfo.name);
+ code.addStatement("$1N.destroy()", dynfieldinfo.name);
+ code.addStatement("$1N = null", dynfieldinfo.name);
+ code.endControlFlow();
+ }
+ }
+ break;
+ case "getNativeFieldInfo" :
+ code.addStatement("return $1N", m_fieldsinfo.get("nfieldinfo").name);
+ break;
+ default:
+ throw new AnnotationProcessingException(null, "Method %s is not supported.",
+ name);
+ }
+ typespecbuilder.addMethod(methodinfo.specbuilder.addCode(code.build()).build());
+ }
+ }
+
+ protected void buildEntityMethodSpecs(TypeSpec.Builder typespecbuilder) throws AnnotationProcessingException {
+ MethodInfo methodinfo;
+ CodeBlock.Builder code;
+ FieldInfo dynfieldinfo;
+ VariableElement arg0, arg1, arg2, arg3, arg4;
+ String unsafename = m_fieldsinfo.get("unsafe").name;
+ String holdername = m_fieldsinfo.get("holder").name;
+ String allocname = m_fieldsinfo.get("allocator").name;
+ String autoreclaimname = m_fieldsinfo.get("autoreclaim").name;
+ String factoryproxyname = m_fieldsinfo.get("factoryproxy").name;
+ String genericfieldname = m_fieldsinfo.get("genericfield").name;
+ for (String name : m_entitymtdinfo.keySet()) {
+ methodinfo = m_entitymtdinfo.get(name);
+ code = CodeBlock.builder();
+ arg0 = methodinfo.elem.getParameters().get(0);
+ arg1 = methodinfo.elem.getParameters().get(1);
+ arg2 = methodinfo.elem.getParameters().get(2);
+ switch(name) {
+ case "initializeNonVolatileEntity" :
+ arg3 = methodinfo.elem.getParameters().get(3);
+ code.addStatement("$1N = $2L", allocname, arg0);
+ code.addStatement("$1N = $2L", factoryproxyname, arg1);
+ code.addStatement("$1N = $2L", genericfieldname, arg2);
+ code.addStatement("$1N = $2L", autoreclaimname, arg3);
+ code.beginControlFlow("try");
+ code.addStatement("$1N = $2T.getUnsafe()", unsafename, Utils.class);
+ code.nextControlFlow("catch (Exception e)");
+ code.addStatement("e.printStackTrace()");
+ code.endControlFlow();
+ break;
+ case "createNonVolatileEntity" :
+ arg3 = methodinfo.elem.getParameters().get(3);
+ code.addStatement("initializeNonVolatileEntity($1L, $2L, $3L, $4L)", arg0, arg1, arg2, arg3);
+ code.addStatement("$1N = $2N.createChunk($3L, $4N)",
+ holdername, allocname, m_holdersize, autoreclaimname);
+ code.beginControlFlow("if (null == $1N)", holdername);
+ code.addStatement("throw new OutOfPersistentMemory(\"Create Non-Volatile Entity Error!\")");
+ code.endControlFlow();
+ // code.beginControlFlow("try");
+ // for (String fname : m_dynfieldsinfo.keySet()) {
+ // dynfieldinfo = m_dynfieldsinfo.get(fname);
+ // if (isUnboxPrimitive(dynfieldinfo.type)) {
+ // code.addStatement("$1N($2L)", gsetterName(fname, false), getIntialValueLiteral(dynfieldinfo.type));
+ // } else {
+ // code.addStatement("$1N(null, false)", gsetterName(fname, false));
+ // }
+ // }
+ // code.nextControlFlow("catch(RetrieveNonVolatileEntityError ex)");
+ // code.endControlFlow();
+ code.addStatement("initializeAfterCreate()");
+ break;
+ case "restoreNonVolatileEntity" :
+ arg3 = methodinfo.elem.getParameters().get(3);
+ arg4 = methodinfo.elem.getParameters().get(4);
+ code.addStatement("initializeNonVolatileEntity($1L, $2L, $3L, $4L)", arg0, arg1, arg2, arg4);
+ code.beginControlFlow("if (0L == $1L)", arg3);
+ code.addStatement("throw new RetrieveNonVolatileEntityError(\"Input handler is null on $1N.\")", name);
+ code.endControlFlow();
+ code.addStatement("$1N = $2N.retrieveChunk($3L, $4N)",
+ holdername, allocname, arg3, autoreclaimname);
+ code.beginControlFlow("if (null == $1N)", holdername);
+ code.addStatement("throw new RetrieveNonVolatileEntityError(\"Retrieve Entity Failure!\")");
+ code.endControlFlow();
+ code.addStatement("initializeAfterRestore()");
+ break;
+ default:
+ throw new AnnotationProcessingException(null, "Method %s is not supported.",
+ name);
+ }
+ typespecbuilder.addMethod(methodinfo.specbuilder.addCode(code.build()).build());
+ }
+ }
+
+ protected void buildFieldSpecs(TypeSpec.Builder typespecbuilder, Map<String, FieldInfo> fieldinfos) {
+ FieldInfo fieldinfo;
+ for (String name : fieldinfos.keySet()) {
+ fieldinfo = fieldinfos.get(name);
+ if (null != fieldinfo.specbuilder) {
+ typespecbuilder.addField(fieldinfo.specbuilder.build());
+ }
+ }
+ }
+
+ protected void buildFactoryMethodSpecs(TypeSpec entityspec, TypeSpec.Builder typespecbuilder) throws AnnotationProcessingException {
+ MethodSpec methodspec;
+ CodeBlock code;
+
+ TypeName entitytn= ParameterizedTypeName.get(ClassName.get(m_packagename, m_entityname), entityspec.typeVariables.toArray(new TypeVariableName[0]));
+
+ ParameterSpec allocparam = ParameterSpec.builder(m_alloctypename, "allocator").build();
+ code = CodeBlock.builder()
+ .addStatement("return create($1L, false)", allocparam.name)
+ .build();
+ methodspec = MethodSpec.methodBuilder("create")
+ .addTypeVariables(entityspec.typeVariables)
+ .addException(OutOfPersistentMemory.class)
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+ .returns(TypeName.get(m_elem.asType()))
+ .addParameter(allocparam)
+ .addCode(code).build();
+ typespecbuilder.addMethod(methodspec);
+
+ ParameterSpec autoreclaimparam = ParameterSpec.builder(TypeName.BOOLEAN, "autoreclaim").build();
+ code = CodeBlock.builder()
+ .addStatement("return create($1L, null, null, $2L)", allocparam.name, autoreclaimparam.name)
+ .build();
+ methodspec = MethodSpec.methodBuilder("create")
+ .addTypeVariables(entityspec.typeVariables)
+ .addException(OutOfPersistentMemory.class)
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+ .returns(TypeName.get(m_elem.asType()))
+ .addParameter(allocparam)
+ .addParameter(autoreclaimparam)
+ .addCode(code).build();
+ typespecbuilder.addMethod(methodspec);
+
+ ParameterSpec factoryproxysparam = ParameterSpec.builder(m_factoryproxystypename, "factoryproxys").build();
+ ParameterSpec gfieldsparam = ParameterSpec.builder(m_gfieldstypename, "gfields").build();
+ code = CodeBlock.builder()
+ .addStatement("$1T entity = new $1T()", entitytn)
+ .addStatement("entity.setupGenericInfo($1N, $2N)", factoryproxysparam.name, gfieldsparam.name)
+ .addStatement("entity.createNonVolatileEntity($1L, $2L, $3L, $4L)",
+ allocparam.name, factoryproxysparam.name, gfieldsparam.name, autoreclaimparam.name)
+ .addStatement("return entity")
+ .build();
+ methodspec = MethodSpec.methodBuilder("create")
+ .addTypeVariables(entityspec.typeVariables)
+ .addException(OutOfPersistentMemory.class)
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+ .returns(TypeName.get(m_elem.asType()))
+ .addParameter(allocparam)
+ .addParameter(factoryproxysparam)
+ .addParameter(gfieldsparam)
+ .addParameter(autoreclaimparam)
+ .addCode(code).build();
+ typespecbuilder.addMethod(methodspec);
+
+ ParameterSpec phandlerparam = ParameterSpec.builder(TypeName.LONG, "phandler").build();
+ code = CodeBlock.builder()
+ .addStatement("return restore($1L, $2L, false)", allocparam.name, phandlerparam.name)
+ .build();
+ methodspec = MethodSpec.methodBuilder("restore")
+ .addTypeVariables(entityspec.typeVariables)
+ .addException(RetrieveNonVolatileEntityError.class)
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+ .returns(TypeName.get(m_elem.asType()))
+ .addParameter(allocparam)
+ .addParameter(phandlerparam)
+ .addCode(code).build();
+ typespecbuilder.addMethod(methodspec);
+
+ code = CodeBlock.builder()
+ .addStatement("return restore($1L, null, null, $2L, $3L)", allocparam.name, phandlerparam.name, autoreclaimparam.name)
+ .build();
+ methodspec = MethodSpec.methodBuilder("restore")
+ .addTypeVariables(entityspec.typeVariables)
+ .addException(RetrieveNonVolatileEntityError.class)
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+ .returns(TypeName.get(m_elem.asType()))
+ .addParameter(allocparam)
+ .addParameter(phandlerparam)
+ .addParameter(autoreclaimparam)
+ .addCode(code).build();
+ typespecbuilder.addMethod(methodspec);
+
+ code = CodeBlock.builder()
+ .addStatement("$1T entity = new $1T()", entitytn)
+ .addStatement("entity.setupGenericInfo($1N, $2N)", factoryproxysparam.name, gfieldsparam.name)
+ .addStatement("entity.restoreNonVolatileEntity($1L, $2L, $3L, $4L, $5L)",
+ allocparam.name, factoryproxysparam.name, gfieldsparam.name, phandlerparam.name, autoreclaimparam.name)
+ .addStatement("return entity")
+ .build();
+ methodspec = MethodSpec.methodBuilder("restore")
+ .addTypeVariables(entityspec.typeVariables)
+ .addException(RetrieveNonVolatileEntityError.class)
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+ .returns(TypeName.get(m_elem.asType()))
+ .addParameter(allocparam)
+ .addParameter(factoryproxysparam)
+ .addParameter(gfieldsparam)
+ .addParameter(phandlerparam)
+ .addParameter(autoreclaimparam)
+ .addCode(code).build();
+ typespecbuilder.addMethod(methodspec);
+ }
+
+ public void generateCode(Filer filer) throws IOException, AnnotationProcessingException {
+ AnnotationSpec classannotation = AnnotationSpec.builder(SuppressWarnings.class)
+ .addMember("value", "$S", "restriction").build();
+
+ TypeSpec.Builder entitybuilder = TypeSpec.classBuilder(m_entityname)
+ .superclass(TypeName.get(m_elem.asType()))
+ .addModifiers(Modifier.PUBLIC).addAnnotation(classannotation)
+ .addSuperinterface(
+ ParameterizedTypeName.get(ClassName.get(MemoryNonVolatileEntity.class), m_alloctypevarname))
+ .addTypeVariable(m_alloctypevarname);
+
+ for (TypeParameterElement tpe : m_elem.getTypeParameters()) {
+ entitybuilder.addTypeVariable(TypeVariableName.get(tpe));
+ }
+
+ buildFieldSpecs(entitybuilder, m_dynfieldsinfo);
+ buildFieldSpecs(entitybuilder, m_fieldsinfo);
+
+ buildGettersSpecs(entitybuilder);
+ buildSettersSpecs(entitybuilder);
+
+ buildDurableMethodSpecs(entitybuilder);
+ buildEntityMethodSpecs(entitybuilder);
+
+ TypeSpec entityspec = entitybuilder.build();
+
+ JavaFile entityFile = JavaFile
+ .builder(m_packagename, entityspec).build();
+
+ entityFile.writeTo(filer);
+
+ TypeSpec.Builder factorybuilder = TypeSpec.classBuilder(m_factoryname)
+ .addModifiers(Modifier.PUBLIC);
+
+ buildFactoryMethodSpecs(entityspec, factorybuilder);
+
+ JavaFile factoryFile = JavaFile
+ .builder(m_packagename, factorybuilder.build()).build();
+
+ factoryFile.writeTo(filer);
+
+ }
+
+ public static Builder overriding(ExecutableElement method, String varname) {
+
+ Set<Modifier> modifiers = method.getModifiers();
+ if (modifiers.contains(Modifier.PRIVATE) || modifiers.contains(Modifier.FINAL)
+ || modifiers.contains(Modifier.STATIC)) {
+ throw new IllegalArgumentException("cannot override method with modifiers: " + modifiers);
+ }
+
+ String methodName = method.getSimpleName().toString();
+ MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(methodName);
+
+ methodBuilder.addAnnotation(Override.class);
+ for (AnnotationMirror mirror : method.getAnnotationMirrors()) {
+ AnnotationSpec annotationSpec = AnnotationSpec.get(mirror);
+ if (annotationSpec.type.equals(Override.class))
+ continue;
+ methodBuilder.addAnnotation(annotationSpec);
+ }
+
+ modifiers = new LinkedHashSet<>(modifiers);
+ modifiers.remove(Modifier.ABSTRACT);
+ methodBuilder.addModifiers(modifiers);
+
+ for (TypeParameterElement typeParameterElement : method.getTypeParameters()) {
+ TypeVariable var = (TypeVariable) typeParameterElement.asType();
+ methodBuilder.addTypeVariable(TypeVariableName.get(var));
+ }
+
+ methodBuilder.returns(TypeName.get(method.getReturnType()));
+
+ List<? extends VariableElement> parameters = method.getParameters();
+ TypeName type;
+ for (VariableElement parameter : parameters) {
+ if (parameter.asType().getKind() == TypeKind.TYPEVAR && parameter.asType().toString().equals(varname)) {
+ type = TypeVariableName.get(varname);
+ } else {
+ type = TypeName.get(parameter.asType());
+ }
+
+ String name = parameter.getSimpleName().toString();
+ Set<Modifier> parameterModifiers = parameter.getModifiers();
+ ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(type, name)
+ .addModifiers(parameterModifiers.toArray(new Modifier[parameterModifiers.size()]));
+ for (AnnotationMirror mirror : parameter.getAnnotationMirrors()) {
+ parameterBuilder.addAnnotation(AnnotationSpec.get(mirror));
+ }
+ methodBuilder.addParameter(parameterBuilder.build());
+ }
+ methodBuilder.varargs(method.isVarArgs());
+
+ for (TypeMirror thrownType : method.getThrownTypes()) {
+ methodBuilder.addException(TypeName.get(thrownType));
+ }
+
+ return methodBuilder;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/8e83efe5/core/src/main/java/org/apache/mnemonic/AnnotationProcessingException.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/mnemonic/AnnotationProcessingException.java b/core/src/main/java/org/apache/mnemonic/AnnotationProcessingException.java
new file mode 100644
index 0000000..83b42fe
--- /dev/null
+++ b/core/src/main/java/org/apache/mnemonic/AnnotationProcessingException.java
@@ -0,0 +1,23 @@
+package org.apache.mnemonic;
+
+import javax.lang.model.element.Element;
+
+/**
+ * this exception is used for non-volatile annotation processing
+ *
+ */
+public class AnnotationProcessingException extends Exception {
+
+ private static final long serialVersionUID = 6911141027622831646L;
+
+ private Element element;
+
+ public AnnotationProcessingException(Element element, String msg, Object... args) {
+ super(String.format(msg, args));
+ this.element = element;
+ }
+
+ public Element getElement() {
+ return element;
+ }
+}