summaryrefslogtreecommitdiffstats
path: root/src/logfile_sub_source.hh
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/logfile_sub_source.hh363
1 files changed, 83 insertions, 280 deletions
diff --git a/src/logfile_sub_source.hh b/src/logfile_sub_source.hh
index ec032c8..a82db60 100644
--- a/src/logfile_sub_source.hh
+++ b/src/logfile_sub_source.hh
@@ -33,23 +33,16 @@
#define logfile_sub_source_hh
#include <array>
-#include <list>
-#include <map>
-#include <sstream>
#include <utility>
#include <vector>
#include <limits.h>
-#include "base/lnav.console.hh"
-#include "base/lnav_log.hh"
#include "base/time_util.hh"
#include "big_array.hh"
#include "bookmarks.hh"
#include "document.sections.hh"
#include "filter_observer.hh"
-#include "lnav_config_fwd.hh"
-#include "log_accel.hh"
#include "log_format.hh"
#include "logfile.hh"
#include "strong_int.hh"
@@ -80,39 +73,6 @@ public:
virtual void index_complete(logfile_sub_source& lss) {}
};
-class pcre_filter : public text_filter {
-public:
- pcre_filter(type_t type,
- const std::string& id,
- size_t index,
- std::shared_ptr<lnav::pcre2pp::code> code)
- : text_filter(type, filter_lang_t::REGEX, id, index),
- pf_pcre(std::move(code))
- {
- }
-
- ~pcre_filter() override = default;
-
- bool matches(const logfile& lf,
- logfile::const_iterator ll,
- const shared_buffer_ref& line) override
- {
- return this->pf_pcre->find_in(line.to_string_fragment())
- .ignore_error()
- .has_value();
- }
-
- std::string to_command() const override
- {
- return (this->lf_type == text_filter::INCLUDE ? "filter-in "
- : "filter-out ")
- + this->lf_id;
- }
-
-protected:
- std::shared_ptr<lnav::pcre2pp::code> pf_pcre;
-};
-
class sql_filter : public text_filter {
public:
sql_filter(logfile_sub_source& lss,
@@ -124,8 +84,7 @@ public:
this->sf_filter_stmt = stmt;
}
- bool matches(const logfile& lf,
- logfile::const_iterator ll,
+ bool matches(nonstd::optional<line_source> ls,
const shared_buffer_ref& line) override;
std::string to_command() const override;
@@ -240,7 +199,10 @@ private:
class logfile_sub_source
: public text_sub_source
, public text_time_translator
- , public list_input_delegate {
+ , public text_accel_source
+ , public list_input_delegate
+ , public text_anchors
+ , public text_delegate {
public:
const static bookmark_type_t BM_ERRORS;
const static bookmark_type_t BM_WARNINGS;
@@ -252,72 +214,11 @@ public:
~logfile_sub_source() = default;
- void toggle_time_offset()
- {
- this->lss_flags ^= F_TIME_OFFSET;
- this->clear_line_size_cache();
- }
-
- void increase_line_context()
- {
- auto old_flags = this->lss_flags;
-
- if (this->lss_flags & F_FILENAME) {
- // Nothing to do
- } else if (this->lss_flags & F_BASENAME) {
- this->lss_flags &= ~F_NAME_MASK;
- this->lss_flags |= F_FILENAME;
- } else {
- this->lss_flags |= F_BASENAME;
- }
- if (old_flags != this->lss_flags) {
- this->clear_line_size_cache();
- }
- }
-
- bool decrease_line_context()
- {
- auto old_flags = this->lss_flags;
-
- if (this->lss_flags & F_FILENAME) {
- this->lss_flags &= ~F_NAME_MASK;
- this->lss_flags |= F_BASENAME;
- } else if (this->lss_flags & F_BASENAME) {
- this->lss_flags &= ~F_NAME_MASK;
- }
- if (old_flags != this->lss_flags) {
- this->clear_line_size_cache();
-
- return true;
- }
-
- return false;
- }
+ void increase_line_context();
- size_t get_filename_offset() const
- {
- if (this->lss_flags & F_FILENAME) {
- return this->lss_filename_width;
- } else if (this->lss_flags & F_BASENAME) {
- return this->lss_basename_width;
- }
+ bool decrease_line_context();
- return 0;
- }
-
- void set_time_offset(bool enabled)
- {
- if (enabled)
- this->lss_flags |= F_TIME_OFFSET;
- else
- this->lss_flags &= ~F_TIME_OFFSET;
- this->clear_line_size_cache();
- }
-
- bool is_time_offset_enabled() const
- {
- return (bool) (this->lss_flags & F_TIME_OFFSET);
- }
+ size_t get_filename_offset() const;
bool is_filename_enabled() const
{
@@ -341,11 +242,15 @@ public:
}
}
- bool get_min_log_time(struct timeval& tv_out) const
+ nonstd::optional<timeval> get_min_log_time() const
{
- tv_out = this->lss_min_log_time;
- return (this->lss_min_log_time.tv_sec != 0
- || this->lss_min_log_time.tv_usec != 0);
+ if (this->lss_min_log_time.tv_sec == 0
+ && this->lss_min_log_time.tv_usec == 0)
+ {
+ return nonstd::nullopt;
+ }
+
+ return this->lss_min_log_time;
}
void set_min_log_time(const struct timeval& tv)
@@ -356,12 +261,15 @@ public:
}
}
- bool get_max_log_time(struct timeval& tv_out) const
+ nonstd::optional<timeval> get_max_log_time() const
{
- tv_out = this->lss_max_log_time;
- return (this->lss_max_log_time.tv_sec
- != std::numeric_limits<time_t>::max()
- || this->lss_max_log_time.tv_usec != 0);
+ if (this->lss_max_log_time.tv_sec == std::numeric_limits<time_t>::max()
+ && this->lss_max_log_time.tv_usec == 0)
+ {
+ return nonstd::nullopt;
+ }
+
+ return this->lss_max_log_time;
}
void set_max_log_time(struct timeval& tv)
@@ -372,20 +280,7 @@ public:
}
}
- void clear_min_max_log_times()
- {
- if (this->lss_min_log_time.tv_sec != 0
- || this->lss_min_log_time.tv_usec != 0
- || this->lss_max_log_time.tv_sec
- != std::numeric_limits<time_t>::max()
- || this->lss_max_log_time.tv_usec != 0)
- {
- memset(&this->lss_min_log_time, 0, sizeof(this->lss_min_log_time));
- this->lss_max_log_time.tv_sec = std::numeric_limits<time_t>::max();
- this->lss_max_log_time.tv_usec = 0;
- this->text_filters_changed();
- }
- }
+ void clear_min_max_log_times();
bool list_input_handle_key(listview_curses& lv, int ch);
@@ -406,19 +301,7 @@ public:
return this->lss_longest_line;
}
- size_t file_count() const
- {
- size_t retval = 0;
- const_iterator iter;
-
- for (iter = this->cbegin(); iter != this->cend(); ++iter) {
- if (*iter != nullptr && (*iter)->get_file() != nullptr) {
- retval += 1;
- }
- }
-
- return retval;
- }
+ size_t file_count() const;
bool empty() const { return this->lss_filtered_index.empty(); }
@@ -431,19 +314,7 @@ public:
int row,
string_attrs_t& value_out);
- size_t text_size_for_line(textview_curses& tc, int row, line_flags_t flags)
- {
- size_t index = row % LINE_SIZE_CACHE_SIZE;
-
- if (this->lss_line_size_cache[index].first != row) {
- std::string value;
-
- this->text_value_for_line(tc, row, value, flags);
- this->lss_line_size_cache[index].second = value.size();
- this->lss_line_size_cache[index].first = row;
- }
- return this->lss_line_size_cache[index].second;
- }
+ size_t text_size_for_line(textview_curses& tc, int row, line_flags_t flags);
void text_mark(const bookmark_type_t* bm, vis_line_t line, bool added);
@@ -482,10 +353,22 @@ public:
return this->get_bookmark_metadata(this->at(vl));
}
+ struct bookmark_metadata_context {
+ nonstd::optional<vis_line_t> bmc_current;
+ nonstd::optional<bookmark_metadata*> bmc_current_metadata;
+ nonstd::optional<vis_line_t> bmc_next_line;
+ };
+
+ bookmark_metadata_context get_bookmark_metadata_context(
+ vis_line_t vl,
+ bookmark_metadata::categories desired
+ = bookmark_metadata::categories::any) const;
+
nonstd::optional<bookmark_metadata*> find_bookmark_metadata(
- content_line_t cl);
+ content_line_t cl) const;
- nonstd::optional<bookmark_metadata*> find_bookmark_metadata(vis_line_t vl)
+ nonstd::optional<bookmark_metadata*> find_bookmark_metadata(
+ vis_line_t vl) const
{
return this->find_bookmark_metadata(this->at(vl));
}
@@ -504,17 +387,7 @@ public:
return this->lss_index.size() - this->lss_filtered_index.size();
}
- int get_filtered_count_for(size_t filter_index) const
- {
- int retval = 0;
-
- for (const auto& ld : this->lss_files) {
- retval += ld->ld_filter_state.lfo_filter_state
- .tfs_filter_hits[filter_index];
- }
-
- return retval;
- }
+ int get_filtered_count_for(size_t filter_index) const;
Result<void, lnav::console::user_message> set_sql_filter(
std::string stmt_str, sqlite3_stmt* stmt);
@@ -554,7 +427,7 @@ public:
return retval;
}
- logfile* find_file_ptr(content_line_t& line)
+ logfile* find_file_ptr(content_line_t& line) const
{
auto retval
= this->lss_files[line / MAX_LINES_PER_FILE]->get_file_ptr();
@@ -566,7 +439,7 @@ public:
logline* find_line(content_line_t line) const
{
logline* retval = nullptr;
- std::shared_ptr<logfile> lf = this->find(line);
+ auto lf = this->find_file_ptr(line);
if (lf != nullptr) {
auto ll_iter = lf->begin() + line;
@@ -618,14 +491,20 @@ public:
nonstd::optional<vis_line_t> find_from_content(content_line_t cl);
- nonstd::optional<struct timeval> time_for_row(vis_line_t row)
+ nonstd::optional<row_info> time_for_row(vis_line_t row)
{
- if (row < (ssize_t) this->text_line_count()) {
- return this->find_line(this->at(row))->get_timeval();
+ if (row >= 0_vl && row < (ssize_t) this->text_line_count()) {
+ auto cl = this->at(row);
+ return row_info{
+ this->find_line(cl)->get_timeval(),
+ (int64_t) cl,
+ };
}
return nonstd::nullopt;
}
+ nonstd::optional<vis_line_t> row_for(const row_info& ri);
+
nonstd::optional<vis_line_t> row_for_time(struct timeval time_bucket)
{
return this->find_from_time(time_bucket);
@@ -650,8 +529,6 @@ public:
return logline_window(*this, start_vl, end_vl);
}
- log_accel::direction_t get_line_accel_direction(vis_line_t vl);
-
/**
* Container for logfile references that keeps of how many lines in the
* logfile have been indexed.
@@ -812,6 +689,10 @@ public:
void text_crumbs_for_line(int line, std::vector<breadcrumb::crumb>& crumbs);
+ bool text_handle_mouse(textview_curses& tc,
+ const listview_curses::display_line_content_t&,
+ mouse_event& me);
+
Result<bool, lnav::console::user_message> eval_sql_filter(
sqlite3_stmt* stmt, iterator ld, logfile::const_iterator ll);
@@ -823,6 +704,8 @@ public:
void set_exec_context(exec_context* ec) { this->lss_exec_context = ec; }
+ exec_context* get_exec_context() const { return this->lss_exec_context; }
+
static const uint64_t MAX_CONTENT_LINES = (1ULL << 40) - 1;
static const uint64_t MAX_LINES_PER_FILE = 256 * 1024 * 1024;
static const uint64_t MAX_FILES = (MAX_CONTENT_LINES / MAX_LINES_PER_FILE);
@@ -834,25 +717,6 @@ public:
void quiesce();
-private:
- static const size_t LINE_SIZE_CACHE_SIZE = 512;
-
- enum {
- B_SCRUB,
- B_TIME_OFFSET,
- B_FILENAME,
- B_BASENAME,
- };
-
- enum {
- F_SCRUB = (1UL << B_SCRUB),
- F_TIME_OFFSET = (1UL << B_TIME_OFFSET),
- F_FILENAME = (1UL << B_FILENAME),
- F_BASENAME = (1UL << B_BASENAME),
-
- F_NAME_MASK = (F_FILENAME | F_BASENAME),
- };
-
struct __attribute__((__packed__)) indexed_content {
indexed_content() = default;
@@ -866,101 +730,39 @@ private:
uint64_t ic_value : 40;
};
- struct logline_cmp {
- logline_cmp(logfile_sub_source& lc) : llss_controller(lc) {}
-
- bool operator()(const content_line_t& lhs,
- const content_line_t& rhs) const
- {
- logline* ll_lhs = this->llss_controller.find_line(lhs);
- logline* ll_rhs = this->llss_controller.find_line(rhs);
-
- return (*ll_lhs) < (*ll_rhs);
- }
-
- bool operator()(const uint32_t& lhs, const uint32_t& rhs) const
- {
- content_line_t cl_lhs
- = (content_line_t) llss_controller.lss_index[lhs];
- content_line_t cl_rhs
- = (content_line_t) llss_controller.lss_index[rhs];
- logline* ll_lhs = this->llss_controller.find_line(cl_lhs);
- logline* ll_rhs = this->llss_controller.find_line(cl_rhs);
-
- return (*ll_lhs) < (*ll_rhs);
- }
-#if 0
- bool operator()(const indexed_content &lhs, const indexed_content &rhs)
- {
- logline *ll_lhs = this->llss_controller.find_line(lhs.ic_value);
- logline *ll_rhs = this->llss_controller.find_line(rhs.ic_value);
-
- return (*ll_lhs) < (*ll_rhs);
- }
-#endif
-
- bool operator()(const content_line_t& lhs, const time_t& rhs) const
- {
- logline* ll_lhs = this->llss_controller.find_line(lhs);
+ big_array<indexed_content> lss_index;
- return *ll_lhs < rhs;
- }
+ nonstd::optional<vis_line_t> row_for_anchor(const std::string& id);
- bool operator()(const content_line_t& lhs,
- const struct timeval& rhs) const
- {
- logline* ll_lhs = this->llss_controller.find_line(lhs);
+ nonstd::optional<vis_line_t> adjacent_anchor(vis_line_t vl, direction dir);
- return *ll_lhs < rhs;
- }
+ nonstd::optional<std::string> anchor_for_row(vis_line_t vl);
- logfile_sub_source& llss_controller;
- };
+ std::unordered_set<std::string> get_anchors();
- struct filtered_logline_cmp {
- filtered_logline_cmp(const logfile_sub_source& lc) : llss_controller(lc)
- {
- }
-
- bool operator()(const uint32_t& lhs, const uint32_t& rhs) const
- {
- content_line_t cl_lhs
- = (content_line_t) llss_controller.lss_index[lhs];
- content_line_t cl_rhs
- = (content_line_t) llss_controller.lss_index[rhs];
- logline* ll_lhs = this->llss_controller.find_line(cl_lhs);
- logline* ll_rhs = this->llss_controller.find_line(cl_rhs);
-
- return (*ll_lhs) < (*ll_rhs);
- }
+protected:
+ void text_accel_display_changed() { this->clear_line_size_cache(); }
- bool operator()(const uint32_t& lhs, const struct timeval& rhs) const
- {
- content_line_t cl_lhs
- = (content_line_t) llss_controller.lss_index[lhs];
- logline* ll_lhs = this->llss_controller.find_line(cl_lhs);
+ logline* text_accel_get_line(vis_line_t vl)
+ {
+ return this->find_line(this->at(vl));
+ }
- return (*ll_lhs) < rhs;
- }
+private:
+ static const size_t LINE_SIZE_CACHE_SIZE = 512;
- const logfile_sub_source& llss_controller;
+ enum {
+ B_SCRUB,
+ B_FILENAME,
+ B_BASENAME,
};
- /**
- * Functor for comparing the ld_file field of the logfile_data struct.
- */
- struct logfile_data_eq {
- explicit logfile_data_eq(std::shared_ptr<logfile> lf)
- : lde_file(std::move(lf))
- {
- }
-
- bool operator()(const std::unique_ptr<logfile_data>& ld) const
- {
- return this->lde_file == ld->get_file();
- }
+ enum {
+ F_SCRUB = (1UL << B_SCRUB),
+ F_FILENAME = (1UL << B_FILENAME),
+ F_BASENAME = (1UL << B_BASENAME),
- std::shared_ptr<logfile> lde_file;
+ F_NAME_MASK = (F_FILENAME | F_BASENAME),
};
void clear_line_size_cache()
@@ -977,7 +779,6 @@ private:
bool lss_force_rebuild{false};
std::vector<std::unique_ptr<logfile_data>> lss_files;
- big_array<indexed_content> lss_index;
std::vector<uint32_t> lss_filtered_index;
auto_mem<sqlite3_stmt> lss_preview_filter_stmt{sqlite3_finalize};
@@ -1016,6 +817,8 @@ private:
bool lss_in_value_for_line{false};
bool lss_line_meta_changed{false};
+
+ bool lss_indexing_in_progress{false};
};
#endif