22 #ifndef GRAPHLAB_GRAPH_BUILTIN_PARSERS_HPP
23 #define GRAPHLAB_GRAPH_BUILTIN_PARSERS_HPP
29 #if defined(__cplusplus) && __cplusplus >= 201103L
32 #include <boost/config/warning_disable.hpp>
33 #include <boost/spirit/include/qi.hpp>
34 #include <boost/spirit/include/phoenix_core.hpp>
35 #include <boost/spirit/include/phoenix_operator.hpp>
36 #include <boost/spirit/include/phoenix_stl.hpp>
39 #include <graphlab/util/stl_util.hpp>
41 #include <graphlab/serialization/serialization_includes.hpp>
48 namespace builtin_parsers {
62 template <
typename Graph>
63 bool snap_parser(Graph& graph,
const std::string& srcfilename,
64 const std::string& str) {
65 if (str.empty())
return true;
66 else if (str[0] ==
'#') {
67 std::cout << str << std::endl;
69 size_t source, target;
71 source = strtoul(str.c_str(), &targetptr, 10);
72 if (targetptr == NULL)
return false;
73 target = strtoul(targetptr, NULL, 10);
74 if(source != target) graph.add_edge(source, target);
85 template <
typename Graph>
86 bool tsv_parser(Graph& graph,
const std::string& srcfilename,
87 const std::string& str) {
88 if (str.empty())
return true;
89 size_t source, target;
91 source = strtoul(str.c_str(), &targetptr, 10);
92 if (targetptr == NULL)
return false;
93 target = strtoul(targetptr, NULL, 10);
94 if(source != target) graph.add_edge(source, target);
100 #if defined(__cplusplus) && __cplusplus >= 201103L
103 template <
typename Graph>
104 bool adj_parser(Graph& graph,
const std::string& srcfilename,
105 const std::string& line) {
107 if(line.empty())
return true;
108 std::stringstream strm(line);
112 if (strm.fail())
return false;
114 if (strm.fail())
return true;
117 while (strm.good()) {
120 if (strm.fail())
break;
121 if (source != target) graph.add_edge(source, target);
124 if (n != nadded)
return false;
130 template <
typename Graph>
131 bool adj_parser(Graph& graph,
const std::string& srcfilename,
132 const std::string& line) {
134 if(line.empty())
return true;
137 namespace qi = boost::spirit::qi;
138 namespace ascii = boost::spirit::ascii;
139 namespace phoenix = boost::phoenix;
142 std::vector<vertex_id_type> targets;
143 const bool success = qi::phrase_parse
144 (line.begin(), line.end(),
147 qi::ulong_[phoenix::ref(source) = qi::_1] >> -qi::char_(
",") >>
148 qi::ulong_[phoenix::ref(ntargets) = qi::_1] >> -qi::char_(
",") >>
149 *(qi::ulong_[phoenix::push_back(phoenix::ref(targets), qi::_1)] % -qi::char_(
","))
155 if(!success || ntargets != targets.size()) {
156 logstream(
LOG_ERROR) <<
"Parse error in vertex prior parser." << std::endl;
159 for(
size_t i = 0; i < targets.size(); ++i) {
160 if(source != targets[i]) graph.add_edge(source, targets[i]);
166 template <
typename Graph>
168 typedef typename Graph::vertex_type vertex_type;
169 typedef typename Graph::edge_type edge_type;
170 std::string save_vertex(vertex_type) {
return ""; }
171 std::string save_edge(edge_type e) {
172 return tostr(e.source().id()) +
"\t" +
tostr(e.target().id()) +
"\n";
179 template <
typename Graph>
180 struct graphjrl_writer{
181 typedef typename Graph::vertex_type vertex_type;
182 typedef typename Graph::edge_type edge_type;
189 static std::string escape_newline(
charstream& strm) {
191 char *ptr = strm->c_str();
192 size_t strmlen = strm->size();
193 for (
size_t i = 0;i < strmlen; ++i) {
194 ctr += (ptr[i] == (char)255 || ptr[i] ==
'\n');
197 std::string ret(ctr + strmlen, 0);
200 for (
size_t i = 0;i < strmlen; ++i, ++ptr) {
201 if ((*ptr) == (
char)255) {
202 ret[target] = (char)255;
206 else if ((*ptr) ==
'\n') {
207 ret[target] = (char)255;
212 ret[target] = (*ptr);
216 assert(target == ctr + strmlen);
225 static std::string unescape_newline(
const std::string& str) {
228 for (
size_t i = 0;i < str.length(); ++i) {
229 ctr += (str[i] == (char)255);
232 std::string ret(str.size() - ctr, 0);
234 const char escapemap[2] = {
'\n', (char)255};
237 for (
size_t i = 0;i < str.length(); ++i, ++target) {
238 if (str[i] == (
char)255) {
241 ASSERT_MSG(str[i] == 0 || str[i] == 1,
242 "Malformed escape sequence in graphjrl file.");
243 ret[target] = escapemap[(int)str[i]];
246 ret[target] = str[i];
252 std::string save_vertex(vertex_type v) {
255 oarc << char(0) << v.id() << v.data();
257 return escape_newline(strm) +
"\n";
260 std::string save_edge(edge_type e) {
263 oarc << char(1) << e.source().id() << e.target().id() << e.data();
265 return escape_newline(strm) +
"\n";
271 template <
typename Graph>
272 bool graphjrl_parser(Graph& graph,
const std::string& srcfilename,
273 const std::string& str) {
274 std::string unescapedstr = graphjrl_writer<Graph>::unescape_newline(str);
275 boost::iostreams::stream<boost::iostreams::array_source>
276 istrm(unescapedstr.c_str(), unescapedstr.length());
277 iarchive iarc(istrm);
281 if (entrytype == 0) {
282 typename Graph::vertex_id_type vid;
283 typename Graph::vertex_data_type vdata;
284 iarc >> vid >> vdata;
285 graph.add_vertex(vid, vdata);
287 else if (entrytype == 1) {
288 typename Graph::vertex_id_type srcvid, destvid;
289 typename Graph::edge_data_type edata;
290 iarc >> srcvid >> destvid >> edata;
291 graph.add_edge(srcvid, destvid, edata);