Skip to content

Commit 63f6202

Browse files
authored
Fix bug in is_arranged with variable length Tuples
2 parents 225e8a5 + 5f27dd6 commit 63f6202

File tree

3 files changed

+59
-26
lines changed

3 files changed

+59
-26
lines changed

src/abstractdatagraph.jl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -289,9 +289,9 @@ function get(graph::AbstractDataGraph, vertex, default)
289289
end
290290

291291
function getindex(graph::AbstractDataGraph, edge::AbstractEdge)
292-
is_edge_arranged = is_arranged(graph, edge)
293-
data = edge_data(graph)[arrange(is_edge_arranged, edge)]
294-
return reverse_data_direction(is_edge_arranged, graph, data)
292+
is_edge_arranged_ = is_edge_arranged(graph, edge)
293+
data = edge_data(graph)[arrange(is_edge_arranged_, edge)]
294+
return reverse_data_direction(is_edge_arranged_, graph, data)
295295
end
296296

297297
# Support syntax `g[v1 => v2]`
@@ -300,9 +300,9 @@ function getindex(graph::AbstractDataGraph, edge::Pair)
300300
end
301301

302302
function get(graph::AbstractDataGraph, edge::AbstractEdge, default)
303-
is_edge_arranged = is_arranged(graph, edge)
304-
data = get(edge_data(graph), arrange(is_edge_arranged, edge), default)
305-
return reverse_data_direction(is_edge_arranged, graph, data)
303+
is_edge_arranged_ = is_edge_arranged(graph, edge)
304+
data = get(edge_data(graph), arrange(is_edge_arranged_, edge), default)
305+
return reverse_data_direction(is_edge_arranged_, graph, data)
306306
end
307307

308308
function get(graph::AbstractDataGraph, edge::Pair, default)
@@ -332,9 +332,9 @@ function setindex!(graph::AbstractDataGraph, data, vertex)
332332
end
333333

334334
function setindex!(graph::AbstractDataGraph, data, edge::AbstractEdge)
335-
is_edge_arranged = is_arranged(graph, edge)
336-
arranged_edge = arrange(is_edge_arranged, edge)
337-
arranged_data = reverse_data_direction(is_edge_arranged, graph, data)
335+
is_edge_arranged_ = is_edge_arranged(graph, edge)
336+
arranged_edge = arrange(is_edge_arranged_, edge)
337+
arranged_data = reverse_data_direction(is_edge_arranged_, graph, data)
338338
set!(edge_data(graph), arranged_edge, arranged_data)
339339
return graph
340340
end

src/arrange.jl

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,46 @@
55
# stored in directed AbstractDataGraph types (which by default returns nothing,
66
# indicating not to automatically store data in both directions)
77
# TODO: Use `Graphs.is_ordered`? https://juliagraphs.org/Graphs.jl/v1.7/core_functions/core/#Graphs.is_ordered-Tuple{AbstractEdge}
8-
@traitfn function is_arranged(graph::AbstractDataGraph::IsDirected, src, dst)
9-
return true
10-
end
11-
12-
@traitfn function is_arranged(graph::AbstractDataGraph::(!IsDirected), src, dst)
8+
function is_arranged(src, dst)
139
if !hasmethod(isless, typeof.((src, dst)))
14-
src_hash = hash(src)
15-
dst_hash = hash(dst)
16-
if (src_hash == dst_hash) && (src dst)
17-
@warn "Hash collision when arranging vertices to extract edge data. Setting or extracting data may be ill-defined."
18-
end
19-
return isless(src_hash, dst_hash)
10+
return is_arranged_by_hash(src, dst)
2011
end
2112
return isless(src, dst)
2213
end
2314

24-
@traitfn function is_arranged(graph::AbstractDataGraph::(!IsDirected), t1::Tuple, t2::Tuple)
15+
function is_arranged_by_hash(src, dst)
16+
src_hash = hash(src)
17+
dst_hash = hash(dst)
18+
if (src_hash == dst_hash) && (src dst)
19+
@warn "Hash collision when arranging vertices to extract edge data. Setting or extracting data may be ill-defined."
20+
end
21+
return isless(src_hash, dst_hash)
22+
end
23+
24+
# https://github.com/JuliaLang/julia/blob/v1.8.5/base/tuple.jl#L470-L482
25+
is_arranged(::Tuple{}, ::Tuple{}) = false
26+
is_arranged(::Tuple{}, ::Tuple) = true
27+
is_arranged(::Tuple, ::Tuple{}) = false
28+
29+
function is_arranged(t1::Tuple, t2::Tuple)
2530
a, b = t1[1], t2[1]
26-
return is_arranged(graph, a, b) ||
27-
(isequal(a, b) && is_arranged(graph, Base.tail(t1), Base.tail(t2)))
31+
return is_arranged(a, b) || (isequal(a, b) && is_arranged(Base.tail(t1), Base.tail(t2)))
32+
end
33+
34+
@traitfn function is_edge_arranged(graph::AbstractDataGraph::IsDirected, src, dst)
35+
return true
36+
end
37+
38+
@traitfn function is_edge_arranged(graph::AbstractDataGraph::(!IsDirected), src, dst)
39+
return is_arranged(src, dst)
2840
end
2941

30-
function is_arranged(graph::AbstractDataGraph, edge::AbstractEdge)
31-
return is_arranged(graph, src(edge), dst(edge))
42+
function is_edge_arranged(graph::AbstractDataGraph, edge::AbstractEdge)
43+
return is_edge_arranged(graph, src(edge), dst(edge))
3244
end
3345

3446
function arrange(graph::AbstractDataGraph, edge::AbstractEdge)
35-
return arrange(is_arranged(graph, edge), edge)
47+
return arrange(is_edge_arranged(graph, edge), edge)
3648
end
3749

3850
function arrange(is_arranged::Bool, edge::AbstractEdge)

test/runtests.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ using NamedGraphs
55
using Suppressor
66
using Test
77

8+
using DataGraphs: is_arranged
9+
810
@testset "DataGraphs.jl" begin
911
@testset "Examples" begin
1012
examples_path = joinpath(pkgdir(DataGraphs), "examples")
@@ -15,6 +17,25 @@ using Test
1517
end
1618
end
1719

20+
@testset "is_arranged" begin
21+
for (a, b) in [
22+
(1, 2),
23+
([1], [2]),
24+
([1, 2], [2, 1]),
25+
([1, 2], [2]),
26+
([2], [2, 1]),
27+
((1,), (2,)),
28+
((1, 2), (2, 1)),
29+
((1, 2), (2,)),
30+
((2,), (2, 1)),
31+
("X", 1),
32+
(("X",), (1, 2)),
33+
]
34+
@test is_arranged(a, b)
35+
@test !is_arranged(b, a)
36+
end
37+
end
38+
1839
@testset "Basics" begin
1940
g = grid((4,))
2041
dg = DataGraph{<:Any,String,Symbol}(g)

0 commit comments

Comments
 (0)