Learn more  » Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

vistahigherlearning / logstash   deb

Repository URL to install this package:

/ opt / logstash / vendor / bundle / jruby / 1.9 / gems / extlib-0.9.16 / lib / extlib / lazy_array.rb

require 'extlib/try_dup'

class LazyArray  # borrowed partially from StrokeDB
  include Enumerable

  attr_reader :head, :tail

  def first(*args)
    if lazy_possible?(@head, *args)
      @head.first(*args)
    else
      lazy_load
      @array.first(*args)
    end
  end

  def last(*args)
    if lazy_possible?(@tail, *args)
      @tail.last(*args)
    else
      lazy_load
      @array.last(*args)
    end
  end

  def at(index)
    if index >= 0 && lazy_possible?(@head, index + 1)
      @head.at(index)
    elsif index < 0 && lazy_possible?(@tail, index.abs)
      @tail.at(index)
    else
      lazy_load
      @array.at(index)
    end
  end

  def fetch(*args, &block)
    index = args.first

    if index >= 0 && lazy_possible?(@head, index + 1)
      @head.fetch(*args, &block)
    elsif index < 0 && lazy_possible?(@tail, index.abs)
      @tail.fetch(*args, &block)
    else
      lazy_load
      @array.fetch(*args, &block)
    end
  end

  def values_at(*args)
    accumulator = []

    lazy_possible = args.all? do |arg|
      index, length = extract_slice_arguments(arg)

      if index >= 0 && lazy_possible?(@head, index + length)
        accumulator.concat(head.values_at(*arg))
      elsif index < 0 && lazy_possible?(@tail, index.abs)
        accumulator.concat(tail.values_at(*arg))
      end
    end

    if lazy_possible
      accumulator
    else
      lazy_load
      @array.values_at(*args)
    end
  end

  def index(entry)
    (lazy_possible?(@head) && @head.index(entry)) || begin
      lazy_load
      @array.index(entry)
    end
  end

  def include?(entry)
    (lazy_possible?(@tail) && @tail.include?(entry)) ||
    (lazy_possible?(@head) && @head.include?(entry)) || begin
      lazy_load
      @array.include?(entry)
    end
  end

  def empty?
    (@tail.nil? || @tail.empty?) &&
    (@head.nil? || @head.empty?) && begin
      lazy_load
      @array.empty?
    end
  end

  def any?(&block)
    (lazy_possible?(@tail) && @tail.any?(&block)) ||
    (lazy_possible?(@head) && @head.any?(&block)) || begin
      lazy_load
      @array.any?(&block)
    end
  end

  def [](*args)
    index, length = extract_slice_arguments(*args)

    if length == 1 && args.size == 1 && args.first.kind_of?(Integer)
      return at(index)
    end

    if index >= 0 && lazy_possible?(@head, index + length)
      @head[*args]
    elsif index < 0 && lazy_possible?(@tail, index.abs - 1 + length)
      @tail[*args]
    else
      lazy_load
      @array[*args]
    end
  end

  alias slice []

  def slice!(*args)
    index, length = extract_slice_arguments(*args)

    if index >= 0 && lazy_possible?(@head, index + length)
      @head.slice!(*args)
    elsif index < 0 && lazy_possible?(@tail, index.abs - 1 + length)
      @tail.slice!(*args)
    else
      lazy_load
      @array.slice!(*args)
    end
  end

  def []=(*args)
    index, length = extract_slice_arguments(*args[0..-2])

    if index >= 0 && lazy_possible?(@head, index + length)
      @head.[]=(*args)
    elsif index < 0 && lazy_possible?(@tail, index.abs - 1 + length)
      @tail.[]=(*args)
    else
      lazy_load
      @array.[]=(*args)
    end
  end

  alias splice []=

  def reverse
    dup.reverse!
  end

  def reverse!
    # reverse without kicking if possible
    if loaded?
      @array = @array.reverse
    else
      @head, @tail = @tail.reverse, @head.reverse

      proc = @load_with_proc

      @load_with_proc = lambda do |v|
        proc.call(v)
        v.instance_variable_get(:@array).reverse!
      end
    end

    self
  end

  def <<(entry)
    if loaded?
      lazy_load
      @array << entry
    else
      @tail << entry
    end
    self
  end

  def concat(other)
    if loaded?
      lazy_load
      @array.concat(other)
    else
      @tail.concat(other)
    end
    self
  end

  def push(*entries)
    if loaded?
      lazy_load
      @array.push(*entries)
    else
      @tail.push(*entries)
    end
    self
  end

  def unshift(*entries)
    if loaded?
      lazy_load
      @array.unshift(*entries)
    else
      @head.unshift(*entries)
    end
    self
  end

  def insert(index, *entries)
    if index >= 0 && lazy_possible?(@head, index)
      @head.insert(index, *entries)
    elsif index < 0 && lazy_possible?(@tail, index.abs - 1)
      @tail.insert(index, *entries)
    else
      lazy_load
      @array.insert(index, *entries)
    end
    self
  end

  def pop(*args)
    if lazy_possible?(@tail, *args)
      @tail.pop(*args)
    else
      lazy_load
      @array.pop(*args)
    end
  end

  def shift(*args)
    if lazy_possible?(@head, *args)
      @head.shift(*args)
    else
      lazy_load
      @array.shift(*args)
    end
  end

  def delete_at(index)
    if index >= 0 && lazy_possible?(@head, index + 1)
      @head.delete_at(index)
    elsif index < 0 && lazy_possible?(@tail, index.abs)
      @tail.delete_at(index)
    else
      lazy_load
      @array.delete_at(index)
    end
  end

  def delete_if(&block)
    if loaded?
      lazy_load
      @array.delete_if(&block)
    else
      @reapers << block
      @head.delete_if(&block)
      @tail.delete_if(&block)
    end
    self
  end

  def replace(other)
    mark_loaded
    @array.replace(other)
    self
  end

  def clear
    mark_loaded
    @array.clear
    self
  end

  def to_a
    lazy_load
    @array.to_a
  end

  alias to_ary to_a

  def load_with(&block)
    @load_with_proc = block
    self
  end

  def loaded?
    @loaded == true
  end

  def kind_of?(klass)
    super || @array.kind_of?(klass)
  end

  alias is_a? kind_of?

  def respond_to?(method, include_private = false)
    super || @array.respond_to?(method)
  end

  def freeze
    if loaded?
      @array.freeze
    else
      @head.freeze
      @tail.freeze
    end
    @frozen = true
    self
  end

  def frozen?
    @frozen == true
  end

  def ==(other)
    if equal?(other)
      return true
    end

    unless other.respond_to?(:to_ary)
      return false
    end

    # if necessary, convert to something that can be compared
    other = other.to_ary unless other.respond_to?(:[])

    cmp?(other, :==)
  end

  def eql?(other)
    if equal?(other)
      return true
    end

    unless other.class.equal?(self.class)
      return false
    end

    cmp?(other, :eql?)
  end

  def lazy_possible?(list, need_length = 1)
    !loaded? && need_length <= list.size
Loading ...