package com.browseengine.bobo.facets.data; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /** * This class behaves as List<String> with a few extensions: * <ul> * <li> Semi-immutable, e.g. once added, cannot be removed. </li> * <li> Assumes sequence of values added are in sorted order </li> * <li> {@link #indexOf(Object)} return value conforms to the contract of {@link Arrays#binarySearch(Object[], Object)}</li> * <li> {@link #seal()} is introduce to trim the List size, similar to {@link ArrayList#trimToSize()}, once it is called, no add should be performed.</li> * </u> */ public abstract class TermValueList<T> implements List<String> { protected abstract List<?> buildPrimitiveList(int capacity); protected Class<T> _type; public abstract String format(Object o); public abstract void seal(); protected List<?> _innerList; protected TermValueList() { _innerList = buildPrimitiveList(-1); } protected TermValueList(int capacity) { _innerList = buildPrimitiveList(capacity); } /** * The user of this method should not try to alter the content of the list, * which may result in data inconsistency. * And of the content can be accessed using the getRawValue(int) method. * @return the inner list */ public List<?> getInnerList() { return _innerList; } /** * Add a new value to the list. <b>It is important to add the values in sorted (ASC) order.</b> * Our algorithm uses binary searches and priority queues, both of which fails when the ordering is wrong. */ @Override abstract public boolean add(String o); @Override public void add(int index, String element) { throw new IllegalStateException("not supported"); } @Override public boolean addAll(Collection<? extends String> c) { boolean ret = true; for (String s : c) { ret &= add(s); } return ret; } @Override public boolean addAll(int index, Collection<? extends String> c) { throw new IllegalStateException("not supported"); } @Override public void clear() { _innerList.clear(); } @Override public boolean contains(Object o) { return indexOf(o) >= 0; } public abstract boolean containsWithType(T val); @Override public boolean containsAll(Collection<?> c) { throw new IllegalStateException("not supported"); } public Class<T> getType() { return _type; } @Override public String get(int index) { return format(_innerList.get(index)); } @SuppressWarnings("unchecked") public T getRawValue(int index) { return (T) _innerList.get(index); } public Comparable<?> getComparableValue(int index) { return (Comparable<?>) _innerList.get(index); } @Override abstract public int indexOf(Object o); public int indexOfWithOffset(Object value, int offset) { throw new IllegalStateException("not supported"); } public abstract int indexOfWithType(T o); @Override public boolean isEmpty() { return _innerList.isEmpty(); } @Override public Iterator<String> iterator() { final Iterator<?> iter = _innerList.iterator(); return new Iterator<String>() { @Override public boolean hasNext() { return iter.hasNext(); } @Override public String next() { return format(iter.next()); } @Override public void remove() { iter.remove(); } }; } @Override public int lastIndexOf(Object o) { return indexOf(o); } @Override public ListIterator<String> listIterator() { throw new IllegalStateException("not supported"); } @Override public ListIterator<String> listIterator(int index) { throw new IllegalStateException("not supported"); } @Override public boolean remove(Object o) { throw new IllegalStateException("not supported"); } @Override public String remove(int index) { throw new IllegalStateException("not supported"); } @Override public boolean removeAll(Collection<?> c) { throw new IllegalStateException("not supported"); } @Override public boolean retainAll(Collection<?> c) { throw new IllegalStateException("not supported"); } @Override public String set(int index, String element) { throw new IllegalStateException("not supported"); } @Override public int size() { return _innerList.size(); } @Override public List<String> subList(int fromIndex, int toIndex) { throw new IllegalStateException("not supported"); } @Override public Object[] toArray() { Object[] array = _innerList.toArray(); Object[] retArray = new Object[array.length]; for (int i = 0; i < array.length; ++i) { retArray[i] = format(array[i]); } return retArray; } @Override public <R> R[] toArray(R[] a) { List<String> l = subList(0, size()); return l.toArray(a); } public static void main(String[] args) { int numIter = 20000; TermIntList list = new TermIntList(); for (int i = 0; i < numIter; ++i) { list.add(String.valueOf(i)); } long start = System.currentTimeMillis(); List<?> rawList = list.getInnerList(); for (int i = 0; i < numIter; ++i) { rawList.get(i); } long end = System.currentTimeMillis(); System.out.println("took: " + (end - start)); } }