From: Steinar H. Gunderson Date: Thu, 15 Oct 2020 22:22:59 +0000 (+0200) Subject: Move Serializer into its own file. X-Git-Tag: 1.0.4~5 X-Git-Url: https://git.sesse.net/?p=plocate;a=commitdiff_plain;h=4ecef43ea601ab99ad2f2cf7715dbc52e8f3c775 Move Serializer into its own file. --- diff --git a/meson.build b/meson.build index 2e68459..7c6755b 100644 --- a/meson.build +++ b/meson.build @@ -12,7 +12,7 @@ if not uringdep.found() add_project_arguments('-DWITHOUT_URING', language: 'cpp') endif -executable('plocate', ['plocate.cpp', 'io_uring_engine.cpp', 'turbopfor.cpp', 'parse_trigrams.cpp'], +executable('plocate', ['plocate.cpp', 'io_uring_engine.cpp', 'turbopfor.cpp', 'parse_trigrams.cpp', 'serializer.cpp'], dependencies: [uringdep, zstddep, threaddep], install: true, install_mode: ['rwxr-sr-x', 'root', 'mlocate']) diff --git a/options.h b/options.h new file mode 100644 index 0000000..683c8d3 --- /dev/null +++ b/options.h @@ -0,0 +1,16 @@ +#ifndef _OPTIONS_H +#define _OPTIONS_H + +#include + +extern const char *dbpath; +extern bool ignore_case; +extern bool only_count; +extern bool print_nul; +extern bool use_debug; +extern bool patterns_are_regex; +extern bool use_extended_regex; +extern int64_t limit_matches; +extern int64_t limit_left; // Not strictly an option. + +#endif // !defined(_OPTIONS_H) diff --git a/plocate.cpp b/plocate.cpp index 926bbf1..2f31293 100644 --- a/plocate.cpp +++ b/plocate.cpp @@ -2,34 +2,36 @@ #include "dprintf.h" #include "io_uring_engine.h" #include "parse_trigrams.h" +#include "serializer.h" #include "turbopfor.h" #include "unique_sort.h" #include -#include #include +#include #include #include +#include #include #include #include #include #include -#include #include #include +#include #include #include #include -#include #include -#include #include #include +#include #include #include #include #include +#include #include #include #include @@ -57,83 +59,6 @@ ZSTD_DDict *ddict = nullptr; regex_t compile_regex(const string &needle); -void apply_limit() -{ - if (--limit_left > 0) { - return; - } - dprintf("Done in %.1f ms, found %" PRId64 " matches.\n", - 1e3 * duration(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 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(); - } -} - struct Needle { enum { STRSTR, REGEX, @@ -399,7 +324,7 @@ size_t scan_docids(const vector &needles, const vector &docids { Serializer docids_in_order; AccessRXCache access_rx_cache(engine); - atomic matched{0}; + atomic matched{ 0 }; for (size_t i = 0; i < docids.size(); ++i) { uint32_t docid = docids[i]; corpus.get_compressed_filename_block(docid, [i, &matched, &needles, &access_rx_cache, &docids_in_order](string_view compressed) { @@ -427,7 +352,8 @@ struct WorkerThread { class WorkerThreadReceiver : public ResultReceiver { public: - WorkerThreadReceiver(WorkerThread *wt) : wt(wt) {} + WorkerThreadReceiver(WorkerThread *wt) + : wt(wt) {} void print(uint64_t seq, uint64_t skip, const string msg) override { diff --git a/serializer.cpp b/serializer.cpp new file mode 100644 index 0000000..9277125 --- /dev/null +++ b/serializer.cpp @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include +#include + +#include "dprintf.h" +#include "serializer.h" + +using namespace std; +using namespace std::chrono; + +extern steady_clock::time_point start; + +void apply_limit() +{ + if (--limit_left > 0) { + return; + } + dprintf("Done in %.1f ms, found %" PRId64 " matches.\n", + 1e3 * duration(steady_clock::now() - start).count(), limit_matches); + if (only_count) { + printf("%" PRId64 "\n", limit_matches); + } + exit(0); +} + +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(); + } +} + diff --git a/serializer.h b/serializer.h new file mode 100644 index 0000000..580e91d --- /dev/null +++ b/serializer.h @@ -0,0 +1,36 @@ +#ifndef _SERIALIZER_H +#define _SERIALIZER_H 1 + +#include +#include +#include +#include + +#include "options.h" + +class ResultReceiver { +public: + virtual ~ResultReceiver() = default; + virtual void print(uint64_t seq, uint64_t skip, const std::string msg) = 0; +}; + +class Serializer : public ResultReceiver { +public: + ~Serializer() { assert(limit_left <= 0 || pending.empty()); } + void print(uint64_t seq, uint64_t skip, const std::string msg) override; + +private: + uint64_t next_seq = 0; + struct Element { + uint64_t seq, skip; + std::string msg; + + bool operator<(const Element &other) const + { + return seq > other.seq; + } + }; + std::priority_queue pending; +}; + +#endif // !defined(_SERIALIZER_H)