Created
November 4, 2016 20:01
-
-
Save rbwendt/0f917bac6c3de6d779797e80d99262ed to your computer and use it in GitHub Desktop.
multi key map
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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