All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.druid.java.util.common.guava.Sequences Maven / Gradle / Ivy

There is a newer version: 0.12.3
Show newest version
/*
 * Licensed to Metamarkets Group Inc. (Metamarkets) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. Metamarkets licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package io.druid.java.util.common.guava;

import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.Lists;

import java.io.Closeable;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Executor;

/**
 */
public class Sequences
{

  private static final EmptySequence EMPTY_SEQUENCE = new EmptySequence();

  public static  Sequence simple(final Iterable iterable)
  {
    return new BaseSequence<>(
        new BaseSequence.IteratorMaker>()
        {
          @Override
          public Iterator make()
          {
            return iterable.iterator();
          }

          @Override
          public void cleanup(Iterator iterFromMake)
          {

          }
        }
    );
  }

  @SuppressWarnings("unchecked")
  public static  Sequence empty()
  {
    return (Sequence) EMPTY_SEQUENCE;
  }

  public static  Sequence concat(Sequence... sequences)
  {
    return concat(Arrays.asList(sequences));
  }

  public static  Sequence concat(Iterable> sequences)
  {
    return concat(Sequences.simple(sequences));
  }

  public static  Sequence concat(Sequence> sequences)
  {
    return new ConcatSequence<>(sequences);
  }

  public static  Sequence map(Sequence sequence, Function fn)
  {
    return new MappedSequence<>(sequence, fn);
  }

  public static  Sequence filter(Sequence sequence, Predicate pred)
  {
    return new FilteredSequence<>(sequence, pred);
  }

  public static  Sequence limit(final Sequence sequence, final int limit)
  {
    return new LimitedSequence<>(sequence, limit);
  }

  public static  Sequence withBaggage(final Sequence seq, final Closeable baggage)
  {
    Preconditions.checkNotNull(baggage, "baggage");
    return wrap(seq, new SequenceWrapper()
    {
      @Override
      public void after(boolean isDone, Throwable thrown) throws Exception
      {
        baggage.close();
      }
    });
  }

  /**
   * Allows to execute something before, after or around the processing of the given sequence. See documentation to
   * {@link SequenceWrapper} methods for some details.
   */
  public static  Sequence wrap(Sequence seq, SequenceWrapper wrapper)
  {
    Preconditions.checkNotNull(seq, "seq");
    Preconditions.checkNotNull(wrapper, "wrapper");
    return new WrappingSequence<>(seq, wrapper);
  }

  public static  Sequence withEffect(final Sequence  seq, final Runnable effect, final Executor exec)
  {
    // Uses YieldingSequenceBase to be able to execute the effect if all elements of the wrapped seq are processed
    // (i. e. it "is done"), but the yielder of the underlying seq throws some exception from close(). This logic could
    // be found in ExecuteWhenDoneYielder.close(). If accumulate() is implemented manually in this anonymous class
    // instead of extending YieldingSequenceBase, it's not possible to distinguish exception thrown during elements
    // processing in accumulate() of the underlying seq, from exception thrown after all elements are processed,
    // in close().
    return new YieldingSequenceBase()
    {
      @Override
      public  Yielder toYielder(OutType initValue, YieldingAccumulator accumulator)
      {
        return new ExecuteWhenDoneYielder<>(seq.toYielder(initValue, accumulator), effect, exec);
      }
    };
  }

  // This will materialize the entire sequence in memory. Use at your own risk.
  public static  Sequence sort(final Sequence sequence, final Comparator comparator)
  {
    List seqList = Sequences.toList(sequence, Lists.newArrayList());
    Collections.sort(seqList, comparator);
    return simple(seqList);
  }

  public static > ListType toList(Sequence seq, ListType list)
  {
    return seq.accumulate(list, Accumulators.list());
  }

  private static class EmptySequence implements Sequence
  {
    @Override
    public  OutType accumulate(OutType initValue, Accumulator accumulator)
    {
      return initValue;
    }

    @Override
    public  Yielder toYielder(OutType initValue, YieldingAccumulator accumulator)
    {
      return Yielders.done(initValue, null);
    }
  }
}