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/05/06 00:41:03 UTC
[05/13] incubator-mnemonic git commit: MNEMONIC-40 - Clean up
assembled source package for release MNEMONIC-41 - Create a script for
preparing a release of a single package with signing and hashing MNEMONIC-42
- Normalize the names of project submodules
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/30836536/mnemonic-collections/src/test/java/org/apache/mnemonic/collections/DurableNodeValueNGTest.java
----------------------------------------------------------------------
diff --git a/mnemonic-collections/src/test/java/org/apache/mnemonic/collections/DurableNodeValueNGTest.java b/mnemonic-collections/src/test/java/org/apache/mnemonic/collections/DurableNodeValueNGTest.java
new file mode 100644
index 0000000..0cc0095
--- /dev/null
+++ b/mnemonic-collections/src/test/java/org/apache/mnemonic/collections/DurableNodeValueNGTest.java
@@ -0,0 +1,274 @@
+/*
+ * 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.collections;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Random;
+
+import org.apache.mnemonic.NonVolatileMemAllocator;
+import org.apache.mnemonic.CommonDurableAllocator;
+import org.apache.mnemonic.Durable;
+import org.apache.mnemonic.EntityFactoryProxy;
+import org.apache.mnemonic.GenericField;
+import org.apache.mnemonic.Reclaim;
+import org.apache.mnemonic.Utils;
+import org.testng.AssertJUnit;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ *
+ *
+ */
+
+public class DurableNodeValueNGTest {
+ private long cKEYCAPACITY;
+ private Random m_rand;
+ private NonVolatileMemAllocator m_act;
+
+ @BeforeClass
+ public void setUp() {
+ m_rand = Utils.createRandom();
+ m_act = new NonVolatileMemAllocator(Utils.getNonVolatileMemoryAllocatorService("pmalloc"), 1024 * 1024 * 1024,
+ "./pobj_NodeValue.dat", true);
+ cKEYCAPACITY = m_act.handlerCapacity();
+ m_act.setBufferReclaimer(new Reclaim<ByteBuffer>() {
+ @Override
+ public boolean reclaim(ByteBuffer mres, Long sz) {
+ System.out.println(String.format("Reclaim Memory Buffer: %X Size: %s", System.identityHashCode(mres),
+ null == sz ? "NULL" : sz.toString()));
+ return false;
+ }
+ });
+ m_act.setChunkReclaimer(new Reclaim<Long>() {
+ @Override
+ public boolean reclaim(Long mres, Long sz) {
+ System.out.println(String.format("Reclaim Memory Chunk: %X Size: %s", System.identityHashCode(mres),
+ null == sz ? "NULL" : sz.toString()));
+ return false;
+ }
+ });
+
+ for (long i = 0; i < cKEYCAPACITY; ++i) {
+ m_act.setHandler(i, 0L);
+ }
+ }
+
+ @AfterClass
+ public void tearDown() {
+ m_act.close();
+ }
+
+ @Test(enabled = false)
+ public void testSingleNodeValueWithInteger() {
+ int val = m_rand.nextInt();
+ GenericField.GType gtypes[] = {GenericField.GType.INTEGER};
+ DurableNodeValue<Integer> plln = DurableNodeValueFactory.create(m_act, null, gtypes, false);
+ plln.setItem(val, false);
+ Long handler = plln.getHandler();
+ System.err.println("-------------Start to Restore Integer -----------");
+ DurableNodeValue<Integer> plln2 = DurableNodeValueFactory.restore(m_act, null, gtypes, handler, false);
+ AssertJUnit.assertEquals(val, (int) plln2.getItem());
+ }
+
+ @Test(enabled = false)
+ public void testNodeValueWithString() {
+ String val = Utils.genRandomString();
+ GenericField.GType gtypes[] = {GenericField.GType.STRING};
+ DurableNodeValue<String> plln = DurableNodeValueFactory.create(m_act, null, gtypes, false);
+ plln.setItem(val, false);
+ Long handler = plln.getHandler();
+ System.err.println("-------------Start to Restore String-----------");
+ DurableNodeValue<String> plln2 = DurableNodeValueFactory.restore(m_act, null, gtypes, handler, false);
+ AssertJUnit.assertEquals(val, plln2.getItem());
+ }
+
+ @Test(enabled = false)
+ public void testNodeValueWithPerson() {
+
+ Person<Long> person = PersonFactory.create(m_act);
+ person.setAge((short) 31);
+
+ GenericField.GType gtypes[] = {GenericField.GType.DURABLE};
+ EntityFactoryProxy efproxies[] = {new EntityFactoryProxy() {
+ @Override
+ public <A extends CommonDurableAllocator<A>> Durable restore(A allocator, EntityFactoryProxy[] factoryproxys,
+ GenericField.GType[] gfields, long phandler, boolean autoreclaim) {
+ return PersonFactory.restore(allocator, factoryproxys, gfields, phandler, autoreclaim);
+ }
+ } };
+
+ DurableNodeValue<Person<Long>> plln = DurableNodeValueFactory.create(m_act, efproxies, gtypes, false);
+ plln.setItem(person, false);
+ Long handler = plln.getHandler();
+
+ DurableNodeValue<Person<Long>> plln2 = DurableNodeValueFactory.restore(m_act, efproxies, gtypes, handler,
+ false);
+ AssertJUnit.assertEquals(31, (int) plln2.getItem().getAge());
+
+ }
+
+ @Test(enabled = false)
+ public void testLinkedNodeValueWithPerson() {
+
+ int elem_count = 10;
+ List<Long> referlist = new ArrayList();
+
+ GenericField.GType listgftypes[] = {GenericField.GType.DURABLE};
+ EntityFactoryProxy listefproxies[] = {new EntityFactoryProxy() {
+ @Override
+ public <A extends CommonDurableAllocator<A>> Durable restore(A allocator, EntityFactoryProxy[] factoryproxys,
+ GenericField.GType[] gfields, long phandler, boolean autoreclaim) {
+ return PersonFactory.restore(allocator, factoryproxys, gfields, phandler, autoreclaim);
+ }
+ } };
+
+ DurableNodeValue<Person<Long>> firstnv = DurableNodeValueFactory.create(m_act, listefproxies, listgftypes,
+ false);
+
+ DurableNodeValue<Person<Long>> nextnv = firstnv;
+
+ Person<Long> person;
+ long val;
+ DurableNodeValue<Person<Long>> newnv;
+ for (int i = 0; i < elem_count; ++i) {
+ person = PersonFactory.create(m_act);
+ person.setAge((short) m_rand.nextInt(50));
+ person.setName(String.format("Name: [%s]", Utils.genRandomString()), true);
+ nextnv.setItem(person, false);
+ newnv = DurableNodeValueFactory.create(m_act, listefproxies, listgftypes, false);
+ nextnv.setNext(newnv, false);
+ nextnv = newnv;
+ }
+
+ Person<Long> eval;
+ DurableNodeValue<Person<Long>> iternv = firstnv;
+ while (null != iternv) {
+ System.out.printf(" Stage 1 --->\n");
+ eval = iternv.getItem();
+ if (null != eval) {
+ eval.testOutput();
+ }
+ iternv = iternv.getNext();
+ }
+
+ long handler = firstnv.getHandler();
+
+ DurableNodeValue<Person<Long>> firstnv2 = DurableNodeValueFactory.restore(m_act, listefproxies, listgftypes,
+ handler, false);
+
+ for (Person<Long> eval2 : firstnv2) {
+ System.out.printf(" Stage 2 ---> \n");
+ if (null != eval2) {
+ eval2.testOutput();
+ }
+ }
+
+ // Assert.assert, expected);(plist, plist2);
+
+ }
+
+ @Test(enabled = true)
+ public void testLinkedNodeValueWithLinkedNodeValue() {
+
+ int elem_count = 10;
+ long slotKeyId = 10;
+
+ GenericField.GType[] elem_gftypes = {GenericField.GType.DOUBLE};
+ EntityFactoryProxy[] elem_efproxies = null;
+
+ GenericField.GType linkedgftypes[] = {GenericField.GType.DURABLE, GenericField.GType.DOUBLE};
+ EntityFactoryProxy linkedefproxies[] = {new EntityFactoryProxy() {
+ @Override
+ public <A extends CommonDurableAllocator<A>> Durable restore(A allocator, EntityFactoryProxy[] factoryproxys,
+ GenericField.GType[] gfields, long phandler, boolean autoreclaim) {
+ EntityFactoryProxy[] val_efproxies = null;
+ GenericField.GType[] val_gftypes = null;
+ if (null != factoryproxys && factoryproxys.length >= 2) {
+ val_efproxies = Arrays.copyOfRange(factoryproxys, 1, factoryproxys.length);
+ }
+ if (null != gfields && gfields.length >= 2) {
+ val_gftypes = Arrays.copyOfRange(gfields, 1, gfields.length);
+ }
+ return DurableNodeValueFactory.restore(allocator, val_efproxies, val_gftypes, phandler, autoreclaim);
+ }
+ } };
+
+ DurableNodeValue<DurableNodeValue<Double>> nextnv = null, pre_nextnv = null;
+ DurableNodeValue<Double> elem = null, pre_elem = null, first_elem = null;
+
+ Long linkhandler = 0L;
+
+ System.out.printf(" Stage 1 -testLinkedNodeValueWithLinkedNodeValue--> \n");
+
+ pre_nextnv = null;
+ Double val;
+ for (int i = 0; i < elem_count; ++i) {
+ first_elem = null;
+ pre_elem = null;
+ for (int v = 0; v < 3; ++v) {
+ elem = DurableNodeValueFactory.create(m_act, elem_efproxies, elem_gftypes, false);
+ val = m_rand.nextDouble();
+ elem.setItem(val, false);
+ if (null == pre_elem) {
+ first_elem = elem;
+ } else {
+ pre_elem.setNext(elem, false);
+ }
+ pre_elem = elem;
+ System.out.printf("%f ", val);
+ }
+
+ nextnv = DurableNodeValueFactory.create(m_act, linkedefproxies, linkedgftypes, false);
+ nextnv.setItem(first_elem, false);
+ if (null == pre_nextnv) {
+ linkhandler = nextnv.getHandler();
+ } else {
+ pre_nextnv.setNext(nextnv, false);
+ }
+ pre_nextnv = nextnv;
+ System.out.printf(" generated an item... \n");
+ }
+ m_act.setHandler(slotKeyId, linkhandler);
+
+ long handler = m_act.getHandler(slotKeyId);
+
+ DurableNodeValue<DurableNodeValue<Double>> linkedvals = DurableNodeValueFactory.restore(m_act,
+ linkedefproxies, linkedgftypes, handler, false);
+ Iterator<DurableNodeValue<Double>> iter = linkedvals.iterator();
+ Iterator<Double> elemiter = null;
+
+ System.out.printf(" Stage 2 -testLinkedNodeValueWithLinkedNodeValue--> \n");
+ while (iter.hasNext()) {
+ elemiter = iter.next().iterator();
+ while (elemiter.hasNext()) {
+ System.out.printf("%f ", elemiter.next());
+ }
+ System.out.printf(" Fetched an item... \n");
+ }
+
+ // Assert.assert, expected);(plist, plist2);
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/30836536/mnemonic-collections/src/test/java/org/apache/mnemonic/collections/DurablePersonNGTest.java
----------------------------------------------------------------------
diff --git a/mnemonic-collections/src/test/java/org/apache/mnemonic/collections/DurablePersonNGTest.java b/mnemonic-collections/src/test/java/org/apache/mnemonic/collections/DurablePersonNGTest.java
new file mode 100644
index 0000000..7694b6d
--- /dev/null
+++ b/mnemonic-collections/src/test/java/org/apache/mnemonic/collections/DurablePersonNGTest.java
@@ -0,0 +1,148 @@
+/*
+ * 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.collections;
+
+import org.apache.mnemonic.NonVolatileMemAllocator;
+import org.apache.mnemonic.OutOfHybridMemory;
+import org.apache.mnemonic.Reclaim;
+import org.apache.mnemonic.RetrieveDurableEntityError;
+import org.apache.mnemonic.Utils;
+import org.testng.annotations.Test;
+import java.nio.ByteBuffer;
+import java.util.Random;
+import java.util.UUID;
+
+/**
+ *
+ *
+ */
+
+public class DurablePersonNGTest {
+ private long cKEYCAPACITY;
+
+ @Test(expectedExceptions = { OutOfHybridMemory.class })
+ public void testGenPeople() throws OutOfHybridMemory, RetrieveDurableEntityError {
+ Random rand = Utils.createRandom();
+ NonVolatileMemAllocator act = new NonVolatileMemAllocator(Utils.getNonVolatileMemoryAllocatorService("pmalloc"),
+ 1024 * 1024 * 8, "./pobj_person.dat", true);
+ cKEYCAPACITY = act.handlerCapacity();
+ act.setBufferReclaimer(new Reclaim<ByteBuffer>() {
+ @Override
+ public boolean reclaim(ByteBuffer mres, Long sz) {
+ System.out.println(String.format("Reclaim Memory Buffer: %X Size: %s", System.identityHashCode(mres),
+ null == sz ? "NULL" : sz.toString()));
+ return false;
+ }
+ });
+ act.setChunkReclaimer(new Reclaim<Long>() {
+ @Override
+ public boolean reclaim(Long mres, Long sz) {
+ System.out.println(String.format("Reclaim Memory Chunk: %X Size: %s", System.identityHashCode(mres),
+ null == sz ? "NULL" : sz.toString()));
+ return false;
+ }
+ });
+
+ for (long i = 0; i < cKEYCAPACITY; ++i) {
+ act.setHandler(i, 0L);
+ }
+
+ Person<Integer> mother;
+ Person<Integer> person;
+
+ long keyidx = 0;
+ long val;
+
+ try {
+ while (true) {
+ // if (keyidx >= KEYCAPACITY) break;
+
+ keyidx %= cKEYCAPACITY;
+
+ System.out.printf("************ Generating People on Key %d ***********\n", keyidx);
+
+ val = act.getHandler(keyidx);
+ if (0L != val) {
+ PersonFactory.restore(act, val, true);
+ }
+
+ person = PersonFactory.create(act);
+ person.setAge((short) rand.nextInt(50));
+ person.setName(String.format("Name: [%s]", UUID.randomUUID().toString()), true);
+ person.setName(String.format("Name: [%s]", UUID.randomUUID().toString()), true);
+ person.setName(String.format("Name: [%s]", UUID.randomUUID().toString()), true);
+ person.setName(String.format("Name: [%s]", UUID.randomUUID().toString()), true);
+
+ act.setHandler(keyidx, person.getHandler());
+
+ for (int deep = 0; deep < rand.nextInt(100); ++deep) {
+
+ mother = PersonFactory.create(act);
+ mother.setAge((short) (50 + rand.nextInt(50)));
+ mother.setName(String.format("Name: [%s]", UUID.randomUUID().toString()), true);
+
+ person.setMother(mother, true);
+
+ person = mother;
+
+ }
+ ++keyidx;
+ }
+ } finally {
+ act.close();
+ }
+ }
+
+ @Test(dependsOnMethods = { "testGenPeople" })
+ public void testCheckPeople() throws RetrieveDurableEntityError {
+ NonVolatileMemAllocator act = new NonVolatileMemAllocator(Utils.getNonVolatileMemoryAllocatorService("pmalloc"),
+ 1024 * 1024 * 8, "./pobj_person.dat", true);
+ act.setBufferReclaimer(new Reclaim<ByteBuffer>() {
+ @Override
+ public boolean reclaim(ByteBuffer mres, Long sz) {
+ System.out.println(String.format("Reclaim Memory Buffer: %X Size: %s", System.identityHashCode(mres),
+ null == sz ? "NULL" : sz.toString()));
+ return false;
+ }
+ });
+ act.setChunkReclaimer(new Reclaim<Long>() {
+ @Override
+ public boolean reclaim(Long mres, Long sz) {
+ System.out.println(String.format("Reclaim Memory Chunk: %X Size: %s", System.identityHashCode(mres),
+ null == sz ? "NULL" : sz.toString()));
+ return false;
+ }
+ });
+
+ long val;
+ for (long i = 0; i < cKEYCAPACITY; ++i) {
+ System.out.printf("----------Key %d--------------\n", i);
+ val = act.getHandler(i);
+ if (0L == val) {
+ break;
+ }
+ Person<Integer> person = PersonFactory.restore(act, val, true);
+ while (null != person) {
+ person.testOutput();
+ person = person.getMother();
+ }
+ }
+
+ act.close();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/30836536/mnemonic-collections/src/test/java/org/apache/mnemonic/collections/Payload.java
----------------------------------------------------------------------
diff --git a/mnemonic-collections/src/test/java/org/apache/mnemonic/collections/Payload.java b/mnemonic-collections/src/test/java/org/apache/mnemonic/collections/Payload.java
new file mode 100644
index 0000000..a6f6518
--- /dev/null
+++ b/mnemonic-collections/src/test/java/org/apache/mnemonic/collections/Payload.java
@@ -0,0 +1,44 @@
+/*
+ * 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.collections;
+
+/**
+ * a dummy object that is used for other test cases.
+ *
+ *
+ *
+ */
+public class Payload implements java.io.Serializable, Comparable<Payload> {
+
+ private static final long serialVersionUID = 187397440699436500L;
+
+ public Payload(int iv, String strv, double dv) {
+ ival = iv;
+ strval = strv;
+ dval = dv;
+ }
+
+ public int ival;
+ public String strval;
+ public double dval;
+
+ @Override
+ public int compareTo(Payload pl) {
+ return ival == pl.ival && strval.equals(pl.strval) && dval == pl.dval ? 0 : 1;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/30836536/mnemonic-collections/src/test/java/org/apache/mnemonic/collections/Person.java
----------------------------------------------------------------------
diff --git a/mnemonic-collections/src/test/java/org/apache/mnemonic/collections/Person.java b/mnemonic-collections/src/test/java/org/apache/mnemonic/collections/Person.java
new file mode 100644
index 0000000..5210847
--- /dev/null
+++ b/mnemonic-collections/src/test/java/org/apache/mnemonic/collections/Person.java
@@ -0,0 +1,95 @@
+/*
+ * 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.collections;
+
+import org.apache.mnemonic.Durable;
+import org.apache.mnemonic.EntityFactoryProxy;
+import org.apache.mnemonic.GenericField;
+import org.apache.mnemonic.DurableEntity;
+import org.apache.mnemonic.DurableGetter;
+import org.apache.mnemonic.DurableSetter;
+import org.apache.mnemonic.OutOfHybridMemory;
+import org.apache.mnemonic.RetrieveDurableEntityError;
+import org.testng.annotations.Test;
+
+/**
+ *
+ *
+ */
+
+@DurableEntity
+public abstract class Person<E> implements Durable, Comparable<Person<E>> {
+ E element;
+
+ @Override
+ public void initializeAfterCreate() {
+ System.out.println("Initializing After Created");
+ }
+
+ @Override
+ public void initializeAfterRestore() {
+ System.out.println("Initializing After Restored");
+ }
+
+ @Override
+ public void setupGenericInfo(EntityFactoryProxy[] efproxies, GenericField.GType[] gftypes) {
+
+ }
+
+ @Test
+ public void testOutput() throws RetrieveDurableEntityError {
+ System.out.printf("Person %s, Age: %d ( %s ) \n", getName(), getAge(),
+ null == getMother() ? "No Recorded Mother" : "Has Recorded Mother");
+ }
+
+ public int compareTo(Person<E> anotherPerson) {
+ int ret = 0;
+ if (0 == ret) {
+ ret = getAge().compareTo(anotherPerson.getAge());
+ }
+ if (0 == ret) {
+ ret = getName().compareTo(anotherPerson.getName());
+ }
+ return ret;
+ }
+
+ @DurableGetter(Id = 1L)
+ public abstract Short getAge();
+
+ @DurableSetter
+ public abstract void setAge(Short age);
+
+ @DurableGetter(Id = 2L)
+ public abstract String getName() throws RetrieveDurableEntityError;
+
+ @DurableSetter
+ public abstract void setName(String name, boolean destroy)
+ throws OutOfHybridMemory, RetrieveDurableEntityError;
+
+ @DurableGetter(Id = 3L)
+ public abstract Person<E> getMother() throws RetrieveDurableEntityError;
+
+ @DurableSetter
+ public abstract void setMother(Person<E> mother, boolean destroy) throws RetrieveDurableEntityError;
+
+ @DurableGetter(Id = 4L)
+ public abstract Person<E> getFather() throws RetrieveDurableEntityError;
+
+ @DurableSetter
+ public abstract void setFather(Person<E> mother, boolean destroy) throws RetrieveDurableEntityError;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/30836536/mnemonic-collections/src/test/resources/testng.xml
----------------------------------------------------------------------
diff --git a/mnemonic-collections/src/test/resources/testng.xml b/mnemonic-collections/src/test/resources/testng.xml
new file mode 100644
index 0000000..eb82560
--- /dev/null
+++ b/mnemonic-collections/src/test/resources/testng.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<suite name="Suite" verbose="1" parallel="tests" thread-count="1">
+ <test name="Test">
+ <classes>
+ <class name="org.apache.mnemonic.collections.DurableNodeValueNGTest"/>
+ </classes>
+ </test> <!-- Test -->
+</suite> <!-- Suite -->
+
+
+<!--
+ <class name="org.apache.mnemonic.collections.Person"/>
+ <class name="org.apache.mnemonic.collections.DurablePersonNGTest"/>
+ <class name="org.apache.mnemonic.collections.DurableListNGTest"/>
+ <class name="org.apache.mnemonic.collections.DurableNodeValueNGTest"/>
+ -->
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/30836536/mnemonic-core/pom.xml
----------------------------------------------------------------------
diff --git a/mnemonic-core/pom.xml b/mnemonic-core/pom.xml
new file mode 100644
index 0000000..79afda9
--- /dev/null
+++ b/mnemonic-core/pom.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.mnemonic</groupId>
+ <artifactId>mnemonic-parent</artifactId>
+ <version>0.1.2-incubating-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>mnemonic-core</artifactId>
+ <name>mnemonic-core</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.flowcomputing.commons</groupId>
+ <artifactId>commons-resgc</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.flowcomputing.commons</groupId>
+ <artifactId>commons-primitives</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.squareup</groupId>
+ <artifactId>javapoet</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.bsc.maven</groupId>
+ <artifactId>maven-processor-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>process-test</id>
+ <goals><goal>process-test</goal></goals>
+ <phase>generate-test-sources</phase>
+ <configuration>
+ <compilerArguments>-XDenableSunApiLintControl</compilerArguments>
+ <processors>
+ <processor>${project.groupId}.DurableEntityProcessor</processor>
+ </processors>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <transformers>
+ </transformers>
+ <minimizeJar>true</minimizeJar>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>proguard</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>com.github.wvengen</groupId>
+ <artifactId>proguard-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals><goal>proguard</goal></goals>
+ </execution>
+ </executions>
+ <configuration>
+ <maxMemory>4096m</maxMemory>
+ <proguardInclude>${basedir}/proguard.conf</proguardInclude>
+ <libs>
+ <lib>${java.home}/lib/rt.jar</lib>
+ </libs>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>doc</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <aggregate>true</aggregate>
+ <show>public</show>
+ <nohelp>true</nohelp>
+ <header>Mnenomic-core, ${project.version}</header>
+ <footer>Mnenomic-core, ${project.version}</footer>
+ <doctitle>Mnenomic-core, ${project.version}</doctitle>
+ <links>
+ <link>http://static.springsource.org/spring/docs/3.0.x/javadoc-api/</link>
+ <additionalparam>-Xdoclint:all -Xdoclint:-missing</additionalparam>
+ </links>
+ </configuration>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>test</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <argLine>-Xmx2g -XX:MaxPermSize=1g</argLine>
+ <suiteXmlFiles>
+ <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
+ </suiteXmlFiles>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+</project>
+
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/30836536/mnemonic-core/proguard.conf
----------------------------------------------------------------------
diff --git a/mnemonic-core/proguard.conf b/mnemonic-core/proguard.conf
new file mode 100644
index 0000000..889adc6
--- /dev/null
+++ b/mnemonic-core/proguard.conf
@@ -0,0 +1,91 @@
+-dontshrink
+-dontoptimize
+
+-keepattributes Signature
+-renamesourcefileattribute SourceFile
+-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
+ SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
+
+-keepclasseswithmembers class com.intel.bigdatamem.* {
+ *** <init>(...);
+}
+
+-keep class com.intel.bigdatamem.GenericField* {
+ public <methods>;
+}
+
+-keepclassmembers,allowoptimization enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+-keepclassmembernames class * {
+ java.lang.Class class$(java.lang.String);
+ java.lang.Class class$(java.lang.String, boolean);
+}
+
+-keep class org.flowcomputing.commons.resgc.ResHolder {
+ public <methods>;
+}
+
+-keepclasseswithmembers class com.intel.bigdatamem.ByteBufferBacked* {
+ public <methods>;
+}
+
+-keepclasseswithmembers class ** extends javax.annotation.processing.AbstractProcessor {
+ public <methods>;
+}
+
+-keepclasseswithmembers class ** extends java.lang.RuntimeException {
+ public <methods>;
+}
+
+-keepclasseswithmembers class ** extends java.lang.Exception {
+ public <methods>;
+}
+
+-keepclasseswithmembers class ** extends com.intel.bigdatamem.Reclaim {
+ public <methods>;
+}
+
+-keep public class com.intel.bigdatamem.CachePool* {
+ public *;
+}
+
+-keep public class com.intel.bigdatamem.MemClustering* {
+ public *;
+}
+
+-keep public interface ** {
+ public <methods>;
+}
+
+-keep public enum ** {
+ *;
+}
+
+-keep class ** extends com.intel.bigdatamem.CommonAllocator {
+ public <methods>;
+}
+
+-keep class ** extends com.intel.bigdatamem.MemHolder {
+ public <methods>;
+}
+
+-keep class com.intel.bigdatamem.Utils {
+ public <methods>;
+ public final <fields>;
+}
+
+-keep @NonVolatileEntity class * {
+ public <methods>;
+}
+
+-keep public @interface ** {
+ *;
+}
+
+-keepclasseswithmembers class * {
+ native <methods>;
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/30836536/mnemonic-core/src/main/assembly/assembly.xml
----------------------------------------------------------------------
diff --git a/mnemonic-core/src/main/assembly/assembly.xml b/mnemonic-core/src/main/assembly/assembly.xml
new file mode 100644
index 0000000..7eca30c
--- /dev/null
+++ b/mnemonic-core/src/main/assembly/assembly.xml
@@ -0,0 +1,28 @@
+<assembly>
+ <id>mixed</id>
+ <formats>
+ <format>jar</format>
+ </formats>
+ <dependencySets>
+ <dependencySet>
+ <useProjectArtifact>true</useProjectArtifact>
+ <outputDirectory>lib</outputDirectory>
+ </dependencySet>
+ </dependencySets>
+ <fileSets>
+ <fileSet>
+ <outputDirectory>/</outputDirectory>
+ <includes>
+ <include>README.txt</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>src/main/scripts</directory>
+ <outputDirectory>/bin</outputDirectory>
+ <includes>
+ <include>run.sh</include>
+ <include>run.bat</include>
+ </includes>
+ </fileSet>
+ </fileSets>
+</assembly>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/30836536/mnemonic-core/src/main/java/org/apache/mnemonic/Allocatable.java
----------------------------------------------------------------------
diff --git a/mnemonic-core/src/main/java/org/apache/mnemonic/Allocatable.java b/mnemonic-core/src/main/java/org/apache/mnemonic/Allocatable.java
new file mode 100644
index 0000000..2fec5c8
--- /dev/null
+++ b/mnemonic-core/src/main/java/org/apache/mnemonic/Allocatable.java
@@ -0,0 +1,117 @@
+/*
+ * 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;
+
+/**
+ * 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
+ */
+ 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
+ */
+ 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
+ */
+ 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
+ */
+ MemBufferHolder<A> createBuffer(long size);
+
+ /**
+ * register a memory chunk for auto-reclaim
+ *
+ * @param mholder
+ * specify a chunk holder to register
+ */
+ void registerChunkAutoReclaim(MemChunkHolder<A> mholder);
+
+ /**
+ * register a memory buffer for auto-reclaim
+ *
+ * @param mholder
+ * specify a buffer holder to register
+ */
+ 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
+ *
+ */
+ 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
+ *
+ */
+ MemBufferHolder<A> resizeBuffer(MemBufferHolder<A> mholder, long size);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/30836536/mnemonic-core/src/main/java/org/apache/mnemonic/Allocator.java
----------------------------------------------------------------------
diff --git a/mnemonic-core/src/main/java/org/apache/mnemonic/Allocator.java b/mnemonic-core/src/main/java/org/apache/mnemonic/Allocator.java
new file mode 100644
index 0000000..28a1119
--- /dev/null
+++ b/mnemonic-core/src/main/java/org/apache/mnemonic/Allocator.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+/**
+ * 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.
+ *
+ */
+ void close();
+
+ /**
+ * sync. dirty data to underlying memory-like device
+ *
+ */
+ 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
+ */
+ A enableActiveGC(long timeout);
+
+ /**
+ * disable active garbage collection.
+ *
+ * @return this allocator
+ */
+ A disableActiveGC();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/30836536/mnemonic-core/src/main/java/org/apache/mnemonic/AnnotatedDurableEntityClass.java
----------------------------------------------------------------------
diff --git a/mnemonic-core/src/main/java/org/apache/mnemonic/AnnotatedDurableEntityClass.java b/mnemonic-core/src/main/java/org/apache/mnemonic/AnnotatedDurableEntityClass.java
new file mode 100644
index 0000000..7f25b33
--- /dev/null
+++ b/mnemonic-core/src/main/java/org/apache/mnemonic/AnnotatedDurableEntityClass.java
@@ -0,0 +1,943 @@
+/*
+ * 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.io.IOException;
+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.Filer;
+import javax.annotation.processing.Messager;
+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.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 com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ArrayTypeName;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.CodeBlock;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.MethodSpec.Builder;
+import com.squareup.javapoet.ParameterSpec;
+import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeVariableName;
+
+import sun.misc.Unsafe;
+
+/**
+ * this class managed to generate generic non-volatile concrete object and their
+ * corresponding factory.
+ *
+ */
+@SuppressWarnings("restriction")
+public class AnnotatedDurableEntityClass {
+ 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 cFACTORYNAMESUFFIX = "Factory";
+ protected final String cPMEMNAMEPREFIX = "Durable_";
+ protected final String cFIELDNAMESUFFIX = String.format("_field_%s", Utils.genRandomString());
+ protected final String cALLOCATORFIELDNAME = String.format("alloc_%s", Utils.genRandomString());
+ protected final String cAUTORECLAIMFIELDNAME = String.format("autoreclaim_%s", Utils.genRandomString());
+ protected final String cUNSAFEFIELDNAME = String.format("unsafe_%s", Utils.genRandomString());
+ protected final String cHOLDERFIELDNAME = String.format("holder_%s", Utils.genRandomString());
+ protected final String cALLOCTYPENAME = String.format("ALLOC_PMem3C93D24F59");
+
+ private Types m_typeutils;
+ private Elements m_elemutils;
+ 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(cALLOCTYPENAME);
+ private TypeName m_factoryproxystypename = TypeName.get(EntityFactoryProxy[].class);
+ private TypeName m_gfieldstypename = TypeName.get(GenericField.GType[].class);
+ private TypeVariableName m_alloctypevarname = TypeVariableName.get(cALLOCTYPENAME,
+ ParameterizedTypeName.get(ClassName.get(CommonDurableAllocator.class), TypeVariableName.get(cALLOCTYPENAME)));
+
+ 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 AnnotatedDurableEntityClass(TypeElement classElement, Types typeUtils, Elements elementUtils,
+ Messager messager) {
+ m_elem = classElement;
+ m_typeutils = typeUtils;
+ m_elemutils = elementUtils;
+
+ m_packagename = m_elemutils.getPackageOf(m_elem).getQualifiedName().toString();
+
+ m_factoryname = String.format("%s%s", m_elem.getSimpleName(), cFACTORYNAMESUFFIX);
+ m_entityname = String.format("%s%s_%s", cPMEMNAMEPREFIX, m_elem.getSimpleName(), Utils.genRandomString());
+
+ m_durablemtdinfo.put("cancelAutoReclaim", new MethodInfo());
+ m_durablemtdinfo.put("registerAutoReclaim", new MethodInfo());
+ m_durablemtdinfo.put("getHandler", new MethodInfo());
+ m_durablemtdinfo.put("autoReclaim", new MethodInfo());
+ m_durablemtdinfo.put("destroy", new MethodInfo());
+ m_durablemtdinfo.put("getNativeFieldInfo", new MethodInfo());
+
+ m_entitymtdinfo.put("initializeDurableEntity", new MethodInfo());
+ m_entitymtdinfo.put("createDurableEntity", new MethodInfo());
+ m_entitymtdinfo.put("restoreDurableEntity", 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(MemoryDurableEntity.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);
+ DurableGetter pgetter = elem.getAnnotation(DurableGetter.class);
+ if (pgetter != null) {
+ if (!elem.getModifiers().contains(Modifier.ABSTRACT)) {
+ throw new AnnotationProcessingException(elem, "%s annotated with DurableGetter is not abstract.",
+ methodname);
+ }
+ if (null != elem.getAnnotation(DurableSetter.class)) {
+ throw new AnnotationProcessingException(elem, "%s is annotated with DurableSetter 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(DurableSetter.class)) {
+ if (!elem.getModifiers().contains(Modifier.ABSTRACT)) {
+ throw new AnnotationProcessingException(elem, "%s annotated with DurableSetter 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);
+ }
+ }
+ }
+
+ 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);
+ }
+ }
+
+ 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, cALLOCTYPENAME);
+
+ }
+ }
+ }
+ 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 RetrieveDurableEntityError(\"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 RetrieveDurableEntityError(\"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(), cFACTORYNAMESUFFIX),
+ 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 OutOfHybridMemory(\"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 RetrieveDurableEntityError(\"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 RetrieveDurableEntityError(\"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.getHandler())", 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 "getHandler":
+ 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;
+ 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 "initializeDurableEntity":
+ 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 "createDurableEntity":
+ arg3 = methodinfo.elem.getParameters().get(3);
+ code.addStatement("initializeDurableEntity($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 OutOfHybridMemory(\"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(RetrieveDurableEntityError ex)");
+ // code.endControlFlow();
+ code.addStatement("initializeAfterCreate()");
+ break;
+ case "restoreDurableEntity":
+ arg3 = methodinfo.elem.getParameters().get(3);
+ arg4 = methodinfo.elem.getParameters().get(4);
+ code.addStatement("initializeDurableEntity($1L, $2L, $3L, $4L)", arg0, arg1, arg2, arg4);
+ code.beginControlFlow("if (0L == $1L)", arg3);
+ code.addStatement("throw new RetrieveDurableEntityError(\"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 RetrieveDurableEntityError(\"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(OutOfHybridMemory.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(OutOfHybridMemory.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.createDurableEntity($1L, $2L, $3L, $4L)", allocparam.name, factoryproxysparam.name,
+ gfieldsparam.name, autoreclaimparam.name)
+ .addStatement("return entity").build();
+ methodspec = MethodSpec.methodBuilder("create").addTypeVariables(entityspec.typeVariables)
+ .addException(OutOfHybridMemory.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(RetrieveDurableEntityError.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(RetrieveDurableEntityError.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.restoreDurableEntity($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(RetrieveDurableEntityError.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(MemoryDurableEntity.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/30836536/mnemonic-core/src/main/java/org/apache/mnemonic/AnnotationProcessingException.java
----------------------------------------------------------------------
diff --git a/mnemonic-core/src/main/java/org/apache/mnemonic/AnnotationProcessingException.java b/mnemonic-core/src/main/java/org/apache/mnemonic/AnnotationProcessingException.java
new file mode 100644
index 0000000..d454b22
--- /dev/null
+++ b/mnemonic-core/src/main/java/org/apache/mnemonic/AnnotationProcessingException.java
@@ -0,0 +1,40 @@
+/*
+ * 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 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;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-mnemonic/blob/30836536/mnemonic-core/src/main/java/org/apache/mnemonic/ByteBufferBackedInputStream.java
----------------------------------------------------------------------
diff --git a/mnemonic-core/src/main/java/org/apache/mnemonic/ByteBufferBackedInputStream.java b/mnemonic-core/src/main/java/org/apache/mnemonic/ByteBufferBackedInputStream.java
new file mode 100644
index 0000000..7a554dd
--- /dev/null
+++ b/mnemonic-core/src/main/java/org/apache/mnemonic/ByteBufferBackedInputStream.java
@@ -0,0 +1,78 @@
+/*
+ * 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.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+/**
+ * an input Stream that is backed by a in-memory ByteBuffer.
+ *
+ *
+ */
+public class ByteBufferBackedInputStream extends InputStream {
+
+ private ByteBuffer buf;
+
+ /**
+ * accept a ByteBuffer as backed object for inputStream.
+ *
+ * @param buf
+ * specify a bytebuffer that is where any data is from
+ */
+ public ByteBufferBackedInputStream(ByteBuffer buf) {
+ this.buf = buf;
+ }
+
+ /**
+ * read an integer value from backed ByteBuffer.
+ *
+ * @return a integer value from stream input
+ */
+ public int read() throws IOException {
+ if (!buf.hasRemaining()) {
+ return -1;
+ }
+ return buf.get() & 0xFF;
+ }
+
+ /**
+ * read a specified range of byte array from backed ByteBuffer.
+ *
+ * @param bytes
+ * specify a output byte array to store data
+ *
+ * @param off
+ * specify the offset from ByteBuffer to read
+ *
+ * @param len
+ * specify the length of bytes to read
+ *
+ * @return the number of bytes has been read
+ */
+ public int read(byte[] bytes, int off, int len) throws IOException {
+ if (!buf.hasRemaining()) {
+ return -1;
+ }
+
+ len = Math.min(len, buf.remaining());
+ buf.get(bytes, off, len);
+ return len;
+ }
+}