-void apply_limit()
-{
- if (--limit_left > 0) {
- return;
- }
- dprintf("Done in %.1f ms, found %" PRId64 " matches.\n",
- 1e3 * duration<float>(steady_clock::now() - start).count(), limit_matches);
- if (only_count) {
- printf("%" PRId64 "\n", limit_matches);
- }
- exit(0);
-}
-
-class ResultReceiver {
-public:
- virtual ~ResultReceiver() = default;
- virtual void print(uint64_t seq, uint64_t skip, const string msg) = 0;
-};
-
-class Serializer : public ResultReceiver {
-public:
- ~Serializer() { assert(limit_left <= 0 || pending.empty()); }
- void print(uint64_t seq, uint64_t skip, const string msg) override;
-
-private:
- uint64_t next_seq = 0;
- struct Element {
- uint64_t seq, skip;
- string msg;
-
- bool operator<(const Element &other) const
- {
- return seq > other.seq;
- }
- };
- priority_queue<Element> pending;
-};
-
-void Serializer::print(uint64_t seq, uint64_t skip, const string msg)
-{
- if (only_count) {
- if (!msg.empty()) {
- apply_limit();
- }
- return;
- }
-
- if (next_seq != seq) {
- pending.push(Element{ seq, skip, move(msg) });
- return;
- }
-
- if (!msg.empty()) {
- if (print_nul) {
- printf("%s%c", msg.c_str(), 0);
- } else {
- printf("%s\n", msg.c_str());
- }
- apply_limit();
- }
- next_seq += skip;
-
- // See if any delayed prints can now be dealt with.
- while (!pending.empty() && pending.top().seq == next_seq) {
- if (!pending.top().msg.empty()) {
- if (print_nul) {
- printf("%s%c", pending.top().msg.c_str(), 0);
- } else {
- printf("%s\n", pending.top().msg.c_str());
- }
- apply_limit();
- }
- next_seq += pending.top().skip;
- pending.pop();
- }
-}
-