aboutsummaryrefslogblamecommitdiff
path: root/shard/lib/data/data.ex
blob: 8d2b277dd749f43b4122c9e93c0fb762d923b8f6 (plain) (tree)
1
2
3
4
5
6
7
8
9
10


                   






                                                                                        

     
         
                                                                    
                                                                  
     

                                                     

     


                                                     



                                   


                                 



                                       


                               





                                                                           


                                                        



                                        
         
                                                             









                          
                                          











                                             
                         

                                      
   
defmodule SData do
  @moduledoc """
  Utility functions

  Compare functions are functions that compares stored items and provides a total order.
  They must return:
    - `:after` if the first argument is more recent
    - `:duplicate` if the two items are the same
    - `:before` if the first argument is older
  These functions must only return :duplicate for equal items.
  """

  @doc"""
  Calculate the hash of an Erlang term by first converting it to its
  binary representation. Equivalent to `bin_hash(term_bin(term))`.
  """
  def term_hash(term, algo \\ :sha256) do
    :crypto.hash(algo, (:erlang.term_to_binary term))
  end

  @doc"""
  Convert any Erlang term to a binary representation.
  """
  def term_bin(term) do
  	:erlang.term_to_binary term
  end

  @doc"""
  Calculate the hash of a binary.
  """
  def bin_hash(bin, algo \\ :sha256) do
    :crypto.hash(algo, bin)
  end

  @doc"""
  Calculate the hash of a file.
  """
  def file_hash(path, algo \\ :sha256) do
    File.stream!(path, [], 65536)
    |> Enum.reduce(:crypto.hash_init(algo), &(:crypto.hash_update(&2, &1)))
    |> :crypto.hash_final()
  end

  @doc"""
  Recover an Erlang term from its binary representation.
  """
  def term_unbin(bin) do
    :erlang.binary_to_term(bin, [:safe])
  end

  @doc"""
  Compare function for arbitrary terms using the Erlang order
  """
  def cmp_term(a, b) do
    cond do
      a > b -> :after
      a < b -> :before
      a == b -> :duplicate
    end
  end

  @doc"""
  Compare function for timestamped strings
  """
  def cmp_ts_str({ts1, str1}, {ts2, str2}) do
    cond do
      ts1 > ts2 -> :after
      ts1 < ts2 -> :before
      str1 > str2 -> :after
      str1 < str2 -> :before
      true -> :duplicate
    end
  end

  @doc"""
  Merge function for nils
  """
  def merge_true(true, true), do: true
end