Make Version#<=> allocation-free

This commit is contained in:
Jack Nagel 2015-03-27 20:07:50 -04:00
parent b378dfa7dc
commit 9b75afcf4a

View File

@ -201,8 +201,33 @@ class Version
return 1 if head? && !other.head? return 1 if head? && !other.head?
return -1 if !head? && other.head? return -1 if !head? && other.head?
max = [tokens.length, other.tokens.length].max ltokens = tokens
pad_to(max) <=> other.pad_to(max) rtokens = other.tokens
max = max(ltokens.length, rtokens.length)
l = r = 0
while l < max
a = ltokens[l] || NULL_TOKEN
b = rtokens[r] || NULL_TOKEN
if a == b
l += 1
r += 1
next
elsif a.numeric? && b.numeric?
return a <=> b
elsif a.numeric?
return 1 if a > NULL_TOKEN
l += 1
elsif b.numeric?
return -1 if b > NULL_TOKEN
r += 1
else
return a <=> b
end
end
return 0
end end
alias_method :eql?, :== alias_method :eql?, :==
@ -219,24 +244,16 @@ class Version
attr_reader :version attr_reader :version
def begins_with_numeric?
tokens.first.numeric?
end
def pad_to(length)
if begins_with_numeric?
nums, rest = tokens.partition(&:numeric?)
nums.fill(NULL_TOKEN, nums.length, length - tokens.length)
nums.concat(rest)
else
tokens.dup.fill(NULL_TOKEN, tokens.length, length - tokens.length)
end
end
def tokens def tokens
@tokens ||= tokenize @tokens ||= tokenize
end end
private
def max(a, b)
a > b ? a : b
end
def tokenize def tokenize
version.scan(SCAN_PATTERN).map! do |token| version.scan(SCAN_PATTERN).map! do |token|
case token case token