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 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.
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).