Skip to content
This repository has been archived by the owner on Oct 8, 2021. It is now read-only.

Commit

Permalink
new LG format for persistence, plus randgraph test loosening (#726)
Browse files Browse the repository at this point in the history
* new LG format for persistence, plus randgraph test loosening

* fixes deprecated syntax (#731)
  • Loading branch information
sbromberger authored Aug 23, 2017
1 parent 024a440 commit 1cce7dc
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 34 deletions.
6 changes: 4 additions & 2 deletions src/persistence/common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ function loadgraph(fn::AbstractString, gname::AbstractString, format::AbstractGr
loadgraph(auto_decompress(io), gname, format)
end
end
loadgraph(fn::AbstractString, gname::AbstractString="graph") = loadgraph(fn, gname, LGFormat())
loadgraph(fn::AbstractString) = loadgraph(fn, "graph", LGFormat())
loadgraph(fn::AbstractString, gname::AbstractString) = loadgraph(fn, gname, LGFormat())
loadgraph(fn::AbstractString, format::AbstractGraphFormat) = loadgraph(fn, "graph", format)


"""
loadgraphs(file, format=LGFormat)
loadgraphs(file, format=LGFormat())
Load multiple graphs from `file` in the format `format`.
Return a dictionary mapping graph name to graph.
Expand Down
92 changes: 64 additions & 28 deletions src/persistence/lg.jl
Original file line number Diff line number Diff line change
@@ -1,30 +1,50 @@
# The format of simplegraph files is as follows:
# a one line header: <num_vertices>, <num_edges>, {"d" | "u"}, <name>
# a one line header: <num_vertices>, <num_edges>, {"d" | "u"}, <name>[, <ver>, <datatype>, <graphcode>]
# - num_vertices is an integer
# - num_edges is an integer
# - "d" for directed graph, "u" for undirected. Note that this
# option does not perform any additional edge construction; it's
# merely used to return the correct type of graph.
# - name is a string
# - ver is optional and is an int
# - datatype is mandatory if version is set and is a string ("UInt8", etc.)
# - graphcode is mandatory if version is set and is a string.
# header followed by a list of (comma-delimited) edges - src,dst.
# Multiple graphs may be present in one file.


struct LGFormat <: AbstractGraphFormat end

struct LGHeader
nv::Int
ne::Int
is_directed::Bool
name::String
ver::Int
dtype::DataType
code::String
end
function show(io::IO, h::LGHeader)
isdir = h.is_directed? "d" : "u"
print(io, "$(h.nv),$(h.ne),$isdir,$(h.name),$(h.ver),$(h.dtype),$(h.code)")
end

LGHeader(nv::Int, ne::Int, is_directed::Bool, name::AbstractString) =
LGHeader(nv, ne, is_directed, name, 1, Int64, "simplegraph")

function _lg_read_one_graph(f::IO, n_v::Integer, n_e::Integer, directed::Bool)
if directed
g = DiGraph(n_v)
function _lg_read_one_graph(f::IO, header::LGHeader)
T = header.dtype
if header.is_directed
g = DiGraph{T}(header.nv)
else
g = Graph(n_v)
g = Graph{T}(header.nv)
end
for i = 1:n_e
for i = 1:header.ne
line = chomp(readline(f))
if length(line) > 0
src_s, dst_s = split(line, r"\s*,\s*")
src = parse(Int, src_s)
dst = parse(Int, dst_s)
src = parse(T, src_s)
dst = parse(T, dst_s)
add_edge!(g, src, dst)
end
end
Expand All @@ -37,6 +57,33 @@ function _lg_skip_one_graph(f::IO, n_e::Integer)
end
end

function _parse_header(s::AbstractString)
addl_info = false
nvstr, nestr, dirundir, graphname = split(s, r"s*,s*", limit=4)
if contains(graphname, ",") # version number and type
graphname, _ver, _dtype, graphcode = split(graphname, r"s*,s*")
ver = parse(Int, _ver)
dtype = eval(Symbol(_dtype))
addl_info = true
end
n_v = parse(Int, nvstr)
n_e = parse(Int, nestr)
dirundir = strip(dirundir)
directed = !(dirundir == "u")
graphname = strip(graphname)
if !addl_info
header = LGHeader(n_v, n_e, directed, graphname)
else
header = LGHeader(n_v, n_e, directed, graphname, ver, dtype, graphcode)
end
return header
end






"""
loadlg_mult(io)
Expand All @@ -49,15 +96,9 @@ function loadlg_mult(io::IO)
if startswith(line, "#") || line == ""
next
else
nvstr, nestr, dirundir, graphname = split(line, r"s*,s*", limit=4)
n_v = parse(Int, nvstr)
n_e = parse(Int, nestr)
dirundir = strip(dirundir)
graphname = strip(graphname)
directed = !(dirundir == "u")

g = _lg_read_one_graph(io, n_v, n_e, directed)
graphs[graphname] = g
header = _parse_header(line)
g = _lg_read_one_graph(io, header)
graphs[header.name] = g
end
end
return graphs
Expand All @@ -67,16 +108,11 @@ function loadlg(io::IO, gname::String)
while !eof(io)
line = strip(chomp(readline(io)))
(startswith(line, "#") || line == "") && continue
nvstr, nestr, dirundir, graphname = split(line, r"s*,s*", limit=4)
n_v = parse(Int, nvstr)
n_e = parse(Int, nestr)
graphname = strip(graphname)
if gname == graphname
dirundir = strip(dirundir)
directed = !(dirundir == "u")
return _lg_read_one_graph(io, n_v, n_e, directed)
header = _parse_header(line)
if gname == header.name
return _lg_read_one_graph(io, header)
else
_lg_skip_one_graph(io, n_e)
_lg_skip_one_graph(io, header.ne)
end
end
error("Graph $gname not found")
Expand All @@ -89,9 +125,9 @@ Write a graph `g` with name `gname` in a proprietary format
to the IO stream designated by `io`. Return 1 (number of graphs written).
"""
function savelg(io::IO, g::AbstractGraph, gname::String)
header = LGHeader(nv(g), ne(g), is_directed(g), gname, 2, eltype(g), "simplegraph")
# write header line
dir = is_directed(g) ? "d" : "u"
line = join([nv(g), ne(g), dir, gname], ",")
line = string(header)
write(io, "$line\n")
# write edges
for e in edges(g)
Expand Down
4 changes: 2 additions & 2 deletions test/generators/randgraphs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,9 @@
@test is_directed(rd)

g = stochastic_block_model(2., 3., [100,100])
@test 4.3 < mean(degree(g)) < 5.8
@test 4.0 < mean(degree(g)) < 6.0
g = stochastic_block_model(3., 4., [100,100,100])
@test 10.3 < mean(degree(g)) < 11.8
@test 10.0 < mean(degree(g)) < 12.0

function generate_nbp_sbm(numedges, sizes)
density = 1
Expand Down
7 changes: 5 additions & 2 deletions test/persistence/persistence.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@
@test (ne(p2), nv(p2)) == (9, 10)

g2 = loadgraph(f)
h2 = loadgraph(f, LGFormat())
j2 = loadgraph(f, "graph")
@test g2 == h2 == j2
@test (ne(g2), nv(g2)) == (9, 10)
# test try block (#701)
@test_throws TypeError savegraph(f, p2; compress=nothing)

(f, fio) = mktemp()
@test length(sprint(savegraph, p1, LGFormat())) == 401
@test length(sprint(savegraph, p2, LGFormat())) == 50
@test length(sprint(savegraph, p1, LGFormat())) == 421
@test length(sprint(savegraph, p2, LGFormat())) == 70
gs = loadgraph(joinpath(testdir, "testdata", "tutte-pathdigraph.jgz"), "pathdigraph")
@test gs == p2
@test_throws ErrorException loadgraph(joinpath(testdir, "testdata", "tutte-pathdigraph.jgz"), "badname")
Expand Down

0 comments on commit 1cce7dc

Please sign in to comment.