def binary_search_by_directory(dir, key)
Innodb::Stats.increment :binary_search_by_directory
return nil if dir.empty?
mid = ((dir.size-1) / 2)
rec = record(dir[mid])
if Innodb.debug?
puts "binary_search_by_directory: page=%i, level=%i, dir.size=%i, dir[%i]=(%s)" % [
offset,
level,
dir.size,
mid,
rec.key_string,
]
end
if rec.header[:type] == :infimum
return linear_search_from_cursor(record_cursor(rec.next), key)
end
case rec.compare_key(key)
when 0
Innodb::Stats.increment :binary_search_by_directory_exact_match
rec
when +1
if dir.size > 2
Innodb::Stats.increment :binary_search_by_directory_recurse_right
binary_search_by_directory(dir[mid...dir.size], key)
else
next_rec = record(dir[mid+1])
next_key = next_rec && next_rec.compare_key(key)
if dir.size == 1 || next_key == -1 || next_key == 0
Innodb::Stats.increment :binary_search_by_directory_linear_search
linear_search_from_cursor(record_cursor(rec.offset), key)
elsif next_key == +1
Innodb::Stats.increment :binary_search_by_directory_linear_search
linear_search_from_cursor(record_cursor(next_rec.offset), key)
else
nil
end
end
when -1
if dir.size == 1
Innodb::Stats.increment :binary_search_by_directory_empty_result
nil
else
Innodb::Stats.increment :binary_search_by_directory_recurse_left
binary_search_by_directory(dir[0...mid], key)
end
end
end