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 * 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 * element found. If there is more than one element in the iterator a
* {@link NoSuchElementException} will be thrown. * {@link NoSuchElementException} will be thrown.
* * <p>
* If the {@code iterator} implements {@link Resource} it will be {@link Resource#close() closed} * 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. * 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 * Returns the given iterator's single element. If there are no elements
* or more than one element in the iterator a {@link NoSuchElementException} * or more than one element in the iterator a {@link NoSuchElementException}
* will be thrown. * will be thrown.
* * <p>
* If the {@code iterator} implements {@link Resource} it will be {@link Resource#close() closed} * 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. * 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 * 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 * element found. If there is more than one element in the iterator a
* {@link NoSuchElementException} will be thrown. * {@link NoSuchElementException} will be thrown.
* * <p>
* If the {@code iterator} implements {@link Resource} it will be {@link Resource#close() closed} * 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. * 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() ) if ( iterator.hasNext() )
{ {
throw new NoSuchElementException( "More than one element in " + iterator + ". First element is '" 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; 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}. * Adds all the items in {@code iterator} to {@code collection}.
*
* @param <C> the type of {@link Collection} to add to items to. * @param <C> the type of {@link Collection} to add to items to.
* @param <T> the type of items in the collection and iterator. * @param <T> the type of items in the collection and iterator.
* @param iterator the {@link Iterator} to grab the items from. * @param iterator the {@link Iterator} to grab the items from.
* @param collection the {@link Collection} to add the items to. * @param collection the {@link Collection} to add the items to.
* @return the {@code collection} which was passed in, now filled * @return the {@code collection} which was passed in, now filled
* with the items from {@code iterator}. * 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 ) C collection )
{ {
while ( iterator.hasNext() ) 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}. * Adds all the items in {@code iterator} to {@code collection}.
*
* @param <C> the type of {@link Collection} to add to items to. * @param <C> the type of {@link Collection} to add to items to.
* @param <T> the type of items in the collection and iterator. * @param <T> the type of items in the collection and iterator.
* @param iterator the {@link Iterator} to grab the items from. * @param iterator the {@link Iterator} to grab the items from.
* @param collection the {@link Collection} to add the items to. * @param collection the {@link Collection} to add the items to.
* @return the {@code collection} which was passed in, now filled * @return the {@code collection} which was passed in, now filled
* with the items from {@code iterator}. * 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 ) C collection )
{ {
while ( iterator.hasNext() ) 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 ) ) if ( !collection.add( item ) )
{ {
throw new IllegalStateException( "Encountered an already added item:" + 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}. * Adds all the items in {@code iterator} to {@code collection}.
*
* @param <C> the type of {@link Collection} to add to items to. * @param <C> the type of {@link Collection} to add to items to.
* @param <T> the type of items in the collection and iterator. * @param <T> the type of items in the collection and iterator.
* @param iterable the {@link Iterator} to grab the items from. * @param iterable the {@link Iterator} to grab the items from.
* @param collection the {@link Collection} to add the items to. * @param collection the {@link Collection} to add the items to.
* @return the {@code collection} which was passed in, now filled * @return the {@code collection} which was passed in, now filled
* with the items from {@code iterator}. * 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 ) C collection )
{ {
return addToCollectionUnique( iterable.iterator(), 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 * Counts the number of filtered in the {@code iterator} by looping
* through it. * through it.
*
* @param <T> the type of items in the iterator. * @param <T> the type of items in the iterator.
* @param iterator the {@link Iterator} to count items in. * @param iterator the {@link Iterator} to count items in.
* @param filter the filter to test items against * @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<>() ); 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<>(); List<T> out = new ArrayList<>();
while ( iterator.hasNext() ) while ( iterator.hasNext() )
Expand Down Expand Up @@ -577,13 +581,13 @@ public void remove()
} }


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


@SafeVarargs @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 ); 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" ) @SuppressWarnings( "unchecked" )
public static <T> ResourceIterator<T> emptyResourceIterator() 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 ); 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 ); return new MapIterable.MapIterator<>( from, function );
} }


public static <FROM, TO, EX extends Exception> RawIterator<TO, EX> map( public static <FROM, TO, EX extends Exception> RawIterator<TO,EX> map(
ThrowingFunction<? super FROM, ? extends TO, EX> function, RawIterator<FROM, EX> from ) ThrowingFunction<? super FROM,? extends TO,EX> function, RawIterator<FROM,EX> from )
{ {
return new RawMapIterator<>( from, function ); 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>() 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() ); 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 @SafeVarargs
Expand Down Expand Up @@ -775,7 +811,7 @@ protected T fetchNextOrNull()


/** /**
* Create a stream from the given iterator. * 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 * <b>Note:</b> returned stream needs to be closed via {@link Stream#close()} if the given iterator implements
* {@link Resource}. * {@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. * 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 * <b>Note:</b> returned stream needs to be closed via {@link Stream#close()} if the given iterator implements
* {@link Resource}. * {@link Resource}.
* *
Expand Down
Expand Up @@ -93,11 +93,11 @@ else if ( rhs instanceof ListValue )
} }
else if ( lhs instanceof AnyValue ) else if ( lhs instanceof AnyValue )
{ {
return VirtualValues.prependToList( (ListValue) rhs, (AnyValue) lhs ); return ( (ListValue) rhs).prepend( (AnyValue) lhs );
} }
else else
{ {
return VirtualValues.prependToList( (ListValue) rhs, ValueUtils.of( lhs ) ); return ((ListValue) rhs).prepend( ValueUtils.of( lhs ) );
} }
} }
else if ( lhs instanceof List<?> && rhs instanceof List<?> ) 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 (x: TextValue, y: TextValue) => Values.stringValue(x.stringValue() + y.stringValue())
case (IsList(x), IsList(y)) => VirtualValues.concat(x, y) case (IsList(x), IsList(y)) => VirtualValues.concat(x, y)
case (IsList(x), y) => x.append(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: TextValue, y: IntegralValue) => Values.stringValue(x.stringValue() + y.longValue())
case (x: IntegralValue, y: TextValue) => Values.stringValue(x.longValue() + y.stringValue()) case (x: IntegralValue, y: TextValue) => Values.stringValue(x.longValue() + y.stringValue())
case (x: TextValue, y: FloatValue) => Values.stringValue(x.stringValue() + y.doubleValue()) 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) 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 def symbolTableDependencies = a.symbolTableDependencies ++ b.symbolTableDependencies
} }
Expand Up @@ -556,7 +556,7 @@ public AnyValue value( int offset )
{ {
return base.value( offset ); return base.value( offset );
} }
else if ( offset < size + appended.length) else if ( offset < size + appended.length )
{ {
return appended[offset - size]; 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() public boolean isEmpty()
{ {
return size() == 0; return size() == 0;
Expand Down Expand Up @@ -793,9 +849,22 @@ public ListValue reverse()
return new ReversedList( this ); 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() private AnyValue[] iterationAsArray()
Expand Down
Expand Up @@ -80,14 +80,6 @@ public static ListValue concat( ListValue... lists )
return new ListValue.ConcatList( 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() public static MapValue emptyMap()
{ {
return EMPTY_MAP; return EMPTY_MAP;
Expand Down

0 comments on commit 7e8002c

Please sign in to comment.