Fix missing range sanitize

pull/7493/head
Qwerty5Uiop 2 years ago
parent b4c960ef5d
commit 5e632ae17a
  1. 51
      apps/explorer/lib/explorer/utility/missing_block_range.ex

@ -100,8 +100,6 @@ defmodule Explorer.Utility.MissingBlockRange do
Enum.map(batch, &delete_range/1) Enum.map(batch, &delete_range/1)
end end
def save_batch([]), do: {0, nil}
def save_batch(batch) do def save_batch(batch) do
batch batch
|> List.wrap() |> List.wrap()
@ -148,28 +146,39 @@ defmodule Explorer.Utility.MissingBlockRange do
|> update([r], set: [from_number: r.to_number, to_number: r.from_number]) |> update([r], set: [from_number: r.to_number, to_number: r.from_number])
|> Repo.update_all([]) |> Repo.update_all([])
__MODULE__ {last_range, merged_ranges} = delete_and_merge_ranges()
|> join(:inner, [r], r1 in __MODULE__,
on: save_batch((last_range && [last_range | merged_ranges]) || [])
((r1.from_number <= r.from_number and r1.from_number >= r.to_number) or end
(r1.to_number <= r.from_number and r1.to_number >= r.to_number)) and r1.id != r.id
) defp delete_and_merge_ranges do
|> select([r, r1], [r, r1]) delete_intersecting_ranges()
|> Repo.all() |> Enum.sort_by(& &1.from_number, &>=/2)
|> Enum.map(&Enum.sort/1) |> Enum.reduce({nil, []}, fn %{from_number: from, to_number: to}, {last_range, result} ->
|> Enum.uniq() cond do
|> Enum.map(fn [range_1, range_2] -> is_nil(last_range) -> {from..to, result}
Repo.delete(range_2) Range.disjoint?(from..to, last_range) -> {from..to, [last_range | result]}
true -> {Range.new(max(from, last_range.first), min(to, last_range.last)), result}
range_1 end
|> changeset(%{
from_number: max(range_1.from_number, range_2.from_number),
to_number: min(range_1.to_number, range_2.to_number)
})
|> Repo.update()
end) end)
end end
defp delete_intersecting_ranges do
{_, intersecting_ranges} =
__MODULE__
|> join(:inner, [r], r1 in __MODULE__,
on:
((r1.from_number <= r.from_number and r1.from_number >= r.to_number) or
(r1.to_number <= r.from_number and r1.to_number >= r.to_number) or
(r.from_number <= r1.from_number and r.from_number >= r1.to_number) or
(r.to_number <= r1.from_number and r.to_number >= r1.to_number)) and r1.id != r.id
)
|> select([r, r1], r)
|> Repo.delete_all()
intersecting_ranges
end
def min_max_block_query do def min_max_block_query do
from(r in __MODULE__, select: %{min: min(r.to_number), max: max(r.from_number)}) from(r in __MODULE__, select: %{min: min(r.to_number), max: max(r.from_number)})
end end

Loading…
Cancel
Save