text: /*
   * SNAPEdgeListPartitionReader.cpp
   *
   *  Created on: Jun 20, 2013
   *      Author: forigem
   */
  #include <fstream>
  #include <sstream>
  #include <unordered_map>
  
  #include <networkit/io/SNAPEdgeListPartitionReader.hpp>
  #include <networkit/auxiliary/Log.hpp>
  
  namespace NetworKit {
  
  Cover SNAPEdgeListPartitionReader::read(std::string path, std::unordered_map<node,node>& mapNodeIds, Graph& G) {
      std::ifstream file;
      std::string line; // the current line
  
      // read file once to get to the last line and figure out the number of nodes
      // unfortunately there is an empty line at the ending of the file, so we need to get the line before that
      
      file.open(path);
      if (! file.good()) {
          throw std::runtime_error("unable to read from file");
      }
      
  //	std::string previousLine;
      node current;
      
      std::string commentPrefix = "#";
      
  //	count firstNode = 0;
  //	char separator = '\t';
      std::set<node> uniqueIDs;
      count totalCounter = 0;
  
      Cover communities(G.upperNodeIdBound());
  
      //DEBUG("separator: " , separator);
      //DEBUG("first node: " , firstNode);
  
      // first find out the maximum node id
      //DEBUG("first pass");
      count i = 0;
      while (file.good()) {
          ++i;
          std::getline(file, line);
          // TRACE("read line: " , line);
          if (line.compare(0, commentPrefix.length(), commentPrefix) == 0) {
              // TRACE("ignoring comment: " , line);
              } else if (line.length() == 0) {
                  // TRACE("ignoring empty line");
          } else {
              std::stringstream linestream(line);
              while (linestream >> current) {
                  uniqueIDs.insert(current);
                  totalCounter++;
                  if (mapNodeIds.find(current) != mapNodeIds.end()) {
                      communities.addToSubset(i,mapNodeIds[current]);
                  } else {
                      WARN("unknown node ID found (",current,") and ignored");
                  }
              }
          }
      }
      DEBUG("read ", uniqueIDs.size(), " unique node IDs with the total amount of occurrences: ",totalCounter);
      count emptyElements = 0;
      count output = 0;
      std::stringstream outputString;
      std::vector<node> outputIDs;
      outputString << "first 10 unassigned IDs: ";
      for (index i = 0, end = communities.numberOfElements(); i < end; ++i) {
          if (communities[i].empty()) {
              emptyElements++;
              if (output < 10) {
                  outputIDs.push_back(i);
                  output++;
              }
          }
      }
      DEBUG(emptyElements, " nodes have not been assigned to any community");
      auto endIt = mapNodeIds.end();
      for (index i = 0, end = outputIDs.size(); i < end; ++i) {
          bool found = false;
          auto it = mapNodeIds.begin();
          //DEBUG("find key to nodeID: ",outputIDs[i]);
          while (!found && it != endIt) {
              if (it->second == outputIDs[i]) {
                  found = true;
                  //DEBUG("key is: ",it->first);
                  outputString << "("<<it->first<<","<<it->second<<"),\t";
              }
              ++it;
          }
      }
      DEBUG(outputString.str());
  
      file.close();
      communities.setUpperBound(i);
      return communities;
  }
  
  #if 0
  Partition SNAPEdgeListPartitionReader::readWithInfo(std::string path, count nNodes) {
      std::ifstream file(path);
  
      // check if file readable
      if (!file) {
          throw std::runtime_error("invalid clustering file");
      }
  
      Partition communities(nNodes);
      std::string line;
      //	std::stringstream linestream;
      count lines = 1;
      count nValues = 0;
      std::unordered_map<node,count> ids;
      node current;
      while (std::getline(file,line)) {
          std::stringstream linestream(line);
          while (linestream >> current) {
              nValues++;
              if (!ids.insert(std::make_pair(current,0)).second) {
                  ids[current]++;
              }
              //DEBUG("read nodeID: ", current);
              if ( current < nNodes ) {
                  communities[current] = lines;
              } else {
                  DEBUG("found invalid node ID: ",current);
              }
          }
          lines++;
      }
      count sum = 0;
      for(auto x: ids) {
          if (x.second > 1) {
              DEBUG(x.first," has been found ",x.second, " times");
              sum += x.second;
          }
      }
      WARN("found ",ids.size()," values and ",sum," total occurrences");
  
      communities.setUpperBound(lines);
      return communities;
  }
  #endif
  
  } /* namespace NetworKit */
  