169ab6119SShuo Chen#include <boost/asio/io_service.hpp> 269ab6119SShuo Chen#include <boost/asio/ip/tcp.hpp> 369ab6119SShuo Chen#include <boost/ptr_container/ptr_vector.hpp> 469ab6119SShuo Chen 569ab6119SShuo Chen#include <fstream> 669ab6119SShuo Chen 769ab6119SShuo Chen#include <stdio.h> 869ab6119SShuo Chen 969ab6119SShuo Chenclass Source 1069ab6119SShuo Chen{ 1169ab6119SShuo Chen public: 1269ab6119SShuo Chen explicit Source(std::istream* in) 1369ab6119SShuo Chen : in_(in), 1469ab6119SShuo Chen count_(0), 15cc454125SShuo Chen word_() 1669ab6119SShuo Chen { 1769ab6119SShuo Chen } 1869ab6119SShuo Chen 1969ab6119SShuo Chen bool next() 2069ab6119SShuo Chen { 2169ab6119SShuo Chen std::string line; 2269ab6119SShuo Chen if (getline(*in_, line)) 2369ab6119SShuo Chen { 2469ab6119SShuo Chen size_t tab = line.find('\t'); 2569ab6119SShuo Chen if (tab != std::string::npos) 2669ab6119SShuo Chen { 2769ab6119SShuo Chen count_ = atoll(line.c_str()); 2869ab6119SShuo Chen if (count_ > 0) 2969ab6119SShuo Chen { 30cc454125SShuo Chen word_ = line.substr(tab+1); 3169ab6119SShuo Chen return true; 3269ab6119SShuo Chen } 3369ab6119SShuo Chen } 3469ab6119SShuo Chen } 3569ab6119SShuo Chen return false; 3669ab6119SShuo Chen } 3769ab6119SShuo Chen 3869ab6119SShuo Chen bool operator<(const Source& rhs) const 3969ab6119SShuo Chen { 4069ab6119SShuo Chen return count_ < rhs.count_; 4169ab6119SShuo Chen } 4269ab6119SShuo Chen 4369ab6119SShuo Chen void output(std::ostream& out) 4469ab6119SShuo Chen { 45cc454125SShuo Chen out << count_ << '\t' << word_ << '\n'; 4669ab6119SShuo Chen } 4769ab6119SShuo Chen 4869ab6119SShuo Chen private: 4969ab6119SShuo Chen std::istream* in_; 5069ab6119SShuo Chen int64_t count_; 51cc454125SShuo Chen std::string word_; 5269ab6119SShuo Chen}; 5369ab6119SShuo Chen 5469ab6119SShuo Chenboost::asio::ip::tcp::endpoint get_endpoint(const std::string& ipport) 5569ab6119SShuo Chen{ 5669ab6119SShuo Chen size_t colon = ipport.find(':'); 5769ab6119SShuo Chen if (colon != std::string::npos) 5869ab6119SShuo Chen { 5969ab6119SShuo Chen std::string ip = ipport.substr(0, colon); 6069ab6119SShuo Chen uint16_t port = static_cast<uint16_t>(atoi(ipport.c_str() + colon + 1)); 6169ab6119SShuo Chen return boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(ip), port); 6269ab6119SShuo Chen } 6369ab6119SShuo Chen else 6469ab6119SShuo Chen { 6569ab6119SShuo Chen throw std::invalid_argument("Invalid format of endpoint"); 6669ab6119SShuo Chen } 6769ab6119SShuo Chen} 6869ab6119SShuo Chen 6969ab6119SShuo Chenint main(int argc, char* argv[]) 7069ab6119SShuo Chen{ 7169ab6119SShuo Chen if (argc >= 3) 7269ab6119SShuo Chen { 7369ab6119SShuo Chen boost::ptr_vector<boost::asio::ip::tcp::iostream> inputs; 7469ab6119SShuo Chen std::vector<Source> keys; 7569ab6119SShuo Chen const int64_t topK = atoll(argv[1]); 7669ab6119SShuo Chen 7769ab6119SShuo Chen for (int i = 2; i < argc; ++i) 7869ab6119SShuo Chen { 7969ab6119SShuo Chen inputs.push_back(new boost::asio::ip::tcp::iostream(get_endpoint(argv[i]))); 8069ab6119SShuo Chen Source src(&inputs.back()); 8169ab6119SShuo Chen if (src.next()) 8269ab6119SShuo Chen { 8369ab6119SShuo Chen keys.push_back(src); 8469ab6119SShuo Chen } 8569ab6119SShuo Chen } 8669ab6119SShuo Chen printf("Connected to %zd sender(s)\n", keys.size()); 8769ab6119SShuo Chen 8869ab6119SShuo Chen std::ofstream out("output"); 8969ab6119SShuo Chen int64_t cnt = 0; 9069ab6119SShuo Chen std::make_heap(keys.begin(), keys.end()); 9169ab6119SShuo Chen while (!keys.empty() && cnt < topK) 9269ab6119SShuo Chen { 9369ab6119SShuo Chen std::pop_heap(keys.begin(), keys.end()); 9469ab6119SShuo Chen keys.back().output(out); 9569ab6119SShuo Chen ++cnt; 9669ab6119SShuo Chen 9769ab6119SShuo Chen if (keys.back().next()) 9869ab6119SShuo Chen { 9969ab6119SShuo Chen std::push_heap(keys.begin(), keys.end()); 10069ab6119SShuo Chen } 10169ab6119SShuo Chen else 10269ab6119SShuo Chen { 10369ab6119SShuo Chen keys.pop_back(); 10469ab6119SShuo Chen } 10569ab6119SShuo Chen } 10669ab6119SShuo Chen printf("merging done\n"); 10769ab6119SShuo Chen } 10869ab6119SShuo Chen else 10969ab6119SShuo Chen { 11069ab6119SShuo Chen printf("Usage: %s topK ip1:port1 [ip2:port2 ...]\n", argv[0]); 11169ab6119SShuo Chen } 11269ab6119SShuo Chen} 11369ab6119SShuo Chen 114