http://stxxl.sourceforge.net
<dementiev@mpi-sb.mpg.de>
http://www.boost.org/LICENSE_1_0.txt
#include <stxxl.h>
#include <algorithm>
#include <vector>
#include <fstream>
#include <ctime>
#define CT_PER_MIN 2
struct LogEntry
{
long long int from;
long long int to;
time_t timestamp;
int event;
};
std::istream & operator >> (std::istream & i, LogEntry & entry)
{
i >> entry.from;
i >> entry.to;
i >> entry.timestamp;
i >> entry.event;
return i;
}
std::ostream & operator << (std::ostream & i, const LogEntry & entry)
{
i << entry.from << " ";
i << entry.to << " ";
i << entry.timestamp << " ";
i << entry.event;
return i;
}
struct ProduceBill
{
std::ostream & out;
unsigned sum;
LogEntry last;
ProduceBill(std::ostream & o_) : out(o_), sum(0) { last.from = -1; }
void operator () (const LogEntry & e)
{
if (last.from == e.from)
{
assert((last.event == 1 && e.event == 2) ||
(last.event == 2 && e.event == 1));
if (e.event == 2)
sum += CT_PER_MIN * (e.timestamp - last.timestamp) / 60;
}
else if (last.from != -1)
{
assert(last.event == 2);
assert(e.event == 1);
out << last.from << "; " << (sum / 100) << " EUR " << (sum % 100) <<
" ct" << std::endl;
sum = 0;
}
last = e;
}
};
struct SortByCaller
{
bool operator () (const LogEntry & a, const LogEntry & b) const
{
return a.from < b.from ||
(a.from == b.from && a.timestamp < b.timestamp) ||
(a.from == b.from && a.timestamp == b.timestamp &&
a.event < b.event);
}
static LogEntry min_value()
{
LogEntry e;
e.from = (std::numeric_limits<long long int>::min)();
return e;
}
static LogEntry max_value()
{
LogEntry e;
e.from = (std::numeric_limits<long long int>::max)();
return e;
}
};
#ifdef USE_STXXL
typedef stxxl::vector<LogEntry> vector_type;
#else
typedef std::vector<LogEntry> vector_type;
#endif
void print_usage(const char * program)
{
std::cout << "Usage: " << program << " logfile main billfile" << std::endl;
std::cout << " logfile - file name of the input" << std::endl;
std::cout << " main - memory to use (in MiB)" << std::endl;
std::cout << " billfile - file name of the output" << std::endl;
}
int main(int argc, char * argv[])
{
if (argc < 4)
{
print_usage(argv[0]);
return 0;
}
std::fstream in(argv[1], std::ios::in);
vector_type v;
std::copy(std::istream_iterator<LogEntry>(in),
std::istream_iterator<LogEntry>(),
std::back_inserter(v));
#ifndef USE_STXXL
std::sort(v.begin(), v.end(), SortByCaller());
std::fstream out(argv[3], std::ios::out);
std::for_each(v.begin(), v.end(), ProduceBill(out));
#else
const unsigned M = atol(argv[2]) * 1024 * 1024;
stxxl::sort(v.begin(), v.end(), SortByCaller(), M);
std::fstream out(argv[3], std::ios::out);
stxxl::for_each(v.begin(), v.end(), ProduceBill(out), M / vector_type::block_type::raw_size);
#endif
return 0;
}