Skip to content

Instantly share code, notes, and snippets.

@rbwendt
Created November 4, 2016 20:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rbwendt/0f917bac6c3de6d779797e80d99262ed to your computer and use it in GitHub Desktop.
Save rbwendt/0f917bac6c3de6d779797e80d99262ed to your computer and use it in GitHub Desktop.
multi key map
class DynamicFlow::DimensionValue
include Comparable
attr_accessor :dimension, :value
def initialize(dimension, value)
@dimension = dimension
@value = value
end
def <=>(dv)
dimension <=> dv.dimension && value <=> dv.value
end
end
require_relative '../../test_helper'
class DimensionValueTest < ActiveSupport::TestCase
def test_accessors
dv = DynamicFlow::DimensionValue.new(:a, :b)
assert_equal [:a, :b], [dv.dimension, dv.value]
end
def test_spaceship
assert DynamicFlow::DimensionValue.new(:a, :b) == DynamicFlow::DimensionValue.new(:a, :b)
end
end
class DynamicFlow::MultiKeyMap
def initialize
@map = {}
end
# keys should be a collection os DimensionValues
# value can be anything but for our tree we will be using Vertex values
def put(keys, value)
keys.each do |key|
@map[key.dimension] ||= {}
@map[key.dimension][key.value] ||= []
@map[key.dimension][key.value] << value
end
end
# keys is a collection of DimensionValues
def get(keys)
candidates = keys.reduce({}) do |a, key|
a[@map[key.dimension][key.value]] ||= []
a[@map[key.dimension][key.value]] << key
a
end
max_matches = candidates.values.map(&:size).max
binding.pry
candidates.keep_if{|k, v| v.size.equal?(max_matches)}.to_a
end
end
require_relative '../../test_helper'
class MultiKeyMapTest < ActiveSupport::TestCase
def test_one_condition
mkm = DynamicFlow::MultiKeyMap.new
conditions = [DynamicFlow::DimensionValue.new(:a, :b)]
mkm.put(conditions, :x)
assert_equal [[[:x], conditions]], mkm.get(conditions)
end
def test_two_conditions
mkm = DynamicFlow::MultiKeyMap.new
conditions = [DynamicFlow::DimensionValue.new(:a, :b), DynamicFlow::DimensionValue.new(:a, :c)]
mkm.put(conditions, :y)
assert_equal [[[:y], conditions]], mkm.get(conditions)
end
def test_two_matches
mkm = DynamicFlow::MultiKeyMap.new
condition_1 = DynamicFlow::DimensionValue.new(:a, :b)
condition_2 = DynamicFlow::DimensionValue.new(:a, :c)
conditions = [condition_1, condition_2]
mkm.put([condition_1], :z)
mkm.put([condition_2], :z)
assert_equal [[[:z], [condition_1, condition_2]]], mkm.get(conditions)
end
def test_most_specific
# this test currently fails.
mkm = DynamicFlow::MultiKeyMap.new
condition_d1 = DynamicFlow::DimensionValue.new(:d, 1)
condition_t1 = DynamicFlow::DimensionValue.new(:t, 1)
conditions = [condition_d1, condition_t1]
mkm.put([condition_d1, condition_t1], :z)
mkm.put([condition_d1], :z)
assert_equal [[[:z], [condition_d1, condition_t1]]], mkm.get(conditions)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment