package bytecode.patchfile; import java.util.AbstractList; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.NoSuchElementException; public class TreeList<T> extends AbstractList<T> { private List<T> left; private List<T> right; private int cachedSize = -1; private static <T> List<T> createBalancedTree(List<List<T>> chunks) { if(chunks.size() == 1) return chunks.get(0); int mid = chunks.size() / 2; return new TreeList<T>(createBalancedTree(chunks.subList(0, mid)), createBalancedTree(chunks.subList(mid, chunks.size()))); } public TreeList(List<? extends T> from) { int fromSize = from.size(); final int CHUNKSIZE = 128; int numChunks = (fromSize + CHUNKSIZE - 1) / CHUNKSIZE; List<List<T>> chunks = new ArrayList<>(); for(int chunkstart = 0; chunkstart < fromSize; chunkstart += CHUNKSIZE) { int chunkend = Math.min(chunkstart + CHUNKSIZE, fromSize); chunks.add(new ArrayList<>(from.subList(chunkstart, chunkend))); } if(numChunks == 0) { left = new ArrayList<>(); right = new ArrayList<>(); } else if(numChunks == 1) { left = chunks.get(0); right = new ArrayList<>(); } else { left = createBalancedTree(chunks.subList(0, chunks.size()/2)); right = createBalancedTree(chunks.subList(chunks.size()/2, chunks.size())); } if(size() != fromSize) throw new AssertionError(); } public TreeList(List<T> left, List<T> right) { this.left = left; this.right = right; this.cachedSize = left.size() + right.size(); } @Override public int size() { if(cachedSize < 0) cachedSize = left.size() + right.size(); return cachedSize; } @Override public boolean isEmpty() { throw new UnsupportedOperationException(); } @Override public boolean contains(Object o) { throw new UnsupportedOperationException(); } @Override public Iterator<T> iterator() { return new Iterator<T>() { Iterator<T> cur = left.iterator(); Iterator<T> next = right.iterator(); @Override public boolean hasNext() { if(cur.hasNext()) return true; if(next == null) return false; cur = next; next = null; return cur.hasNext(); } @Override public T next() { if(cur.hasNext()) return cur.next(); if(next == null) throw new NoSuchElementException(); cur = next; next = null; return cur.next(); } @Override public void remove() { throw new UnsupportedOperationException(); } }; } @Override public Object[] toArray() { throw new UnsupportedOperationException(); } @Override public <U> U[] toArray(U[] a) { throw new UnsupportedOperationException(); } @Override public boolean add(T e) { throw new UnsupportedOperationException(); } @Override public boolean remove(Object o) { throw new UnsupportedOperationException(); } @Override public boolean containsAll(Collection<?> c) { throw new UnsupportedOperationException(); } @Override public boolean addAll(Collection<? extends T> c) { return addAll(size(), c); } @Override public boolean addAll(int index, Collection<? extends T> c) { int mid = left.size(); cachedSize = -1; if(index < mid) return left.addAll(index, c); else return right.addAll(index - mid, c); } @Override public boolean removeAll(Collection<?> c) { throw new UnsupportedOperationException(); } @Override public boolean retainAll(Collection<?> c) { throw new UnsupportedOperationException(); } @Override public void clear() { left.clear(); right.clear(); cachedSize = 0; } @Override public T get(int index) { int mid = left.size(); if(index < mid) return left.get(index); else return right.get(index - mid); } @Override public T set(int index, T element) { int mid = left.size(); if(index < mid) return left.set(index, element); else return right.set(index - mid, element); } @Override public void add(int index, T element) { throw new UnsupportedOperationException(); } @Override public T remove(int index) { throw new UnsupportedOperationException(); } @Override public int indexOf(Object o) { throw new UnsupportedOperationException(); } @Override public int lastIndexOf(Object o) { throw new UnsupportedOperationException(); } @Override public ListIterator<T> listIterator() { throw new UnsupportedOperationException(); } @Override public ListIterator<T> listIterator(int index) { throw new UnsupportedOperationException(); } @Override public List<T> subList(int fromIndex, int toIndex) { if(fromIndex == 0 && toIndex == size()) return this; cachedSize = -1; int mid = left.size(); if(fromIndex < mid && toIndex <= mid) return left.subList(fromIndex, toIndex); if(fromIndex >= mid && toIndex >= mid) return right.subList(fromIndex - mid, toIndex - mid); return new TreeList<T>(left.subList(fromIndex, mid), right.subList(0, toIndex - mid)); //return super.subList(fromIndex, toIndex); } }