#1 ✓invalid
bahuvrihi

Tuple Rewrite?

Reported by bahuvrihi | September 23rd, 2008 @ 10:53 AM

Perhaps the internals of External could get rewritten to use the Rubinius Array class. Some inspection indicates that primarily this would involve making a subclass of Tuple. This is a sketch of the required interface:


# kernel/core/array.rb:# depends on: class.rb enumerable.rb tuple.rb kernel.rb
# kernel/core/array.rb:  def tuple=(t) ; @tuple = t ; end
# kernel/core/array.rb:    ary.tuple = Tuple.new 8
# kernel/core/array.rb:        tuple = Tuple.new(ary.size + 10)
# kernel/core/array.rb:        tuple.copy_from ary.tuple, ary.start, 0
# kernel/core/array.rb:        @tuple = tuple
# kernel/core/array.rb:        @tuple = Tuple.new(count + 10)
# kernel/core/array.rb:          count.times { |i| @tuple.put i, yield(i) }
# kernel/core/array.rb:          count.times { |i| @tuple.put i, obj }
# kernel/core/array.rb:      return @tuple.at(@start + start)
# kernel/core/array.rb:        if newtotal > @tuple.fields - @start
# kernel/core/array.rb:          nt.copy_from @tuple, @start, 0 # FIXME: double copy of right part
# kernel/core/array.rb:          @tuple = nt
# kernel/core/array.rb:          @tuple.put(@start+t, @tuple.at(@start+f))
# kernel/core/array.rb:        @tuple.put(@start+idx+i, el)
# kernel/core/array.rb:          @tuple.put(t, @tuple.at(f))
# kernel/core/array.rb:        while t < @tuple.fields
# kernel/core/array.rb:          @tuple.put(t, nil)
# kernel/core/array.rb:    reallocate(nt) if @tuple.size < nt
# kernel/core/array.rb:    @tuple.put @start + idx, ent
# kernel/core/array.rb:    reallocate nt if @tuple.size < nt
# kernel/core/array.rb:    @tuple.put @start + @total, obj
# kernel/core/array.rb:    size.times { |i| return false unless @tuple.at(@start + i) == other.at(i) }
# kernel/core/array.rb:    @tuple.at @start + idx
# kernel/core/array.rb:    @tuple = Tuple.new(1)
# kernel/core/array.rb:      if @tuple.at(i).nil?
# kernel/core/array.rb:          if @tuple.at(i) != nil
# kernel/core/array.rb:            @tuple.put j, @tuple.at(i)
# kernel/core/array.rb:        # OK to leave tuple size larger?
# kernel/core/array.rb:    tuple = Tuple.new size
# kernel/core/array.rb:    tuple.copy_from @tuple, @start, 0 if @total > 0
# kernel/core/array.rb:    tuple.copy_from ary.tuple, ary.start, @total
# kernel/core/array.rb:    @tuple = tuple
# kernel/core/array.rb:    # Leaves the tuple to the original size still
# kernel/core/array.rb:      if @tuple.at(i) == obj
# kernel/core/array.rb:          if @tuple.at(i) != obj
# kernel/core/array.rb:            @tuple.put(j, @tuple.at(i))
# kernel/core/array.rb:    obj = @tuple.at(@start + idx)
# kernel/core/array.rb:    idx.upto(@total - 2) { |i| @tuple.put(@start + i, @tuple.at(@start + i + 1)) }
# kernel/core/array.rb:    @tuple.put(@start + @total - 1, nil)
# kernel/core/array.rb:    # Leaves the tuple to the original size still
# kernel/core/array.rb:      if yield @tuple.at(i)
# kernel/core/array.rb:          unless yield @tuple.at(i)
# kernel/core/array.rb:            @tuple.put(j, @tuple.at(i))
# kernel/core/array.rb:      reallocate(nt) if @tuple.size < nt
# kernel/core/array.rb:      start.upto(finish) { |i|  @tuple.put @start + i, yield(i) }
# kernel/core/array.rb:      start.upto(finish) { |i|  @tuple.put @start + i, obj }
# kernel/core/array.rb:    @total.times { |i| return true if @tuple.at(@start + i) == obj }
# kernel/core/array.rb:    @total.times { |i| return i if @tuple.at(@start + i) == obj }
# kernel/core/array.rb:    # TODO Reduce tuple if there are a lot of free slots
# kernel/core/array.rb:    @tuple = other.tuple.dup
# kernel/core/array.rb:    tuple = Tuple.new @total
# kernel/core/array.rb:      tuple.put i, @tuple.at(j)
# kernel/core/array.rb:    @tuple = tuple
# kernel/core/array.rb:    obj = @tuple.at(@start)
# kernel/core/array.rb:      slot << @tuple.at(@start + i)
# kernel/core/array.rb:      @tuple.put @start, values.pop
# kernel/core/array.rb:    @tuple = @tuple.shifted(values.size)
# kernel/core/array.rb:      @tuple.put i, val
# kernel/core/array.rb:    return if at_least < @tuple.size
# kernel/core/array.rb:    new_size = @tuple.size * 2
# kernel/core/array.rb:    tuple = Tuple.new(new_size)
# kernel/core/array.rb:    tuple.copy_from @tuple, @start, 0     # Swap over old data
# kernel/core/array.rb:    @tuple = tuple
# kernel/core/array.rb:      low, mid, hi = @tuple.at(left_end), @tuple.at(middle), @tuple.at(right_end)
# kernel/core/array.rb:        semi_left = @tuple.at(left_end + ((middle - left_end) / 2))
# kernel/core/array.rb:        semi_right = @tuple.at(middle + ((right_end - middle) / 2))
# kernel/core/array.rb:        semi_right = @tuple.at(middle + ((right_end - middle) / 2))
# kernel/core/array.rb:            @tuple.swap(rand(segment_size), rand(segment_size))
# kernel/core/array.rb:      @tuple.swap(left_end, right_end)  if (hi <=> low) < 0
# kernel/core/array.rb:        semi_right = @tuple.at(middle + ((right_end - middle) / 2))
# kernel/core/array.rb:            @tuple.swap(rand(segment_size), rand(segment_size))
# kernel/core/array.rb:      @tuple.swap(left_end, right_end)  if (hi <=> low) < 0
# kernel/core/array.rb:      @tuple.swap(left_end, middle)     if (mid <=> low) < 0
# kernel/core/array.rb:      @tuple.swap(middle, right_end)    if (hi <=> mid) < 0
# kernel/core/array.rb:      pivot = @tuple.at(middle)
# kernel/core/array.rb:      @tuple.swap(right_end, middle)  # Known position to help partition three ways
# kernel/core/array.rb:          case @tuple.at(left) <=> pivot
# kernel/core/array.rb:            @tuple.swap(left, (eqls_left += 1))
# kernel/core/array.rb:        semi_right = @tuple.at(middle + ((right_end - middle) / 2))
# kernel/core/array.rb:            @tuple.swap(rand(segment_size), rand(segment_size))
# kernel/core/array.rb:      @tuple.swap(left_end, right_end)  if (hi <=> low) < 0
# kernel/core/array.rb:        semi_right = @tuple.at(middle + ((right_end - middle) / 2))
# kernel/core/array.rb:            @tuple.swap(rand(segment_size), rand(segment_size))
# kernel/core/array.rb:      @tuple.swap(left_end, right_end)  if (hi <=> low) < 0
# kernel/core/array.rb:      @tuple.swap(left_end, middle)     if (mid <=> low) < 0
# kernel/core/array.rb:      @tuple.swap(middle, right_end)    if (hi <=> mid) < 0
# kernel/core/array.rb:      pivot = @tuple.at(middle)
# kernel/core/array.rb:      @tuple.swap(right_end, middle)  # Known position to help partition three ways
# kernel/core/array.rb:          case @tuple.at(left) <=> pivot
# kernel/core/array.rb:            @tuple.swap(left, (eqls_left += 1))
# kernel/core/array.rb:          case @tuple.at(right) <=> pivot
# kernel/core/array.rb:            @tuple.swap(right, (eqls_right -= 1))
# kernel/core/array.rb:        @tuple.swap(left, right)
# kernel/core/array.rb:      @tuple.swap(left, right_end)
# kernel/core/array.rb:        @tuple.swap(eqls_left, left)
# kernel/core/array.rb:          @tuple.swap(eqls_right, right)
# kernel/core/array.rb:      low, mid, hi = @tuple.at(left_end), @tuple.at(middle), @tuple.at(right_end)
# kernel/core/array.rb:        semi_left = @tuple.at(left_end + ((middle - left_end) / 2))
# kernel/core/array.rb:        semi_right = @tuple.at(middle + ((right_end - middle) / 2))
# kernel/core/array.rb:            @tuple.swap(rand(segment_size), rand(segment_size))
# kernel/core/array.rb:      @tuple.swap(left_end, right_end)  if block.call(hi, low)  < 0kernel/core/array.rb:      @tuple.swap(left_end, middle)     if block.call(mid, low) < 0
# kernel/core/array.rb:      @tuple.swap(middle, right_end)    if block.call(hi, mid)  < 0
# kernel/core/array.rb:      pivot = @tuple.at(middle)
# kernel/core/array.rb:      @tuple.swap(right_end, middle)  # Known position to help partition three ways
# kernel/core/array.rb:          case block.call(@tuple.at(left), pivot)
# kernel/core/array.rb:            @tuple.swap(left, (eqls_left += 1))kernel/core/array.rb:          case block.call(@tuple.at(right), pivot)
# kernel/core/array.rb:            @tuple.swap(right, (eqls_right -= 1))
# kernel/core/array.rb:        @tuple.swap(left, right)
# kernel/core/array.rb:      @tuple.swap(left, right_end)
# kernel/core/array.rb:        @tuple.swap(eqls_left, left)
# kernel/core/array.rb:          @tuple.swap(eqls_right, right)
# kernel/core/array.rb:      while j > 0 and (@tuple.at(j - 1) <=> @tuple.at(j)) > 0
# kernel/core/array.rb:        @tuple.swap(j, (j - 1))
# kernel/core/array.rb:      while j > 0 and block.call(@tuple.at(j - 1), @tuple.at(j)) > 0
# kernel/core/array.rb:        @tuple.swap(j, (j - 1))
# kernel/core/block_environment.rb:  # First field of the tuple holds a boolean indicating if the context is from
# kernel/core/compiled_method.rb:  # literals tuple stores literals from
# kernel/core/compiled_method.rb:  # - a tuple of symbols naming required args (or nil if none)kernel/core/compiled_method.rb:  # - a tuple of symbols naming optional args (or nil if none)
# kernel/core/compiled_method.rb:  # Tuple of tuples. Inner tuples contain

class TupleInterface

  def self.[](*args)
    sz = args.size
    tup = new(sz)
    i = 0
    while i < sz
      tup.put i, args[i]
      i += 1
    end

    return tup
  end

  # Makes a new instance of self that can
  # accommodate size values.
  def initialize(size)
  end

  # Sets the value at index to value.
  def put(index, value)
  end

  # Retrieves the value at index.
  def at(index)
  end

  # Returns the number of values in self.
  def size
  end

  # Alias for size
  def fields
  end

  # Alias for size
  def length
  end

  def empty?
    size == 0
  end

  def first
    at(0)
  end

  def last
    at(fields-1)
  end

  # Duplicates self
  def dup
  end

  # ?
  # def shifted
  # end

  def shift
    return self unless fields > 0
    t = Tuple.new(fields-1)
    t.copy_from self, 1, 0
    return t
  end

  # Swap elements of the two indexes.
  def swap(a, b)
    temp = at(a)
    put(a, at(b))
    put(b, temp)
  end

  # def enlarge(size)
  #   if size > fields()
  #     t = Tuple.new(size)
  #     t.copy_from self, 0, 0
  #     return t
  #   end
  #
  #   return self
  # end

  # def copy_from
  # end

  def each
    i = 0
    t = fields
    while i < t
      yield self.at(i)
      i += 1
    end
    self
  end

  def + o
    t = Tuple.new(size + o.size)
    each_with_index { |e, i| t[i] = e }
    o.each_with_index { |e, i| t[i + size] = e }
    t
  end

  def to_s
    "#<Tuple:0x#{object_id.to_s(16)} #{fields} elements>"
  end

  def inspect
    str = "#<Tuple"
    if fields != 0
      str << ": #{join(", ", :inspect)}"
    end
    str << ">"
    return str
  end

  def join(sep, meth=:to_s)
    join_upto(sep, fields, meth)
  end

  def join_upto(sep, count, meth=:to_s)
    str = ""
    return str if count == 0 or empty?
    count = fields if count >= fields
    count -= 1
    i = 0
    while i < count
      str << at(i).__send__(meth)
      str << sep.dup
      i += 1
    end
    str << at(count).__send__(meth)
    return str
  end

  def ===(other)
    return false unless Tuple === other and fields == other.fields
    i = 0
    while i < fields
      return false unless at(i) === other.at(i)
      i += 1
    end
    true
  end

  def to_a
    ary = []
    each do |ent|
      ary << ent
    end
    return ary
  end
end

Comments and changes to this ticket

  • bahuvrihi

    bahuvrihi September 23rd, 2008 @ 03:02 PM

    • State changed from “new” to “invalid”

    Likely more trouble than it's worth. The real savings would only be on easy-to-implement methods and may require significant re-writes.

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

Indexing and array-like access to data stored on disk (rather than in memory).

People watching this ticket

Pages