1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
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
|