Skip to content

Instantly share code, notes, and snippets.

@jgaskins
Created January 17, 2017 19:14
Show Gist options
  • Save jgaskins/c0f5e8c2ab81470f89bfe10482e02138 to your computer and use it in GitHub Desktop.
Save jgaskins/c0f5e8c2ab81470f89bfe10482e02138 to your computer and use it in GitHub Desktop.
Pure-Ruby port of MRI's Hash class
class MyHash
include Enumerable
def initialize(data=nil, capacity=11)
@capacity = capacity
@data = Array.new(capacity) { [] }
@keys = []
return unless data
data.each do |key, value|
self[key] = value
end
end
def []= key, value
hash = key.hash % @capacity
@data[hash].each_with_index do |pair, index|
if pair[0].eql? key
return pair[1] = value
end
end
@keys << key
@data[hash] << [key, value]
rehash if @keys.length > @capacity * 5
value
end
def [] key
hash = key.hash % @capacity
@data.fetch(hash).each_with_index do |(k, v), index|
if k.eql? key
return @data[hash][index][1]
end
end
end
def inspect
str = '{'
str << @keys
.map { |key| "#{key.inspect}=>#{self[key].inspect}" }
.join(', ')
str << '}'
end
def keys
@keys
end
def each
@keys.each do |key|
yield key, self[key]
end
end
def delete key
hash = key.hash % @capacity
index = @data[hash].index { |pair| pair[0].eql? key }
return unless index
@keys.delete key
pair = @data[hash].delete_at index
pair[1]
end
def rehash
data = @keys.map { |key| [key, self[key]] }
@capacity = @keys.length
@data = Array.new(@capacity) { [] }
data.each do |pair|
hash = pair[0].hash % @capacity
@data[hash] << pair
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment