Packages

Modules for 1:1 reconciliation matching and deduplication

Current section

Files

Jump to
pair2 lib index.ex
Raw

lib/index.ex

defmodule Pair2.Index do
@moduledoc """
Maintains an ETS map of attribute values to ID values.
For instance, an index of mobile numbers will list ID's
of all records with a given mobile number.
"""
def new(attr) do
:ets.new(attr, [:set, :protected, :named_table])
end
def delete(attr) do
:ets.delete(attr)
end
def put(_attr, nil, _id), do: nil
def put(_attr, "", _id), do: nil
def put(_attr, '', _id), do: nil
def put(attr, serial, id) do
case :ets.lookup(attr, serial) do
[] ->
:ets.insert_new(attr, {serial, [id]})
[{serial, list}] ->
:ets.insert(attr, {serial, [id|list]})
end
end
def get(attr, serial) do
case :ets.lookup(attr, serial) do
[] ->
[]
[{_, list}] ->
list
end
end
def load_indexes(list, indexed_attrs) do
# Create an index for each indexed attribute.
Enum.each(indexed_attrs, fn(attr) ->
new(attr)
Enum.each(list, fn(r) -> put(attr, Map.fetch!(r, attr), r.id) end)
end)
# Create an index for the full map
new(:full)
Enum.each(list, fn(r) -> put(:full, r.id, r) end)
:ok
end
def close_indexes(indexed_attrs) do
Enum.each(indexed_attrs, &(delete&1))
delete(:full)
:ok
end
def get_potential_matches(target_map, indexed_attrs) do
indexed_attrs
|> Enum.reduce([], fn(attr, acc) ->
target_val = Map.fetch!(target_map, attr)
acc ++ get(attr, target_val)
end) # IDs
|> Enum.uniq
|> Enum.map(fn(id) ->
get(:full, id)
end) # Full maps
|> List.flatten
end
end