Skip to content

Instantly share code, notes, and snippets.

@willhbr
Created February 25, 2020 10:44
Show Gist options
  • Save willhbr/c22b5522e52aeb5e50f2f9e1cce99203 to your computer and use it in GitHub Desktop.
Save willhbr/c22b5522e52aeb5e50f2f9e1cce99203 to your computer and use it in GitHub Desktop.
module MultiIndexable
macro index(type, *args, set_args = [] of Nil)
@%lock = Mutex.new
{% for arg in args %}
@values_by_{{ arg.var }} = Hash({{ arg.type }}, {{ type }}).new
def [](*, {{ arg.var }} key : {{ arg.type }}) : {{ type }}
@values_by_{{ arg.var }}[key]
end
def []?(*, {{ arg.var }} key : {{ arg.type }}) : {{ type }}?
@values_by_{{ arg.var }}[key]?
end
def find_by_{{ arg.var }}(key : {{ arg.type }}) : {{ type }}?
self[{{ arg.var }}: key]?
end
{% end %}
{% for arg in set_args %}
@values_by_{{ arg.var }} = Hash({{ arg.type }}, Set({{ type }})).new
def [](*, {{ arg.var }} key : {{ arg.type }}) : Set({{ type }})
@values_by_{{ arg.var }}[key] ||= Set({{ type }}).new
end
def []?(*, {{ arg.var }} key : {{ arg.type }}) : Set({{ type }})
@values_by_{{ arg.var }}[key]?
end
def find_by_{{ arg.var }}(key : {{ arg.type }}) : Set({{ type }})
self[{{ arg.var }}: key]
end
{% end %}
def add(item : {{ type }})
@%lock.synchronize do
{% for arg in args %}
@values_by_{{ arg.var }}[item.{{ arg.var }}] = item
{% end %}
{% for arg in set_args %}
s = @values_by_{{ arg.var }}[item.{{ arg.var }}] ||= Set({{ type }}).new
s.add(item)
{% end %}
end
end
def remove(item : {{ type }})
@%lock.synchronize do
{% for arg in args %}
@values_by_{{ arg.var }}.delete item.{{ arg.var }}
{% end %}
end
end
def remove_all(items : Set({{ type }}))
items.each do |i|
remove(i)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment