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

com.metamx.common.guava.LimitedSequence Maven / Gradle / Ivy

The newest version!
package com.metamx.common.guava;

import com.google.common.base.Preconditions;

import java.io.IOException;

/**
 * Limits the number of inputs from this sequence.  For example, if there are actually 100 things in the sequence
 * but the limit is set to 10, the Sequence will act as if it only had 10 things.
 */
public class LimitedSequence extends YieldingSequenceBase
{
  private final Sequence baseSequence;
  private final int limit;

  public LimitedSequence(
      Sequence baseSequence,
      int limit
  )
  {
    Preconditions.checkNotNull(baseSequence);
    Preconditions.checkArgument(limit >= 0, "limit is negative");

    this.baseSequence = baseSequence;
    this.limit = limit;
  }

  @Override
  public  Yielder toYielder(OutType initValue, YieldingAccumulator accumulator)
  {
    final LimitedYieldingAccumulator limitedAccumulator = new LimitedYieldingAccumulator(accumulator);
    final Yielder subYielder = baseSequence.toYielder(initValue, limitedAccumulator);
    return new LimitedYielder(subYielder, limitedAccumulator);
  }

  private class LimitedYielder implements Yielder
  {
    private final Yielder subYielder;
    private final LimitedYieldingAccumulator limitedAccumulator;

    public LimitedYielder(
        Yielder subYielder,
        LimitedYieldingAccumulator limitedAccumulator
    )
    {
      this.subYielder = subYielder;
      this.limitedAccumulator = limitedAccumulator;
    }

    @Override
    public OutType get()
    {
      return subYielder.get();
    }

    @Override
    public Yielder next(OutType initValue)
    {
      final Yielder next = subYielder.next(initValue);
      if (! limitedAccumulator.withinThreshold()) {
        return Yielders.done(next.get(), next);
      }
      return new LimitedYielder(LimitedYielder.this, limitedAccumulator);
    }

    @Override
    public boolean isDone()
    {
      return false;
    }

    @Override
    public void close() throws IOException
    {
      subYielder.close();
    }
  }

  private class LimitedYieldingAccumulator extends DelegatingYieldingAccumulator
  {
    int count;

    public LimitedYieldingAccumulator(YieldingAccumulator accumulator)
    {
      super(accumulator);
      count = 0;
    }

    @Override
    public OutType accumulate(OutType accumulated, T in)
    {
      ++count;

      if (! withinThreshold()) {
        yield();
      }

      return super.accumulate(accumulated, in);
    }

    private boolean withinThreshold() {
      return count < limit;
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy