Просмотр исходного кода

Merge branch 'master' of https://repo1.mydevil.net/git/priv/ranides/assira

Ranides Atterwim 10 лет назад
Родитель
Сommit
a0ced8a931

Разница между файлами не показана из-за своего большого размера
+ 687 - 688
assira/src/main/java/net/ranides/assira/collection/lists/AIntList.java


Разница между файлами не показана из-за своего большого размера
+ 588 - 596
assira/src/main/java/net/ranides/assira/collection/lists/IntArrayList.java


+ 102 - 0
assira/src/main/java/net/ranides/assira/collection/lists/IntRTList.java

@@ -0,0 +1,102 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.collection.lists;
+
+import net.ranides.assira.collection.IntCollection;
+import net.ranides.assira.collection.arrays.ArrayUtils;
+
+/**
+ * That implementation stores internally as small array as possible. It reallocates
+ * memory after every operation. Empty list does not allocate any memory. 
+ * Especially helpful for rarely modified collections with small number of elements,
+ * or no elements at all.
+ * 
+ * @author ranides
+ */
+public class IntRTList extends AIntList {
+
+    private final static int[] EMPTY = new int[0];
+	
+    private int[] content;
+
+    public IntRTList() {
+        content = EMPTY;
+    }
+
+    public IntRTList(IntCollection values) {
+        content = values.toIntArray();
+    }
+	
+	public IntRTList(int[] values) {
+        content = ArrayUtils.copy(values);
+    }
+
+    @Override
+    public int getInt(int index) {
+        return content[index];
+    }
+
+    @Override
+    public int size() {
+        return content.length;
+    }
+
+    @Override
+    public void clear() {
+        content = EMPTY;
+    }
+
+    @Override
+    public int set(int index, int element) {
+        int prev = content[index];
+        content[index] = element;
+        return prev;
+    }
+
+    @Override
+    public void add(int index, int element) {
+        if(index > content.length) {
+            throw new IndexOutOfBoundsException(index + " out of bound " + content.length);
+        }
+        if(content == EMPTY) {
+            content = new int[]{ element };
+            return;
+        }
+        int[] buffer = new int[content.length + 1];
+        if(index > 0) {
+            System.arraycopy(content, 0, buffer, 0, index);
+        }
+        if(index < content.length) {
+            System.arraycopy(content, index, buffer, index+1, content.length - index);
+        }
+        buffer[index] = element;
+        content = buffer;
+    }
+
+    @Override
+    public int removeInt(int index) {
+        if(index > content.length) {
+            throw new IndexOutOfBoundsException(index + " out of bound " + content.length);
+        }
+        int prev = content[index];
+        if(content.length == 1) {
+            content = EMPTY;
+            return prev;
+        }
+        int[] buffer = new int[content.length - 1];
+        if(index > 0) {
+            System.arraycopy(content, 0, buffer, 0, index);
+        }
+        if( content.length - index > 1) {
+            System.arraycopy(content, index+1, buffer, index, content.length - index - 1);
+        }
+
+        content = buffer;
+        return prev;
+    }
+
+}

+ 176 - 0
assira/src/main/java/net/ranides/assira/collection/lists/ListUtils.java

@@ -7,13 +7,20 @@
 
 package net.ranides.assira.collection.lists;
 
+import java.io.Serializable;
+import java.util.AbstractList;
+import java.util.Collection;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import java.util.RandomAccess;
 import java.util.function.Function;
 import java.util.function.IntFunction;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import net.ranides.assira.collection.CollectionUtils;
+import net.ranides.assira.collection.arrays.NativeArrayAllocator;
+import net.ranides.assira.collection.iterators.RandomAccessIterator;
 import net.ranides.assira.functional.ProjectionFunction;
 
 /**
@@ -119,5 +126,174 @@ public final class ListUtils {
             }
         };
     }  
+	
+	// @todo (assira #1) IntListUtils#sublist
+	
+	public static <T> List<T> sublist(List<T> list, int begin, int end) {
+		NativeArrayAllocator.ensureFromTo(list.size(), begin, end);
+		if(list instanceof RandomAccess) {
+			return new RandomSubList<>(list, begin, end);
+		} else {
+			return new SubList<>(list, begin, end);
+		}
+	}
+	
+	private static class RandomSubList<T> extends SubList<T> implements RandomAccess {
+		
+		public RandomSubList(List<T> list, int begin, int end) {
+			super(list, begin, end);
+		}
+
+		@Override
+		public ListIterator<T> listIterator(int offset) {
+			return new RandomAccessIterator<T>(offset){
+				@Override
+				protected int size() {
+					return RandomSubList.this.size();
+				}
+
+				@Override
+				protected T get(int index) {
+					return RandomSubList.this.get(index);
+				}
+				
+			};
+		}
+		
+	}
+	
+	private static class SubList<T> extends AbstractList<T> implements Serializable {
+
+        private static final long serialVersionUID = 2;
+
+        protected final List<T> that;
+        protected final int begin;
+        protected int end;
+
+        public SubList(List<T> list, int begin, int end) {
+            this.that = list;
+            this.begin = begin;
+            this.end = end;
+        }
+
+        @Override
+        public void add(int index, T value) {
+            that.add(begin + index, value);
+            end++;
+        }
+
+        @Override
+        public boolean addAll(int index, Collection<? extends T> values) {
+            if( that.addAll(begin + index, values) ) {
+				end += values.size();
+				return true;
+			}
+            return false;
+        }
+
+        @Override
+        public T get(int index) {
+            return that.get(begin + index);
+        }
+
+        @Override
+        public T remove(int index) {
+            T prev = that.remove(begin + index);
+			end--;
+			return prev;
+        }
+
+        @Override
+        public T set(int index, T value) {
+            return that.set(begin + index, value);
+        }
+
+        @Override
+        public void clear() {
+			super.clear();
+			end = begin;
+        }
+
+        @Override
+        public int size() {
+            return end - begin;
+        }
+
+        @Override
+        public ListIterator<T> listIterator(int index) {
+            return new SIterator(index);
+        }
+
+        @Override
+        public List<T> subList(int from, int to) {
+			NativeArrayAllocator.ensureFromTo(size(), from, to);
+            return new SubList(this, from, to);
+        }
+
+        protected final class SIterator implements ListIterator<T> {
+			
+			private final ListIterator<T> delegate;
+
+			public SIterator(int index) {
+				this.delegate = that.listIterator(begin + index);
+			}
+
+			@Override
+			public boolean hasNext() {
+				return delegate.nextIndex() < end;
+			}
+
+			@Override
+			public T next() {
+				if(!hasNext()) {
+					throw new NoSuchElementException();
+				}
+				return delegate.next();
+			}
+
+			@Override
+			public boolean hasPrevious() {
+				return delegate.previousIndex() >= begin;
+			}
+
+			@Override
+			public T previous() {
+				if(!hasPrevious()) {
+					throw new NoSuchElementException();
+				}
+				return delegate.previous();
+			}
+
+			@Override
+			public int nextIndex() {
+				return delegate.nextIndex() - begin;
+			}
+
+			@Override
+			public int previousIndex() {
+				return delegate.previousIndex() - begin;
+			}
+
+			@Override
+			public void remove() {
+				delegate.remove();
+				end--;
+			}
+
+			@Override
+			public void set(T e) {
+				delegate.set(e);
+			}
+
+			@Override
+			public void add(T e) {
+				delegate.add(e);
+				end++;
+			}
+			
+			
+			
+        }
+    }
 
 }

+ 118 - 0
assira/src/main/java/net/ranides/assira/collection/lists/RTList.java

@@ -0,0 +1,118 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.collection.lists;
+
+import java.io.Serializable;
+import java.util.AbstractList;
+import java.util.Collection;
+import java.util.List;
+import net.ranides.assira.collection.arrays.ArrayUtils;
+
+/**
+ * <p>
+ * That implementation stores internally as small array as possible. It reallocates
+ * memory after every operation. Empty list does not allocate any memory. 
+ * Especially helpful for rarely modified collections with small number of elements,
+ * or no elements at all.
+ * </p><p>
+ * Based on idea from {@link javax.swing.event.EventListenerList}.
+ * </p>
+ * @param <T>
+ * @author ranides
+ */
+@SuppressWarnings("unchecked")
+public class RTList<T> extends AbstractList<T> implements Serializable {
+	
+	private static final long serialVersionUID = 1L;
+
+    private final static Object[] EMPTY = new Object[0];
+	
+    private Object[] content;
+
+    public RTList() {
+        content = EMPTY;
+    }
+	
+	public RTList(T[] values) {
+		content = new Object[values.length];
+		ArrayUtils.copy(values, 0, content, 0, values.length);
+	}
+
+    public RTList(Collection<? extends T> values) {
+        content = values.toArray();
+    }
+
+    @Override
+    public T get(int index) {
+        return (T)content[index];
+    }
+
+    @Override
+    public int size() {
+        return content.length;
+    }
+
+    @Override
+    public void clear() {
+        content = EMPTY;
+    }
+
+    @Override
+    public T set(int index, T element) {
+        T prev = (T)content[index];
+        content[index] = element;
+        return prev;
+    }
+
+    @Override
+    public void add(int index, T element) {
+        if(index > content.length) {
+            throw new IndexOutOfBoundsException(index + " out of bound " + content.length);
+        }
+        if(content == EMPTY) {
+            content = new Object[]{ element };
+            return;
+        }
+        Object[] buffer = new Object[content.length + 1];
+        if(index > 0) {
+            System.arraycopy(content, 0, buffer, 0, index);
+        }
+        if(index < content.length) {
+            System.arraycopy(content, index, buffer, index+1, content.length - index);
+        }
+        buffer[index] = element;
+        content = buffer;
+    }
+
+    @Override
+    public T remove(int index) {
+        if(index > content.length) {
+            throw new IndexOutOfBoundsException(index + " out of bound " + content.length);
+        }
+        T prev = (T)content[index];
+        if(content.length == 1) {
+            content = EMPTY;
+            return prev;
+        }
+        Object[] buffer = new Object[content.length - 1];
+        if(index > 0) {
+            System.arraycopy(content, 0, buffer, 0, index);
+        }
+        if( content.length - index > 1) {
+            System.arraycopy(content, index+1, buffer, index, content.length - index - 1);
+        }
+
+        content = buffer;
+        return prev;
+    }
+
+	@Override
+	public List<T> subList(int begin, int end) {
+		return ListUtils.sublist(this, begin, end);
+	}
+	
+}

+ 39 - 0
assira/src/test/java/net/ranides/assira/collection/lists/IntRTListTest.java

@@ -0,0 +1,39 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.collection.lists;
+
+import net.ranides.assira.collection.mockup.CollectionSuite;
+import net.ranides.assira.collection.mockup.TMaps;
+import net.ranides.assira.test.TCollection;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class IntRTListTest {
+	
+	private final TCollection<Integer> $var = TMaps.MAP_IS.keys();
+
+    @Test
+    public void testSuite() {
+        CollectionSuite.SUITE
+			.debug(true)
+			.param("collection!", $var)
+			.run((array) -> new IntRTList($var.list(array).valuesInt()));
+		
+    }
+	
+	@Test
+    public void testConstruct() {
+        assertNotNull(new IntRTList());
+        assertNotNull(new IntRTList(new int[]{1,2,3}));
+        assertNotNull(new IntRTList(new int[]{}));
+    }
+	
+}

+ 38 - 0
assira/src/test/java/net/ranides/assira/collection/lists/RTListTest.java

@@ -0,0 +1,38 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.collection.lists;
+
+import net.ranides.assira.collection.mockup.CollectionSuite;
+import net.ranides.assira.collection.mockup.TMaps;
+import net.ranides.assira.test.TCollection;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class RTListTest {
+	
+	private final TCollection<Integer> $var = TMaps.MAP_IS.keys();
+
+    @Test
+    public void testSuite() {
+        CollectionSuite.SUITE
+			.param("collection!", $var)
+			.run((array) -> new RTList<>($var.list(array).values()));
+		
+    }
+	
+	@Test
+    public void testConstruct() {
+        assertNotNull(new RTList());
+        assertNotNull(new RTList(new Integer[]{1,2,3}));
+        assertNotNull(new RTList(new Integer[]{}));
+    }
+	
+}

+ 112 - 113
assira1/src/main/java/net/ranides/assira/collection/list/RTList.java

@@ -1,113 +1,112 @@
-/*
- * @author Ranides Atterwim <ranides@gmail.com>
- * @copyright Ranides Atterwim
- * @license WTFPL
- * @url http://ranides.net/projects/assira
- */
-package net.ranides.assira.collection.list;
-
-import java.util.AbstractList;
-import java.util.Collection;
-
-/**
- * <p>
- * Specjalna wersja listy, oszczędzająca pamięć w maksymalnym możliwym stopniu.
- * Dokonuje realokacji po dowolnej modyfikacji, odpowiednio zwiększając lub
- * zmniejszając zużycie pamięci w czasie rzeczywistym. W szczególności pusta
- * lista wprowadza minimalny narzut pamięciowy, tzn nie alokuje żadnej pamięci na bufor.
- * </p><p>
- * Klasa wzorowana na {@link javax.swing.event.EventListenerList}, szczególnie
- * przydatna do obsługi kolekcji, które przez większość czasu nie są modyfikowane,
- * posiadają mało elementów, lub w ogóle pozostają puste.
- * </p>
- * całej zawartości
- * @param <T>
- * @author ranides
- * @todo (migration) assira
- */
-@SuppressWarnings("unchecked")
-public class RTList<T> extends AbstractList<T> {
-
-    private final static Object[] EMPTY = new Object[0];
-    private Object[] content = EMPTY;
-
-    /**
-     * Tworzy nową pustą listę.
-     */
-    public RTList() {
-        // do nothing
-    }
-
-    /**
-     * Tworzy nową listę, zawierającą podane elementy.
-     * @param values
-     */
-    public RTList(Collection<? extends T> values) {
-        content = values.toArray();
-    }
-
-    @Override
-    public T get(int index) {
-        return (T)content[index];
-    }
-
-    @Override
-    public int size() {
-        return content.length;
-    }
-
-    @Override
-    public void clear() {
-        content = EMPTY;
-    }
-
-    @Override
-    public T set(int index, T element) {
-        T prev = (T)content[index];
-        content[index] = element;
-        return prev;
-    }
-
-    @Override
-    public void add(int index, T element) {
-        if(index > content.length) {
-            throw new IndexOutOfBoundsException(index + " out of bound " + content.length);
-        }
-        if(content == EMPTY) {
-            content = new Object[]{ element };
-            return;
-        }
-        Object[] buffer = new Object[content.length + 1];
-        if(index > 0) {
-            System.arraycopy(content, 0, buffer, 0, index);
-        }
-        if(index < content.length) {
-            System.arraycopy(content, index, buffer, index+1, content.length - index);
-        }
-        buffer[index] = element;
-        content = buffer;
-    }
-
-    @Override
-    public T remove(int index) {
-        if(index > content.length) {
-            throw new IndexOutOfBoundsException(index + " out of bound " + content.length);
-        }
-        T prev = (T)content[index];
-        if(content.length == 1) {
-            content = EMPTY;
-            return prev;
-        }
-        Object[] buffer = new Object[content.length - 1];
-        if(index > 0) {
-            System.arraycopy(content, 0, buffer, 0, index);
-        }
-        if( content.length - index > 1) {
-            System.arraycopy(content, index+1, buffer, index, content.length - index - 1);
-        }
-
-        content = buffer;
-        return prev;
-    }
-
-}
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.collection.list;
+
+import java.util.AbstractList;
+import java.util.Collection;
+
+/**
+ * <p>
+ * Specjalna wersja listy, oszczędzająca pamięć w maksymalnym możliwym stopniu.
+ * Dokonuje realokacji po dowolnej modyfikacji, odpowiednio zwiększając lub
+ * zmniejszając zużycie pamięci w czasie rzeczywistym. W szczególności pusta
+ * lista wprowadza minimalny narzut pamięciowy, tzn nie alokuje żadnej pamięci na bufor.
+ * </p><p>
+ * Klasa wzorowana na {@link javax.swing.event.EventListenerList}, szczególnie
+ * przydatna do obsługi kolekcji, które przez większość czasu nie są modyfikowane,
+ * posiadają mało elementów, lub w ogóle pozostają puste.
+ * </p>
+ * całej zawartości
+ * @param <T>
+ * @author ranides
+ */
+@SuppressWarnings("unchecked")
+public class RTList<T> extends AbstractList<T> {
+
+    private final static Object[] EMPTY = new Object[0];
+    private Object[] content = EMPTY;
+
+    /**
+     * Tworzy nową pustą listę.
+     */
+    public RTList() {
+        // do nothing
+    }
+
+    /**
+     * Tworzy nową listę, zawierającą podane elementy.
+     * @param values
+     */
+    public RTList(Collection<? extends T> values) {
+        content = values.toArray();
+    }
+
+    @Override
+    public T get(int index) {
+        return (T)content[index];
+    }
+
+    @Override
+    public int size() {
+        return content.length;
+    }
+
+    @Override
+    public void clear() {
+        content = EMPTY;
+    }
+
+    @Override
+    public T set(int index, T element) {
+        T prev = (T)content[index];
+        content[index] = element;
+        return prev;
+    }
+
+    @Override
+    public void add(int index, T element) {
+        if(index > content.length) {
+            throw new IndexOutOfBoundsException(index + " out of bound " + content.length);
+        }
+        if(content == EMPTY) {
+            content = new Object[]{ element };
+            return;
+        }
+        Object[] buffer = new Object[content.length + 1];
+        if(index > 0) {
+            System.arraycopy(content, 0, buffer, 0, index);
+        }
+        if(index < content.length) {
+            System.arraycopy(content, index, buffer, index+1, content.length - index);
+        }
+        buffer[index] = element;
+        content = buffer;
+    }
+
+    @Override
+    public T remove(int index) {
+        if(index > content.length) {
+            throw new IndexOutOfBoundsException(index + " out of bound " + content.length);
+        }
+        T prev = (T)content[index];
+        if(content.length == 1) {
+            content = EMPTY;
+            return prev;
+        }
+        Object[] buffer = new Object[content.length - 1];
+        if(index > 0) {
+            System.arraycopy(content, 0, buffer, 0, index);
+        }
+        if( content.length - index > 1) {
+            System.arraycopy(content, index+1, buffer, index, content.length - index - 1);
+        }
+
+        content = buffer;
+        return prev;
+    }
+
+}