Skip to content

Commit

Permalink
Move prependToList to ListValue and remove copying
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusmelke committed May 27, 2018
1 parent dc39e8d commit 7e8002c
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 46 deletions.
Expand Up @@ -122,7 +122,7 @@ public static <T> T last( Iterator<T> iterator )
* Returns the given iterator's single element or {@code null} if no
* element found. If there is more than one element in the iterator a
* {@link NoSuchElementException} will be thrown.
*
* <p>
* If the {@code iterator} implements {@link Resource} it will be {@link Resource#close() closed}
* in a {@code finally} block after the single item has been retrieved, or failed to be retrieved.
*
Expand All @@ -141,7 +141,7 @@ public static <T> T singleOrNull( Iterator<T> iterator )
* Returns the given iterator's single element. If there are no elements
* or more than one element in the iterator a {@link NoSuchElementException}
* will be thrown.
*
* <p>
* If the {@code iterator} implements {@link Resource} it will be {@link Resource#close() closed}
* in a {@code finally} block after the single item has been retrieved, or failed to be retrieved.
*
Expand Down Expand Up @@ -234,7 +234,7 @@ private static <T> T assertNotNull( Iterator<T> iterator, T result )
* Returns the given iterator's single element or {@code itemIfNone} if no
* element found. If there is more than one element in the iterator a
* {@link NoSuchElementException} will be thrown.
*
* <p>
* If the {@code iterator} implements {@link Resource} it will be {@link Resource#close() closed}
* in a {@code finally} block after the single item has been retrieved, or failed to be retrieved.
*
Expand All @@ -253,7 +253,7 @@ public static <T> T single( Iterator<T> iterator, T itemIfNone )
if ( iterator.hasNext() )
{
throw new NoSuchElementException( "More than one element in " + iterator + ". First element is '"
+ result + "' and the second element is '" + iterator.next() + "'" );
+ result + "' and the second element is '" + iterator.next() + "'" );
}
return result;
}
Expand All @@ -268,14 +268,15 @@ public static <T> T single( Iterator<T> iterator, T itemIfNone )

/**
* Adds all the items in {@code iterator} to {@code collection}.
*
* @param <C> the type of {@link Collection} to add to items to.
* @param <T> the type of items in the collection and iterator.
* @param iterator the {@link Iterator} to grab the items from.
* @param collection the {@link Collection} to add the items to.
* @return the {@code collection} which was passed in, now filled
* with the items from {@code iterator}.
*/
public static <C extends Collection<T>,T> C addToCollection( Iterator<T> iterator,
public static <C extends Collection<T>, T> C addToCollection( Iterator<T> iterator,
C collection )
{
while ( iterator.hasNext() )
Expand All @@ -287,14 +288,15 @@ public static <C extends Collection<T>,T> C addToCollection( Iterator<T> iterato

/**
* Adds all the items in {@code iterator} to {@code collection}.
*
* @param <C> the type of {@link Collection} to add to items to.
* @param <T> the type of items in the collection and iterator.
* @param iterator the {@link Iterator} to grab the items from.
* @param collection the {@link Collection} to add the items to.
* @return the {@code collection} which was passed in, now filled
* with the items from {@code iterator}.
*/
public static <C extends Collection<T>,T> C addToCollectionUnique( Iterator<T> iterator,
public static <C extends Collection<T>, T> C addToCollectionUnique( Iterator<T> iterator,
C collection )
{
while ( iterator.hasNext() )
Expand All @@ -309,20 +311,21 @@ private static <T, C extends Collection<T>> void addUnique( C collection, T item
if ( !collection.add( item ) )
{
throw new IllegalStateException( "Encountered an already added item:" + item +
" when adding items uniquely to a collection:" + collection );
" when adding items uniquely to a collection:" + collection );
}
}

/**
* Adds all the items in {@code iterator} to {@code collection}.
*
* @param <C> the type of {@link Collection} to add to items to.
* @param <T> the type of items in the collection and iterator.
* @param iterable the {@link Iterator} to grab the items from.
* @param collection the {@link Collection} to add the items to.
* @return the {@code collection} which was passed in, now filled
* with the items from {@code iterator}.
*/
public static <C extends Collection<T>,T> C addToCollectionUnique( Iterable<T> iterable,
public static <C extends Collection<T>, T> C addToCollectionUnique( Iterable<T> iterable,
C collection )
{
return addToCollectionUnique( iterable.iterator(), collection );
Expand Down Expand Up @@ -371,6 +374,7 @@ public static <T> long count( Iterator<T> iterator )
/**
* Counts the number of filtered in the {@code iterator} by looping
* through it.
*
* @param <T> the type of items in the iterator.
* @param iterator the {@link Iterator} to count items in.
* @param filter the filter to test items against
Expand Down Expand Up @@ -399,7 +403,7 @@ public static <T> List<T> asList( Iterator<T> iterator )
return addToCollection( iterator, new ArrayList<>() );
}

public static <T, EX extends Exception> List<T> asList( RawIterator<T, EX> iterator ) throws EX
public static <T, EX extends Exception> List<T> asList( RawIterator<T,EX> iterator ) throws EX
{
List<T> out = new ArrayList<>();
while ( iterator.hasNext() )
Expand Down Expand Up @@ -577,13 +581,13 @@ public void remove()
}

@SafeVarargs
public static <T> Iterator<T> iterator( T ... items )
public static <T> Iterator<T> iterator( T... items )
{
return asIterator( items.length, items );
}

@SafeVarargs
public static <T> Iterator<T> iterator( int maxItems, T ... items )
public static <T> Iterator<T> iterator( int maxItems, T... items )
{
return asIterator( maxItems, items );
}
Expand Down Expand Up @@ -619,6 +623,37 @@ else if ( index < appended.length )
};
}

public static <T> Iterator<T> prependTo( Iterator<T> iterator, T... prepended )
{
return new Iterator<T>()
{
private int index;

@Override
public boolean hasNext()
{
return index < prepended.length || iterator.hasNext();
}

@Override
public T next()
{
if ( index < prepended.length )
{
return prepended[index++];
}
else if ( iterator.hasNext() )
{
return iterator.next();
}
else
{
throw new NoSuchElementException();
}
}
};
}

@SuppressWarnings( "unchecked" )
public static <T> ResourceIterator<T> emptyResourceIterator()
{
Expand Down Expand Up @@ -685,18 +720,18 @@ public static <X> Iterator<X> filter( Predicate<? super X> specification, Iterat
return new FilterIterable.FilterIterator<>( i, specification );
}

public static <FROM, TO> Iterator<TO> map( Function<? super FROM, ? extends TO> function, Iterator<FROM> from )
public static <FROM, TO> Iterator<TO> map( Function<? super FROM,? extends TO> function, Iterator<FROM> from )
{
return new MapIterable.MapIterator<>( from, function );
}

public static <FROM, TO, EX extends Exception> RawIterator<TO, EX> map(
ThrowingFunction<? super FROM, ? extends TO, EX> function, RawIterator<FROM, EX> from )
public static <FROM, TO, EX extends Exception> RawIterator<TO,EX> map(
ThrowingFunction<? super FROM,? extends TO,EX> function, RawIterator<FROM,EX> from )
{
return new RawMapIterator<>( from, function );
}

public static <T, EX extends Exception> RawIterator<T, EX> asRawIterator( Iterator<T> iter )
public static <T, EX extends Exception> RawIterator<T,EX> asRawIterator( Iterator<T> iter )
{
return new RawIterator<T,EX>()
{
Expand All @@ -714,14 +749,15 @@ public T next()
};
}

public static <T, EX extends Exception> RawIterator<T, EX> asRawIterator( Stream<T> stream )
public static <T, EX extends Exception> RawIterator<T,EX> asRawIterator( Stream<T> stream )
{
return asRawIterator( stream.iterator() );
}

public static <FROM, TO> Iterator<TO> flatMap( Function<? super FROM, ? extends Iterator<TO>> function, Iterator<FROM> from )
public static <FROM, TO> Iterator<TO> flatMap( Function<? super FROM,? extends Iterator<TO>> function,
Iterator<FROM> from )
{
return new CombiningIterator<>( map(function, from) );
return new CombiningIterator<>( map( function, from ) );
}

@SafeVarargs
Expand Down Expand Up @@ -775,7 +811,7 @@ protected T fetchNextOrNull()

/**
* Create a stream from the given iterator.
* <p>
*
* <b>Note:</b> returned stream needs to be closed via {@link Stream#close()} if the given iterator implements
* {@link Resource}.
*
Expand All @@ -791,7 +827,7 @@ public static <T> Stream<T> stream( Iterator<T> iterator )

/**
* Create a stream from the given iterator with given characteristics.
* <p>
*
* <b>Note:</b> returned stream needs to be closed via {@link Stream#close()} if the given iterator implements
* {@link Resource}.
*
Expand Down
Expand Up @@ -93,11 +93,11 @@ else if ( rhs instanceof ListValue )
}
else if ( lhs instanceof AnyValue )
{
return VirtualValues.prependToList( (ListValue) rhs, (AnyValue) lhs );
return ( (ListValue) rhs).prepend( (AnyValue) lhs );
}
else
{
return VirtualValues.prependToList( (ListValue) rhs, ValueUtils.of( lhs ) );
return ((ListValue) rhs).prepend( ValueUtils.of( lhs ) );
}
}
else if ( lhs instanceof List<?> && rhs instanceof List<?> )
Expand Down
Expand Up @@ -40,7 +40,7 @@ case class Add(a: Expression, b: Expression) extends Expression {
case (x: TextValue, y: TextValue) => Values.stringValue(x.stringValue() + y.stringValue())
case (IsList(x), IsList(y)) => VirtualValues.concat(x, y)
case (IsList(x), y) => x.append(y)
case (x, IsList(y)) => VirtualValues.prependToList(y, x)
case (x, IsList(y)) => y.prepend(x)
case (x: TextValue, y: IntegralValue) => Values.stringValue(x.stringValue() + y.longValue())
case (x: IntegralValue, y: TextValue) => Values.stringValue(x.longValue() + y.stringValue())
case (x: TextValue, y: FloatValue) => Values.stringValue(x.stringValue() + y.doubleValue())
Expand All @@ -57,11 +57,5 @@ case class Add(a: Expression, b: Expression) extends Expression {

def arguments = Seq(a, b)

private def mergeWithCollection(collection: CypherType, singleElement: CypherType):CypherType= {
val collectionType = collection.asInstanceOf[ListType]
val mergedInnerType = collectionType.innerType.leastUpperBound(singleElement)
CTList(mergedInnerType)
}

def symbolTableDependencies = a.symbolTableDependencies ++ b.symbolTableDependencies
}
Expand Up @@ -556,7 +556,7 @@ public AnyValue value( int offset )
{
return base.value( offset );
}
else if ( offset < size + appended.length)
else if ( offset < size + appended.length )
{
return appended[offset - size];
}
Expand All @@ -581,6 +581,62 @@ public Iterator<AnyValue> iterator()
}
}

static final class PrependList extends ListValue
{
private final ListValue base;
private final AnyValue[] prepended;

PrependList( ListValue base, AnyValue[] prepended )
{
this.base = base;
this.prepended = prepended;
}

@Override
public IterationPreference iterationPreference()
{
return base.iterationPreference();
}

@Override
public int size()
{
return prepended.length + base.size();
}

@Override
public AnyValue value( int offset )
{
int size = base.size();
if ( offset < prepended.length )
{
return prepended[offset];
}
else if ( offset < size + prepended.length )
{
return base.value( offset - size );
}
else
{
throw new IndexOutOfBoundsException( offset + " is outside range " + size );
}
}

@Override
public Iterator<AnyValue> iterator()
{
switch ( base.iterationPreference() )
{
case RANDOM_ACCESS:
return super.iterator();
case ITERATION:
return Iterators.prependTo( base.iterator(), prepended );
default:
throw new IllegalStateException( "unknown iteration preference" );
}
}
}

public boolean isEmpty()
{
return size() == 0;
Expand Down Expand Up @@ -793,9 +849,22 @@ public ListValue reverse()
return new ReversedList( this );
}

public ListValue append( AnyValue...value )
public ListValue append( AnyValue...values )
{
return new AppendList( this, value );
if ( values.length == 0 )
{
return this;
}
return new AppendList( this, values );
}

public ListValue prepend( AnyValue...values )
{
if ( values.length == 0 )
{
return this;
}
return new PrependList( this, values );
}

private AnyValue[] iterationAsArray()
Expand Down
Expand Up @@ -80,14 +80,6 @@ public static ListValue concat( ListValue... lists )
return new ListValue.ConcatList( lists );
}

public static ListValue prependToList( ListValue list, AnyValue value )
{
AnyValue[] newValues = new AnyValue[list.size() + 1];
newValues[0] = value;
System.arraycopy( list.asArray(), 0, newValues, 1, list.size() );
return VirtualValues.list( newValues );
}

public static MapValue emptyMap()
{
return EMPTY_MAP;
Expand Down

0 comments on commit 7e8002c

Please sign in to comment.