diff --git a/.gitignore b/.gitignore index cc134fa..1afcb32 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,11 @@ hs_err_pid* ## Directory-based project format: .idea/ + +# for eclipse +target +.* + # if you remove the above rule, at least ignore the following: # User-specific stuff: diff --git a/Readme.md b/Readme.md index 80b8338..a8fe19d 100644 --- a/Readme.md +++ b/Readme.md @@ -19,6 +19,7 @@ - Adding and removing operations much faster than ArrayList and LinkedList. - Searching operations nearly same with ArrayList and way better than LinkedList. +## ORIGINAL (time diff + SystemOut) ``` Adding(1M) Elements (5 Tests Avg.) @@ -33,6 +34,40 @@ ArrayList: 4118.2 milliseconds GlueList: 3320.1 milliseconds ``` +## JMH + - Prepare local for JMH : "mvn -e clean install" + - Launch Java Class (containing void main) : com.ertu.collection.jmh.GlueListJMH + - for eclipse developers : 3 tools available in "eclipse-tools" directory (you have to configure "mvn" variable in Eclipse Preferences "String subsitutions" pointing to your maven directory) + +``` +Run complete. Total time: 00:02:13 + +Benchmark Mode Cnt Score Error Units +GlueListJMH.test_1_add_500k_linked_list thrpt 5 182,338 ± 32,451 ops/s +GlueListJMH.test_2_add_500k_array_list thrpt 5 214,535 ± 7,479 ops/s +GlueListJMH.test_3_add_500k_glue_list thrpt 5 251,288 ± 14,355 ops/s +GlueListJMH.test_4_add_1m_linked_list thrpt 5 80,549 ± 10,526 ops/s +GlueListJMH.test_5_add_1m_array_list thrpt 5 93,010 ± 4,741 ops/s +GlueListJMH.test_6_add_1m_glue_list thrpt 5 121,447 ± 12,033 ops/s +GlueListJMH.test_7_add_10m_linked_list thrpt 5 2,090 ± 1,890 ops/s +GlueListJMH.test_8_add_10m_array_list thrpt 5 5,713 ± 1,720 ops/s +GlueListJMH.test_9_add_10m_glue_list thrpt 5 9,644 ± 5,810 ops/s +``` +``` +Run complete. Total time: 00:19:37 + +Benchmark Mode Cnt Score Error Units +GlueListJMH.test_1_add_500k_linked_list thrpt 50 174,315 ± 8,554 ops/s +GlueListJMH.test_2_add_500k_array_list thrpt 50 207,423 ± 3,637 ops/s +GlueListJMH.test_3_add_500k_glue_list thrpt 50 286,250 ± 5,346 ops/s +GlueListJMH.test_4_add_1m_linked_list thrpt 50 77,277 ± 1,607 ops/s +GlueListJMH.test_5_add_1m_array_list thrpt 50 91,264 ± 3,051 ops/s +GlueListJMH.test_6_add_1m_glue_list thrpt 50 131,970 ± 3,007 ops/s +GlueListJMH.test_7_add_10m_linked_list thrpt 50 2,026 ± 0,195 ops/s +GlueListJMH.test_8_add_10m_array_list thrpt 50 6,085 ± 0,208 ops/s +GlueListJMH.test_9_add_10m_glue_list thrpt 50 8,842 ± 0,360 ops/s +``` + #Big-O Algorithm Complexity ``` diff --git a/eclipse-tools/1 - eclipse-eclipse.launch b/eclipse-tools/1 - eclipse-eclipse.launch new file mode 100644 index 0000000..d605bea --- /dev/null +++ b/eclipse-tools/1 - eclipse-eclipse.launch @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/eclipse-tools/2 - JMH preparation.launch b/eclipse-tools/2 - JMH preparation.launch new file mode 100644 index 0000000..3675075 --- /dev/null +++ b/eclipse-tools/2 - JMH preparation.launch @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/eclipse-tools/3 - GlueListJMH.launch b/eclipse-tools/3 - GlueListJMH.launch new file mode 100644 index 0000000..123f55d --- /dev/null +++ b/eclipse-tools/3 - GlueListJMH.launch @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/listText b/listText deleted file mode 100644 index e69de29..0000000 diff --git a/pom.xml b/pom.xml index 416c3d4..b129ea3 100644 --- a/pom.xml +++ b/pom.xml @@ -7,14 +7,20 @@ com.ertu.collection ertu-collection 1.0-SNAPSHOT + + + 1.13 + + org.apache.maven.plugins maven-compiler-plugin + 3.5.1 - 1.7 - 1.7 + 1.8 + 1.8 @@ -26,7 +32,18 @@ junit 4.12 + + org.openjdk.jmh + jmh-core + ${jmh.version} + test + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + test + - \ No newline at end of file diff --git a/src/main/java/GlueList.java b/src/main/java/com/ertu/collection/GlueList.java similarity index 88% rename from src/main/java/GlueList.java rename to src/main/java/com/ertu/collection/GlueList.java index ed4763b..ae35899 100644 --- a/src/main/java/GlueList.java +++ b/src/main/java/com/ertu/collection/GlueList.java @@ -1,3 +1,5 @@ +package com.ertu.collection; + /** * Copyright 2015 Ertuğrul Çetin *

@@ -14,6 +16,10 @@ * limitations under the License. */ +import static java.lang.Math.abs; +import static java.lang.Math.max; +import static java.lang.Math.min; + import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; @@ -30,11 +36,6 @@ import java.util.NoSuchElementException; import java.util.Objects; -import static java.lang.Math.abs; -import static java.lang.Math.max; -import static java.lang.Math.min; - - /** * GlueList is a brand new List implementation which is way faster than ArrayList and LinkedList. * This implementation inspired from ArrayList and LinkedList working mechanism. @@ -79,12 +80,18 @@ */ public class GlueList extends AbstractList implements List, Cloneable, Serializable { - transient Node first; - transient Node last; + /** + * + */ + private static final long serialVersionUID = -7116575455324463081L; + + private transient Node first; - int size; + private transient Node last; - int initialCapacity; + private int size; + + private int initialCapacity; private static final int DEFAULT_CAPACITY = 10; @@ -98,7 +105,7 @@ public GlueList() { last = initNode; } - public GlueList(int initialCapacity) { + public GlueList(final int initialCapacity) { this.initialCapacity = (initialCapacity > MAX_ARRAY_SIZE) ? MAX_ARRAY_SIZE : initialCapacity; @@ -108,7 +115,7 @@ public GlueList(int initialCapacity) { last = initNode; } - public GlueList(Collection c) { + public GlueList(final Collection c) { Objects.requireNonNull(c); @@ -138,8 +145,24 @@ public GlueList(Collection c) { size += len; } + public Node getFirst() { + return first; + } + + public Node getLast() { + return last; + } + + public int getSize() { + return size; + } + + public int getInitialCapacity() { + return initialCapacity; + } + @Override - public boolean add(T element) { + public boolean add(final T element) { Node l = last; @@ -160,7 +183,7 @@ public boolean add(T element) { @SuppressWarnings("unchecked") @Override - public void add(int index, T element) { + public void add(final int index, final T element) { rangeCheckForAdd(index); @@ -219,14 +242,14 @@ public void add(int index, T element) { size++; } - private void rangeCheckForAdd(int index) { + private void rangeCheckForAdd(final int index) { if (index > size || index < 0) { throw new ArrayIndexOutOfBoundsException(index); } } - private void updateNodesAfterAdd(Node nodeFrom) { + private void updateNodesAfterAdd(final Node nodeFrom) { for (Node node = nodeFrom.next; node != null; node = node.next) { @@ -237,7 +260,7 @@ private void updateNodesAfterAdd(Node nodeFrom) { @SuppressWarnings("unchecked") @Override - public boolean addAll(Collection c) { + public boolean addAll(final Collection c) { Objects.requireNonNull(c); @@ -338,7 +361,7 @@ public boolean addAll(Collection c) { } @Override - public T set(int index, T element) { + public T set(final int index, final T element) { rangeCheck(index); @@ -354,7 +377,7 @@ public T set(int index, T element) { } @Override - public T get(int index) { + public T get(final int index) { rangeCheck(index); @@ -364,7 +387,7 @@ public T get(int index) { } @Override - public int indexOf(Object o) { + public int indexOf(final Object o) { int index = 0; @@ -394,7 +417,7 @@ public int indexOf(Object o) { } @Override - public int lastIndexOf(Object o) { + public int lastIndexOf(final Object o) { int index = size - 1; @@ -423,13 +446,13 @@ public int lastIndexOf(Object o) { } @Override - public boolean contains(Object o) { + public boolean contains(final Object o) { return indexOf(o) != -1; } @SuppressWarnings("unchecked") @Override - public T remove(int index) { + public T remove(final int index) { rangeCheck(index); @@ -500,7 +523,7 @@ public T remove(int index) { } @Override - public boolean removeAll(Collection c) { + public boolean removeAll(final Collection c) { Objects.requireNonNull(c); @@ -519,7 +542,7 @@ public boolean removeAll(Collection c) { } @Override - public boolean retainAll(Collection c) { + public boolean retainAll(final Collection c) { Objects.requireNonNull(c); @@ -543,7 +566,7 @@ public boolean retainAll(Collection c) { } @Override - public boolean remove(Object o) { + public boolean remove(final Object o) { int index = indexOf(o); @@ -555,7 +578,7 @@ public boolean remove(Object o) { } } - private void updateNodesAfterRemove(Node fromNode) { + private void updateNodesAfterRemove(final Node fromNode) { for (Node node = fromNode.next; node != null; node = node.next) { @@ -564,7 +587,7 @@ private void updateNodesAfterRemove(Node fromNode) { } } - private Node getNode(int index) { + private Node getNode(final int index) { int firstStartingIndex = first.startingIndex; int firstEndingIndex = first.endingIndex; @@ -601,7 +624,7 @@ private Node getNode(int index) { } } - private Node getNodeForAdd(int index) { + private Node getNodeForAdd(final int index) { if (index == size && !(last.startingIndex <= index && index <= last.endingIndex)) { return null; @@ -610,7 +633,7 @@ private Node getNodeForAdd(int index) { return getNode(index); } - private void rangeCheck(int index) { + private void rangeCheck(final int index) { if (index >= size || index < 0) { throw new ArrayIndexOutOfBoundsException(index); @@ -620,7 +643,7 @@ private void rangeCheck(int index) { @Override public void clear() { - for (Node node = first; node != null; ) { + for (Node node = first; node != null;) { Node next = node.next; @@ -664,7 +687,7 @@ public void trimToSize() { } @Override - public List subList(int fromIndex, int toIndex) { + public List subList(final int fromIndex, final int toIndex) { return super.subList(fromIndex, toIndex); } @@ -690,10 +713,11 @@ public Object[] toArray() { @SuppressWarnings("unchecked") @Override - public T[] toArray(T[] a) { + public T[] toArray(final T[] a) { return (T[]) Arrays.copyOf(toArray(), size, a.getClass()); } + @Override public boolean isEmpty() { return size == 0; } @@ -708,11 +732,13 @@ private class Itr implements Iterator { Node node = first; int i = 0;//inner-array index + int j = 0;//total index -> cursor int lastReturn = -1; int expectedModCount = modCount; + int elementDataPointer = node.elementDataPointer; @Override @@ -786,14 +812,14 @@ void checkForComodification() { } @Override - public ListIterator listIterator(int index) { + public ListIterator listIterator(final int index) { checkPositionIndex(index); return new ListItr(index); } - private void checkPositionIndex(int index) { + private void checkPositionIndex(final int index) { if (!(index >= 0 && index <= size)) { throw new ArrayIndexOutOfBoundsException(index); @@ -807,7 +833,7 @@ public ListIterator listIterator() { private class ListItr extends Itr implements ListIterator { - public ListItr(int index) { + public ListItr(final int index) { node = (index == size) ? last : getNode(index); j = index; i = index - node.startingIndex; @@ -878,7 +904,7 @@ public int previousIndex() { } @Override - public void set(T t) { + public void set(final T t) { if (lastReturn < 0) { throw new IllegalStateException(); @@ -894,7 +920,7 @@ public void set(T t) { } @Override - public void add(T t) { + public void add(final T t) { checkForComodification(); @@ -955,7 +981,7 @@ public Object clone() { } } - private void writeObject(ObjectOutputStream s) throws IOException { + private void writeObject(final ObjectOutputStream s) throws IOException { int expectedModCount = modCount; @@ -974,9 +1000,8 @@ private void writeObject(ObjectOutputStream s) throws IOException { } } - @SuppressWarnings("unchecked") - private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { + private void readObject(final ObjectInputStream s) throws IOException, ClassNotFoundException { clear(); @@ -989,21 +1014,24 @@ private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundEx } } - static class Node { + public static class Node { + + private Node pre; + + private Node next; - Node pre; - Node next; + private final int listSize; - int listSize; + private int startingIndex; - int startingIndex; - int endingIndex; + private int endingIndex; - T[] elementData; - int elementDataPointer; + private T[] elementData; + + private int elementDataPointer; @SuppressWarnings("unchecked") - Node(Node pre, Node next, int listSize) { + Node(final Node pre, final Node next, final int listSize) { this.pre = pre; this.next = next; this.listSize = listSize; @@ -1012,7 +1040,7 @@ static class Node { this.endingIndex = listSize + elementData.length - 1; } - Node(Node pre, Node next, int listSize, int initialCapacity) { + Node(final Node pre, final Node next, final int listSize, final int initialCapacity) { this.pre = pre; this.next = next; this.listSize = listSize; @@ -1021,8 +1049,36 @@ static class Node { this.endingIndex = listSize + elementData.length - 1; } + public Node getPre() { + return pre; + } + + public Node getNext() { + return next; + } + + public int getListSize() { + return listSize; + } + + public int getStartingIndex() { + return startingIndex; + } + + public int getEndingIndex() { + return endingIndex; + } + + public T[] getElementData() { + return elementData; + } + + public int getElementDataPointer() { + return elementDataPointer; + } + @SuppressWarnings("unchecked") - T[] createElementData(int capacity) { + T[] createElementData(final int capacity) { if (capacity == 0 || capacity == 1) { return (T[]) new Object[DEFAULT_CAPACITY]; @@ -1037,7 +1093,7 @@ boolean isAddable() { return elementDataPointer < elementData.length; } - void add(T element) { + void add(final T element) { elementData[elementDataPointer++] = element; } @@ -1046,4 +1102,4 @@ public String toString() { return String.format("[sIndex: %d - eIndex: %d | elementDataPointer: %d | elementDataLength: %d]", startingIndex, endingIndex, elementDataPointer, elementData.length); } } -} \ No newline at end of file +} diff --git a/src/test/java/TestUtil.java b/src/test/java/TestUtil.java deleted file mode 100644 index dc678e1..0000000 --- a/src/test/java/TestUtil.java +++ /dev/null @@ -1,98 +0,0 @@ -public class TestUtil { - - private TestUtil() { - } - - public static void printNodesStartingAndEndingIndexes(GlueList glueList) { - - int totalNodesCreated = 0; - - StringBuilder stringBuilder = new StringBuilder(); - for (GlueList.Node node = glueList.first; node != null; node = node.next) { - stringBuilder.append("[").append(node.startingIndex).append(",").append(node.endingIndex).append("] "); - totalNodesCreated++; - } - String result = stringBuilder.toString(); - - if (result.length() == 0) { - System.out.println("[]"); - System.out.println("Total Nodes: " + totalNodesCreated); - } else { - System.out.println(result); - System.out.println("Total Nodes: " + totalNodesCreated); - } - } - - public static void printNodesInfo(GlueList glueList) { - - int totalNodesCreated = 0; - - for (GlueList.Node node = glueList.first; node != null; node = node.next) { - System.out.println(node); - totalNodesCreated++; - } - - System.out.println("Total Nodes: " + totalNodesCreated); - System.out.println(); - } - - - public static boolean isNodesStartingAndEndingIndexesAreTrue(GlueList glueList) { - - for (GlueList.Node node = glueList.first; node != null; node = node.next) { - - GlueList.Node nodeNext = node.next; - if (nodeNext == null) { - continue; - } - - if (node.endingIndex + 1 != nodeNext.startingIndex) { - return false; - } - } - - return true; - } - - public static boolean isNodesElementDataPointerSameWithNodeArrayLength(GlueList glueList) { - - //goes until last.Because last may not been loaded - for (GlueList.Node node = glueList.first; node != glueList.last; node = node.next) { - - if (node.elementDataPointer != node.elementData.length) { - return false; - } - } - - return true; - } - - public static boolean isItCorrectAfterAllDataDeleted(GlueList glueList) { - - if (glueList.size() != 0) { - return false; - } - - if (glueList.first != glueList.last) { - return false; - } - - if (glueList.last.elementDataPointer != 0) { - return false; - } - - if (glueList.last.elementData.length < 2) { - return false; - } - - if (glueList.last.startingIndex > glueList.last.endingIndex) { - return false; - } - - return true; - } - - public static boolean isFirstAndLastNodesAreEqual(GlueList glueList) { - return glueList.first == glueList.last; - } -} \ No newline at end of file diff --git a/src/test/java/GlueList_0_Benchmark.java b/src/test/java/com/ertu/collection/GlueList_0_Benchmark.java similarity index 98% rename from src/test/java/GlueList_0_Benchmark.java rename to src/test/java/com/ertu/collection/GlueList_0_Benchmark.java index 868faf7..24db5cc 100644 --- a/src/test/java/GlueList_0_Benchmark.java +++ b/src/test/java/com/ertu/collection/GlueList_0_Benchmark.java @@ -1,5 +1,9 @@ +package com.ertu.collection; + import org.junit.Test; +import com.ertu.collection.GlueList; + import java.util.ArrayList; import java.util.LinkedList; import java.util.List; diff --git a/src/test/java/GlueList_10_RemoveAllTest.java b/src/test/java/com/ertu/collection/GlueList_10_RemoveAllTest.java similarity index 97% rename from src/test/java/GlueList_10_RemoveAllTest.java rename to src/test/java/com/ertu/collection/GlueList_10_RemoveAllTest.java index 5e30388..03f9d9d 100644 --- a/src/test/java/GlueList_10_RemoveAllTest.java +++ b/src/test/java/com/ertu/collection/GlueList_10_RemoveAllTest.java @@ -1,5 +1,9 @@ +package com.ertu.collection; + import org.junit.Test; +import com.ertu.collection.GlueList; + import static org.junit.Assert.assertEquals; public class GlueList_10_RemoveAllTest { diff --git a/src/test/java/GlueList_11_RetainAllTest.java b/src/test/java/com/ertu/collection/GlueList_11_RetainAllTest.java similarity index 97% rename from src/test/java/GlueList_11_RetainAllTest.java rename to src/test/java/com/ertu/collection/GlueList_11_RetainAllTest.java index 23dea50..bff8568 100644 --- a/src/test/java/GlueList_11_RetainAllTest.java +++ b/src/test/java/com/ertu/collection/GlueList_11_RetainAllTest.java @@ -1,5 +1,9 @@ +package com.ertu.collection; + import org.junit.Test; +import com.ertu.collection.GlueList; + import static org.junit.Assert.assertEquals; public class GlueList_11_RetainAllTest { diff --git a/src/test/java/GlueList_12_ClearTest.java b/src/test/java/com/ertu/collection/GlueList_12_ClearTest.java similarity index 88% rename from src/test/java/GlueList_12_ClearTest.java rename to src/test/java/com/ertu/collection/GlueList_12_ClearTest.java index 1356066..69fed20 100644 --- a/src/test/java/GlueList_12_ClearTest.java +++ b/src/test/java/com/ertu/collection/GlueList_12_ClearTest.java @@ -1,7 +1,11 @@ -import org.junit.Test; +package com.ertu.collection; import static org.junit.Assert.assertEquals; +import org.junit.Test; + +import com.ertu.collection.GlueList; + public class GlueList_12_ClearTest { @Test @@ -15,7 +19,7 @@ public void test_clear_size() { glueList.clear(); assertEquals(0, glueList.size()); - assertEquals(20, glueList.initialCapacity); + assertEquals(20, glueList.getInitialCapacity()); assertEquals(true, TestUtil.isFirstAndLastNodesAreEqual(glueList)); assertEquals(true, TestUtil.isNodesStartingAndEndingIndexesAreTrue(glueList)); assertEquals(true, TestUtil.isNodesElementDataPointerSameWithNodeArrayLength(glueList)); @@ -33,7 +37,7 @@ public void test_clear_initial_size() { glueList.clear(); assertEquals(0, glueList.size()); - assertEquals(30, glueList.initialCapacity); + assertEquals(30, glueList.getInitialCapacity()); assertEquals(true, TestUtil.isFirstAndLastNodesAreEqual(glueList)); assertEquals(true, TestUtil.isNodesStartingAndEndingIndexesAreTrue(glueList)); assertEquals(true, TestUtil.isNodesElementDataPointerSameWithNodeArrayLength(glueList)); @@ -51,9 +55,9 @@ public void test_clear_default_size() { glueList.clear(); assertEquals(0, glueList.size()); - assertEquals(10, glueList.initialCapacity); + assertEquals(10, glueList.getInitialCapacity()); assertEquals(true, TestUtil.isFirstAndLastNodesAreEqual(glueList)); assertEquals(true, TestUtil.isNodesStartingAndEndingIndexesAreTrue(glueList)); assertEquals(true, TestUtil.isNodesElementDataPointerSameWithNodeArrayLength(glueList)); } -} \ No newline at end of file +} diff --git a/src/test/java/GlueList_13_TrimToSizeTest.java b/src/test/java/com/ertu/collection/GlueList_13_TrimToSizeTest.java similarity index 98% rename from src/test/java/GlueList_13_TrimToSizeTest.java rename to src/test/java/com/ertu/collection/GlueList_13_TrimToSizeTest.java index 8895dc1..81cc8e9 100644 --- a/src/test/java/GlueList_13_TrimToSizeTest.java +++ b/src/test/java/com/ertu/collection/GlueList_13_TrimToSizeTest.java @@ -1,5 +1,9 @@ +package com.ertu.collection; + import org.junit.Test; +import com.ertu.collection.GlueList; + import static org.junit.Assert.assertEquals; public class GlueList_13_TrimToSizeTest { diff --git a/src/test/java/GlueList_14_ToArrayTest.java b/src/test/java/com/ertu/collection/GlueList_14_ToArrayTest.java similarity index 96% rename from src/test/java/GlueList_14_ToArrayTest.java rename to src/test/java/com/ertu/collection/GlueList_14_ToArrayTest.java index 654b703..aeef18e 100644 --- a/src/test/java/GlueList_14_ToArrayTest.java +++ b/src/test/java/com/ertu/collection/GlueList_14_ToArrayTest.java @@ -1,5 +1,9 @@ +package com.ertu.collection; + import org.junit.Test; +import com.ertu.collection.GlueList; + import java.util.Arrays; import java.util.List; diff --git a/src/test/java/GlueList_15_GenericToArrayTest.java b/src/test/java/com/ertu/collection/GlueList_15_GenericToArrayTest.java similarity index 96% rename from src/test/java/GlueList_15_GenericToArrayTest.java rename to src/test/java/com/ertu/collection/GlueList_15_GenericToArrayTest.java index df301e1..db902e9 100644 --- a/src/test/java/GlueList_15_GenericToArrayTest.java +++ b/src/test/java/com/ertu/collection/GlueList_15_GenericToArrayTest.java @@ -1,5 +1,9 @@ +package com.ertu.collection; + import org.junit.Test; +import com.ertu.collection.GlueList; + import java.util.Arrays; import java.util.List; diff --git a/src/test/java/GlueList_16_CloneTest.java b/src/test/java/com/ertu/collection/GlueList_16_CloneTest.java similarity index 97% rename from src/test/java/GlueList_16_CloneTest.java rename to src/test/java/com/ertu/collection/GlueList_16_CloneTest.java index 1b212ba..5f3cacd 100644 --- a/src/test/java/GlueList_16_CloneTest.java +++ b/src/test/java/com/ertu/collection/GlueList_16_CloneTest.java @@ -1,5 +1,9 @@ +package com.ertu.collection; + import org.junit.Test; +import com.ertu.collection.GlueList; + import static org.junit.Assert.assertEquals; public class GlueList_16_CloneTest { diff --git a/src/test/java/GlueList_17_WriteAndReadObject.java b/src/test/java/com/ertu/collection/GlueList_17_WriteAndReadObject.java similarity index 96% rename from src/test/java/GlueList_17_WriteAndReadObject.java rename to src/test/java/com/ertu/collection/GlueList_17_WriteAndReadObject.java index 7d54138..466dff2 100644 --- a/src/test/java/GlueList_17_WriteAndReadObject.java +++ b/src/test/java/com/ertu/collection/GlueList_17_WriteAndReadObject.java @@ -1,7 +1,11 @@ +package com.ertu.collection; + import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; +import com.ertu.collection.GlueList; + import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; diff --git a/src/test/java/GlueList_18_Iterator.java b/src/test/java/com/ertu/collection/GlueList_18_Iterator.java similarity index 99% rename from src/test/java/GlueList_18_Iterator.java rename to src/test/java/com/ertu/collection/GlueList_18_Iterator.java index 2a58888..7be5b15 100644 --- a/src/test/java/GlueList_18_Iterator.java +++ b/src/test/java/com/ertu/collection/GlueList_18_Iterator.java @@ -1,5 +1,9 @@ +package com.ertu.collection; + import org.junit.Test; +import com.ertu.collection.GlueList; + import java.util.Iterator; import java.util.NoSuchElementException; diff --git a/src/test/java/GlueList_19_ListIteratorTest.java b/src/test/java/com/ertu/collection/GlueList_19_ListIteratorTest.java similarity index 99% rename from src/test/java/GlueList_19_ListIteratorTest.java rename to src/test/java/com/ertu/collection/GlueList_19_ListIteratorTest.java index e369e17..bca65c8 100644 --- a/src/test/java/GlueList_19_ListIteratorTest.java +++ b/src/test/java/com/ertu/collection/GlueList_19_ListIteratorTest.java @@ -1,5 +1,9 @@ +package com.ertu.collection; + import org.junit.Test; +import com.ertu.collection.GlueList; + import java.util.ListIterator; import static org.junit.Assert.assertEquals; diff --git a/src/test/java/GlueList_1_ConstructorTest.java b/src/test/java/com/ertu/collection/GlueList_1_ConstructorTest.java similarity index 95% rename from src/test/java/GlueList_1_ConstructorTest.java rename to src/test/java/com/ertu/collection/GlueList_1_ConstructorTest.java index 795b92c..4b9b324 100644 --- a/src/test/java/GlueList_1_ConstructorTest.java +++ b/src/test/java/com/ertu/collection/GlueList_1_ConstructorTest.java @@ -1,10 +1,14 @@ -import org.junit.Test; +package com.ertu.collection; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import java.util.LinkedList; import java.util.List; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; +import org.junit.Test; + +import com.ertu.collection.GlueList; public class GlueList_1_ConstructorTest { @@ -13,7 +17,7 @@ public void test() { GlueList glueList = new GlueList<>(); - assertEquals(true, glueList.first == glueList.last); + assertEquals(true, glueList.getFirst() == glueList.getLast()); assertEquals(true, TestUtil.isItCorrectAfterAllDataDeleted(glueList)); assertEquals(true, TestUtil.isNodesStartingAndEndingIndexesAreTrue(glueList)); assertEquals(true, TestUtil.isNodesElementDataPointerSameWithNodeArrayLength(glueList)); @@ -92,4 +96,4 @@ public void test_collection_constructor_2() { assertEquals(true, TestUtil.isNodesStartingAndEndingIndexesAreTrue(glueList)); assertEquals(true, TestUtil.isNodesElementDataPointerSameWithNodeArrayLength(glueList)); } -} \ No newline at end of file +} diff --git a/src/test/java/GlueList_20_SubListTest.java b/src/test/java/com/ertu/collection/GlueList_20_SubListTest.java similarity index 96% rename from src/test/java/GlueList_20_SubListTest.java rename to src/test/java/com/ertu/collection/GlueList_20_SubListTest.java index 8f45676..a2ded77 100644 --- a/src/test/java/GlueList_20_SubListTest.java +++ b/src/test/java/com/ertu/collection/GlueList_20_SubListTest.java @@ -1,5 +1,9 @@ +package com.ertu.collection; + import org.junit.Test; +import com.ertu.collection.GlueList; + import static org.junit.Assert.assertEquals; public class GlueList_20_SubListTest { diff --git a/src/test/java/GlueList_2_AddTest.java b/src/test/java/com/ertu/collection/GlueList_2_AddTest.java similarity index 98% rename from src/test/java/GlueList_2_AddTest.java rename to src/test/java/com/ertu/collection/GlueList_2_AddTest.java index e4d3726..9f66d47 100644 --- a/src/test/java/GlueList_2_AddTest.java +++ b/src/test/java/com/ertu/collection/GlueList_2_AddTest.java @@ -1,5 +1,9 @@ +package com.ertu.collection; + import org.junit.Test; +import com.ertu.collection.GlueList; + import static org.junit.Assert.assertEquals; public class GlueList_2_AddTest { diff --git a/src/test/java/GlueList_3_AddWithIndexTest.java b/src/test/java/com/ertu/collection/GlueList_3_AddWithIndexTest.java similarity index 99% rename from src/test/java/GlueList_3_AddWithIndexTest.java rename to src/test/java/com/ertu/collection/GlueList_3_AddWithIndexTest.java index 621f849..da734f2 100644 --- a/src/test/java/GlueList_3_AddWithIndexTest.java +++ b/src/test/java/com/ertu/collection/GlueList_3_AddWithIndexTest.java @@ -1,5 +1,9 @@ +package com.ertu.collection; + import org.junit.Test; +import com.ertu.collection.GlueList; + import static org.junit.Assert.assertEquals; public class GlueList_3_AddWithIndexTest { diff --git a/src/test/java/GlueList_4_AddAllTest.java b/src/test/java/com/ertu/collection/GlueList_4_AddAllTest.java similarity index 98% rename from src/test/java/GlueList_4_AddAllTest.java rename to src/test/java/com/ertu/collection/GlueList_4_AddAllTest.java index 7e514dc..b2583ee 100644 --- a/src/test/java/GlueList_4_AddAllTest.java +++ b/src/test/java/com/ertu/collection/GlueList_4_AddAllTest.java @@ -1,5 +1,9 @@ +package com.ertu.collection; + import org.junit.Test; +import com.ertu.collection.GlueList; + import java.util.ArrayList; import static org.junit.Assert.assertEquals; diff --git a/src/test/java/GlueList_5_SetTest.java b/src/test/java/com/ertu/collection/GlueList_5_SetTest.java similarity index 97% rename from src/test/java/GlueList_5_SetTest.java rename to src/test/java/com/ertu/collection/GlueList_5_SetTest.java index 8bbc6cc..d1a8f74 100644 --- a/src/test/java/GlueList_5_SetTest.java +++ b/src/test/java/com/ertu/collection/GlueList_5_SetTest.java @@ -1,5 +1,9 @@ +package com.ertu.collection; + import org.junit.Test; +import com.ertu.collection.GlueList; + import static org.junit.Assert.assertEquals; public class GlueList_5_SetTest { diff --git a/src/test/java/GlueList_6_GetTest.java b/src/test/java/com/ertu/collection/GlueList_6_GetTest.java similarity index 97% rename from src/test/java/GlueList_6_GetTest.java rename to src/test/java/com/ertu/collection/GlueList_6_GetTest.java index cdf4cc3..1268a30 100644 --- a/src/test/java/GlueList_6_GetTest.java +++ b/src/test/java/com/ertu/collection/GlueList_6_GetTest.java @@ -1,5 +1,9 @@ +package com.ertu.collection; + import org.junit.Test; +import com.ertu.collection.GlueList; + import java.util.ArrayList; import static org.junit.Assert.assertEquals; diff --git a/src/test/java/GlueList_7_Remove.java b/src/test/java/com/ertu/collection/GlueList_7_Remove.java similarity index 99% rename from src/test/java/GlueList_7_Remove.java rename to src/test/java/com/ertu/collection/GlueList_7_Remove.java index a355d60..53ca2ed 100644 --- a/src/test/java/GlueList_7_Remove.java +++ b/src/test/java/com/ertu/collection/GlueList_7_Remove.java @@ -1,5 +1,9 @@ +package com.ertu.collection; + import org.junit.Test; +import com.ertu.collection.GlueList; + import static org.junit.Assert.assertEquals; public class GlueList_7_Remove { diff --git a/src/test/java/GlueList_8_IndexOfTest.java b/src/test/java/com/ertu/collection/GlueList_8_IndexOfTest.java similarity index 96% rename from src/test/java/GlueList_8_IndexOfTest.java rename to src/test/java/com/ertu/collection/GlueList_8_IndexOfTest.java index f4c2520..9673d1f 100644 --- a/src/test/java/GlueList_8_IndexOfTest.java +++ b/src/test/java/com/ertu/collection/GlueList_8_IndexOfTest.java @@ -1,5 +1,9 @@ +package com.ertu.collection; + import org.junit.Test; +import com.ertu.collection.GlueList; + import static org.junit.Assert.assertEquals; public class GlueList_8_IndexOfTest { diff --git a/src/test/java/GlueList_9_LastIndexOfTest.java b/src/test/java/com/ertu/collection/GlueList_9_LastIndexOfTest.java similarity index 96% rename from src/test/java/GlueList_9_LastIndexOfTest.java rename to src/test/java/com/ertu/collection/GlueList_9_LastIndexOfTest.java index 0bb8603..41c307f 100644 --- a/src/test/java/GlueList_9_LastIndexOfTest.java +++ b/src/test/java/com/ertu/collection/GlueList_9_LastIndexOfTest.java @@ -1,5 +1,9 @@ +package com.ertu.collection; + import org.junit.Test; +import com.ertu.collection.GlueList; + import static org.junit.Assert.assertEquals; public class GlueList_9_LastIndexOfTest { diff --git a/src/test/java/com/ertu/collection/TestUtil.java b/src/test/java/com/ertu/collection/TestUtil.java new file mode 100644 index 0000000..f06cad4 --- /dev/null +++ b/src/test/java/com/ertu/collection/TestUtil.java @@ -0,0 +1,101 @@ +package com.ertu.collection; + +import com.ertu.collection.GlueList; + +public class TestUtil { + + private TestUtil() { + } + + public static void printNodesStartingAndEndingIndexes(final GlueList glueList) { + + int totalNodesCreated = 0; + + StringBuilder stringBuilder = new StringBuilder(); + for (GlueList.Node node = glueList.getFirst(); node != null; node = node.getNext()) { + stringBuilder.append("[").append(node.getStartingIndex()).append(",").append(node.getEndingIndex()).append("] "); + totalNodesCreated++; + } + String result = stringBuilder.toString(); + + if (result.length() == 0) { + System.out.println("[]"); + System.out.println("Total Nodes: " + totalNodesCreated); + } else { + System.out.println(result); + System.out.println("Total Nodes: " + totalNodesCreated); + } + } + + public static void printNodesInfo(final GlueList glueList) { + + int totalNodesCreated = 0; + + for (GlueList.Node node = glueList.getFirst(); node != null; node = node.getNext()) { + System.out.println(node); + totalNodesCreated++; + } + + System.out.println("Total Nodes: " + totalNodesCreated); + System.out.println(); + } + + public static boolean isNodesStartingAndEndingIndexesAreTrue(final GlueList glueList) { + + for (GlueList.Node node = glueList.getFirst(); node != null; node = node.getNext()) { + + GlueList.Node nodeNext = node.getNext(); + if (nodeNext == null) { + continue; + } + + if (node.getEndingIndex() + 1 != nodeNext.getStartingIndex()) { + return false; + } + } + + return true; + } + + public static boolean isNodesElementDataPointerSameWithNodeArrayLength(final GlueList glueList) { + + //goes until last.Because last may not been loaded + for (GlueList.Node node = glueList.getFirst(); node != glueList.getLast(); node = node.getNext()) { + + if (node.getElementDataPointer() != node.getElementData().length) { + return false; + } + } + + return true; + } + + public static boolean isItCorrectAfterAllDataDeleted(final GlueList glueList) { + + if (glueList.size() != 0) { + return false; + } + + if (glueList.getFirst() != glueList.getLast()) { + return false; + } + + if (glueList.getLast().getElementDataPointer() != 0) { + return false; + } + + if (glueList.getLast().getElementData().length < 2) { + return false; + } + + if (glueList.getLast().getStartingIndex() > glueList.getLast().getEndingIndex()) { + return false; + } + + return true; + } + + public static boolean isFirstAndLastNodesAreEqual(final GlueList glueList) { + return glueList.getFirst() == glueList.getLast(); + } +} diff --git a/src/test/java/com/ertu/collection/jmh/GlueListJMH.java b/src/test/java/com/ertu/collection/jmh/GlueListJMH.java new file mode 100644 index 0000000..aa4a72f --- /dev/null +++ b/src/test/java/com/ertu/collection/jmh/GlueListJMH.java @@ -0,0 +1,106 @@ +package com.ertu.collection.jmh; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; + +import com.ertu.collection.GlueList; + +/** + * Lanceur sous forme de Main afin de ne pas lancer les tests JMH (perf) dans le TUs + * (meme si cela serait facilement possible en tranformant le main en méthode + annotation @Test). + * @author egry35 + */ +@State(Scope.Thread) +public class GlueListJMH { + + int dataCount500k = 500_000; + + int dataCount1m = 1_000_000; + + int dataCount10m = 10_000_000; + + @Benchmark + public void test_1_add_500k_linked_list() { + List linkedList = new LinkedList<>(); + for (int i = 0; i < dataCount500k; i++) { + linkedList.add(i); + } + } + + @Benchmark + public void test_2_add_500k_array_list() { + List arrayList = new ArrayList<>(); + for (int i = 0; i < dataCount500k; i++) { + arrayList.add(i); + } + } + + @Benchmark + public void test_3_add_500k_glue_list() { + List glueList = new GlueList<>(); + for (int i = 0; i < dataCount500k; i++) { + glueList.add(i); + } + } + + @Benchmark + public void test_4_add_1m_linked_list() { + List linkedList = new LinkedList<>(); + for (int i = 0; i < dataCount1m; i++) { + linkedList.add(i); + } + } + + @Benchmark + public void test_5_add_1m_array_list() { + List arrayList = new ArrayList<>(); + for (int i = 0; i < dataCount1m; i++) { + arrayList.add(i); + } + } + + @Benchmark + public void test_6_add_1m_glue_list() { + List glueList = new GlueList<>(); + for (int i = 0; i < dataCount1m; i++) { + glueList.add(i); + } + } + + @Benchmark + public void test_7_add_10m_linked_list() { + List linkedList = new LinkedList<>(); + for (int i = 0; i < dataCount10m; i++) { + linkedList.add(i); + } + } + + @Benchmark + public void test_8_add_10m_array_list() { + List arrayList = new ArrayList<>(); + for (int i = 0; i < dataCount10m; i++) { + arrayList.add(i); + } + } + + @Benchmark + public void test_9_add_10m_glue_list() { + List glueList = new GlueList<>(); + for (int i = 0; i < dataCount10m; i++) { + glueList.add(i); + } + } + + /** + * @param args + * @throws Exception + */ + public static void main(final String[] args) throws Exception { + new JMHLauncher().launchJMHBenchmark(GlueListJMH.class); + } +} diff --git a/src/test/java/com/ertu/collection/jmh/JMHLauncher.java b/src/test/java/com/ertu/collection/jmh/JMHLauncher.java new file mode 100644 index 0000000..f86125e --- /dev/null +++ b/src/test/java/com/ertu/collection/jmh/JMHLauncher.java @@ -0,0 +1,45 @@ +package com.ertu.collection.jmh; + +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.ChainedOptionsBuilder; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +/** + * @author egry35 + */ +public class JMHLauncher { + + private static final int NB_ITERATIONS = 50; + + /** + * Methode de lancement du benchmark. + * @param clazz Class de la classe contenant les tests de perf à lancer (@Benchmark) + * @param isEnableAssertions True si on active les assertions (ATTENTION ralentit les perf) + * @throws RunnerException + */ + public void launchJMHBenchmark(final Class clazz) throws RunnerException { + ChainedOptionsBuilder cob = new OptionsBuilder() + .include(clazz.getSimpleName()) + .threads(1) + .forks(1) + .shouldFailOnError(true) + .shouldDoGC(true) + .warmupIterations(NB_ITERATIONS) + .measurementIterations(NB_ITERATIONS) + .jvmArgs("-server"); + + Options options = cob.build(); + try { + new Runner(options).run(); + } catch (RuntimeException ex) { + if (ex.getMessage().contains("Unable to find the resource: /META-INF/BenchmarkList")) { + throw new RuntimeException("Lancer un \"mvn install -DskipTests\" avant de lancer le test (car JMH a besoin de classes préalablement générées par le système d'annotaion JMH => " + ex.getMessage() + ") /// si ERREUR PERSISTE, alors 1.vider le répertoire \"target\", 2.relancer un \"mvn install -DskipTests\"", ex); + } else { + throw ex; + } + } + } + +}