Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
graph-tool
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
43
Issues
43
List
Boards
Labels
Service Desk
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Tiago Peixoto
graph-tool
Commits
91872c4b
Commit
91872c4b
authored
Sep 14, 2015
by
Tiago Peixoto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve performance of Graph.add_vertex() and Graph.add_edge()
parent
f7020a22
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
63 additions
and
53 deletions
+63
-53
src/graph/graph_filtering.cc
src/graph/graph_filtering.cc
+5
-4
src/graph/graph_filtering.hh
src/graph/graph_filtering.hh
+45
-5
src/graph/graph_python_interface.cc
src/graph/graph_python_interface.cc
+8
-4
src/graph/graph_python_interface.hh
src/graph/graph_python_interface.hh
+3
-13
src/graph_tool/__init__.py
src/graph_tool/__init__.py
+2
-27
No files found.
src/graph/graph_filtering.cc
View file @
91872c4b
...
...
@@ -109,12 +109,13 @@ boost::any
check_filtered
(
const
Graph
&
g
,
const
EdgeFilter
&
edge_filter
,
const
bool
&
e_invert
,
bool
e_active
,
size_t
max_eindex
,
const
VertexFilter
&
vertex_filter
,
const
bool
&
v_invert
,
bool
v_active
,
GraphInterface
&
gi
,
bool
reverse
,
bool
directed
)
bool
v_active
,
GraphInterface
&
gi
,
bool
reverse
,
bool
directed
)
{
#ifndef NO_GRAPH_FILTERING
MaskFilter
<
EdgeFilter
>
e_filter
(
edge_filter
,
e_invert
);
MaskFilter
<
VertexFilter
>
v_filter
(
vertex_filter
,
v_invert
);
MaskFilter
<
EdgeFilter
>
e_filter
(
const_cast
<
EdgeFilter
&>
(
edge_filter
),
e_invert
);
MaskFilter
<
VertexFilter
>
v_filter
(
const_cast
<
VertexFilter
&>
(
vertex_filter
),
v_invert
);
if
(
e_active
)
{
...
...
src/graph/graph_filtering.hh
View file @
91872c4b
...
...
@@ -141,7 +141,7 @@ class MaskFilter
public:
typedef
typename
boost
::
property_traits
<
DescriptorProperty
>::
value_type
value_t
;
MaskFilter
(){}
MaskFilter
(
const
DescriptorProperty
&
filtered_property
,
bool
invert
)
MaskFilter
(
DescriptorProperty
&
filtered_property
,
bool
invert
)
:
_filtered_property
(
&
filtered_property
),
_invert
(
invert
)
{}
template
<
class
Descriptor
>
...
...
@@ -151,13 +151,15 @@ public:
return
get
(
*
_filtered_property
,
std
::
forward
<
Descriptor
>
(
d
))
^
_invert
;
// This is a critical section. It will be called for every vertex
// or edge in the graph, every time they're iterated
// through.
// This is a critical section. It will be called for every vertex or
// edge in the graph, every time they're iterated through.
}
DescriptorProperty
&
get_filter
()
{
return
*
_filtered_property
;
}
bool
is_inverted
()
{
return
_invert
;
}
private:
const
DescriptorProperty
*
_filtered_property
;
DescriptorProperty
*
_filtered_property
;
bool
_invert
;
};
...
...
@@ -554,4 +556,42 @@ retrieve_graph_view(GraphInterface& gi, Graph& init)
}
//graph_tool namespace
// Overload add_vertex() and add_edge() to filtered graphs, so that the new
// descriptors are always valid
namespace
boost
{
template
<
class
Graph
,
class
EdgeProperty
,
class
VertexProperty
>
typename
graph_traits
<
filtered_graph
<
Graph
,
graph_tool
::
detail
::
MaskFilter
<
EdgeProperty
>
,
graph_tool
::
detail
::
MaskFilter
<
VertexProperty
>>>::
vertex_descriptor
add_vertex
(
boost
::
filtered_graph
<
Graph
,
graph_tool
::
detail
::
MaskFilter
<
EdgeProperty
>
,
graph_tool
::
detail
::
MaskFilter
<
VertexProperty
>>&
g
)
{
auto
v
=
add_vertex
(
const_cast
<
Graph
&>
(
g
.
m_g
));
auto
&
filt
=
g
.
m_vertex_pred
.
get_filter
();
auto
cfilt
=
filt
.
get_checked
();
cfilt
[
v
]
=
!
g
.
m_vertex_pred
.
is_inverted
();
return
v
;
}
template
<
class
Graph
,
class
EdgeProperty
,
class
VertexProperty
,
class
Vertex
>
std
::
pair
<
typename
graph_traits
<
filtered_graph
<
Graph
,
graph_tool
::
detail
::
MaskFilter
<
EdgeProperty
>
,
graph_tool
::
detail
::
MaskFilter
<
VertexProperty
>>>::
edge_descriptor
,
bool
>
add_edge
(
Vertex
s
,
Vertex
t
,
filtered_graph
<
Graph
,
graph_tool
::
detail
::
MaskFilter
<
EdgeProperty
>
,
graph_tool
::
detail
::
MaskFilter
<
VertexProperty
>>&
g
)
{
auto
e
=
add_edge
(
s
,
t
,
const_cast
<
Graph
&>
(
g
.
m_g
));
auto
&
filt
=
g
.
m_edge_pred
.
get_filter
();
auto
cfilt
=
filt
.
get_checked
();
cfilt
[
e
.
first
]
=
!
g
.
m_edge_pred
.
is_inverted
();
return
e
;
}
}
// namespace boost
#endif // FILTERING_HH
src/graph/graph_python_interface.cc
View file @
91872c4b
...
...
@@ -71,7 +71,11 @@ struct get_vertex_soft
void
operator
()(
Graph
&
g
,
GraphInterface
&
gi
,
size_t
i
,
python
::
object
&
v
)
const
{
std
::
shared_ptr
<
Graph
>
gp
=
retrieve_graph_view
<
Graph
>
(
gi
,
g
);
v
=
python
::
object
(
PythonVertex
<
Graph
>
(
gp
,
vertex
(
i
,
g
)));
if
(
i
<
num_vertices
(
g
))
v
=
python
::
object
(
PythonVertex
<
Graph
>
(
gp
,
vertex
(
i
,
g
)));
else
v
=
python
::
object
(
PythonVertex
<
Graph
>
(
gp
,
graph_traits
<
Graph
>::
null_vertex
()));
}
};
...
...
@@ -96,10 +100,10 @@ struct get_vertex_hard
}
};
python
::
object
get_vertex
(
GraphInterface
&
gi
,
size_t
i
)
python
::
object
get_vertex
(
GraphInterface
&
gi
,
size_t
i
,
bool
use_index
)
{
python
::
object
v
;
if
(
gi
.
is_vertex_filter_active
()
)
if
(
!
use_index
)
run_action
<>
()(
gi
,
std
::
bind
(
get_vertex_hard
(),
placeholders
::
_1
,
std
::
ref
(
gi
),
i
,
std
::
ref
(
v
)))();
...
...
@@ -138,7 +142,7 @@ struct add_new_vertex
python
::
object
&
new_v
)
const
{
std
::
shared_ptr
<
Graph
>
gp
=
retrieve_graph_view
<
Graph
>
(
gi
,
g
);
if
(
n
>
1
)
if
(
n
!=
1
)
{
for
(
size_t
i
=
0
;
i
<
n
;
++
i
)
add_vertex
(
g
);
...
...
src/graph/graph_python_interface.hh
View file @
91872c4b
...
...
@@ -363,19 +363,9 @@ public:
other
.
check_valid
();
Graph
&
g
=
*
std
::
shared_ptr
<
Graph
>
(
_g
);
OGraph
&
og
=
*
std
::
shared_ptr
<
OGraph
>
(
other
.
_g
);
auto
s
=
source
(
_e
,
g
);
auto
t
=
target
(
_e
,
g
);
auto
os
=
source
(
other
.
_e
,
og
);
auto
ot
=
target
(
other
.
_e
,
og
);
if
(
not
is_directed
::
apply
<
Graph
>::
type
::
value
||
not
is_directed
::
apply
<
OGraph
>::
type
::
value
)
{
if
(
t
<
s
)
std
::
swap
(
s
,
t
);
if
(
ot
<
os
)
std
::
swap
(
os
,
ot
);
}
return
s
<
os
&&
t
<
ot
;
auto
eindex
=
get
(
boost
::
edge_index_t
(),
g
);
auto
eindex2
=
get
(
boost
::
edge_index_t
(),
og
);
return
eindex
[
_e
]
<
eindex2
[
other
.
_e
];
}
template
<
class
OGraph
>
bool
operator
<=
(
const
PythonEdge
<
OGraph
>&
other
)
const
{
return
*
this
<
other
||
*
this
==
other
;}
...
...
src/graph_tool/__init__.py
View file @
91872c4b
...
...
@@ -1674,17 +1674,7 @@ class Graph(object):
the necessary number of missing vertices are inserted, and the new
vertex is returned.
"""
vfilt
=
self
.
get_vertex_filter
()
if
vfilt
[
0
]
is
None
or
not
use_index
:
v
=
libcore
.
get_vertex
(
self
.
__graph
,
int
(
i
))
else
:
try
:
self
.
set_vertex_filter
(
None
)
v
=
libcore
.
get_vertex
(
self
.
__graph
,
int
(
i
))
if
v
.
is_valid
()
and
vfilt
[
0
][
v
]
==
vfilt
[
1
]:
raise
ValueError
(
"Invalid vertex index: %d (filtered out)"
%
int
(
i
))
finally
:
self
.
set_vertex_filter
(
vfilt
[
0
],
vfilt
[
1
])
v
=
libcore
.
get_vertex
(
self
.
__graph
,
int
(
i
),
use_index
)
if
not
v
.
is_valid
():
if
add_missing
:
self
.
add_vertex
(
int
(
i
)
-
self
.
num_vertices
(
use_index
)
+
1
)
...
...
@@ -1706,9 +1696,6 @@ class Graph(object):
"""
s
=
self
.
vertex
(
int
(
s
))
t
=
self
.
vertex
(
int
(
t
))
if
s
is
None
or
t
is
None
:
return
None
efilt
=
self
.
get_edge_filter
()
edges
=
libcore
.
get_edge
(
self
.
__graph
,
int
(
s
),
int
(
t
),
all_edges
)
if
add_missing
and
len
(
edges
)
==
0
:
edges
.
append
(
self
.
add_edge
(
s
,
t
))
...
...
@@ -1740,17 +1727,9 @@ class Graph(object):
vertices are inserted and an iterator over the new vertices is returned.
This operation is :math:`O(n)`.
"""
if
n
==
0
:
return
(
None
for
i
in
range
(
0
,
0
))
v
=
libcore
.
add_vertex
(
self
.
__graph
,
n
)
vfilt
=
self
.
get_vertex_filter
()
if
vfilt
[
0
]
is
not
None
:
N
=
self
.
num_vertices
(
True
)
vfilt
[
0
].
a
[
N
-
n
:
N
]
=
not
vfilt
[
1
]
if
n
<=
1
:
if
n
==
1
:
return
v
else
:
pos
=
self
.
num_vertices
(
True
)
-
n
...
...
@@ -1841,14 +1820,10 @@ class Graph(object):
If ``add_missing == True``, the source and target vertices are included
in the graph if they don't yet exist.
"""
e
=
libcore
.
add_edge
(
self
.
__graph
,
self
.
vertex
(
int
(
source
),
add_missing
=
add_missing
),
self
.
vertex
(
int
(
target
),
add_missing
=
add_missing
))
efilt
=
self
.
get_edge_filter
()
if
efilt
[
0
]
is
not
None
:
efilt
[
0
][
e
]
=
not
efilt
[
1
]
return
e
def
remove_edge
(
self
,
edge
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment