inefficient date range
This commit is contained in:
@@ -67,6 +67,9 @@ impl LogViewerApp {
|
|||||||
case_sensitive: config.case_sensitive,
|
case_sensitive: config.case_sensitive,
|
||||||
use_regex: config.use_regex,
|
use_regex: config.use_regex,
|
||||||
history: config.search_history,
|
history: config.search_history,
|
||||||
|
date_range_enabled: false,
|
||||||
|
date_from: String::new(),
|
||||||
|
date_to: String::new(),
|
||||||
},
|
},
|
||||||
indexing_state: IndexingState::new(),
|
indexing_state: IndexingState::new(),
|
||||||
search_state: SearchState::new(),
|
search_state: SearchState::new(),
|
||||||
@@ -111,6 +114,9 @@ impl LogViewerApp {
|
|||||||
query: self.search_panel_state.query.clone(),
|
query: self.search_panel_state.query.clone(),
|
||||||
case_sensitive: self.search_panel_state.case_sensitive,
|
case_sensitive: self.search_panel_state.case_sensitive,
|
||||||
use_regex: self.search_panel_state.use_regex,
|
use_regex: self.search_panel_state.use_regex,
|
||||||
|
date_range_enabled: self.search_panel_state.date_range_enabled,
|
||||||
|
date_from: self.search_panel_state.date_from.clone(),
|
||||||
|
date_to: self.search_panel_state.date_to.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let line_index = Arc::clone(&tab.line_index);
|
let line_index = Arc::clone(&tab.line_index);
|
||||||
@@ -306,7 +312,8 @@ impl eframe::App for LogViewerApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Render filtered view with improved styling
|
// Render filtered view with improved styling
|
||||||
let show_filtered = !self.search_panel_state.query.is_empty();
|
// Show filtered view if there's a query OR if date range is enabled
|
||||||
|
let show_filtered = !self.search_panel_state.query.is_empty() || self.search_panel_state.date_range_enabled;
|
||||||
let highlight_rules = self.highlight_manager.rules.clone();
|
let highlight_rules = self.highlight_manager.rules.clone();
|
||||||
|
|
||||||
let mut export_clicked = false;
|
let mut export_clicked = false;
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ pub struct SearchParams {
|
|||||||
pub query: String,
|
pub query: String,
|
||||||
pub case_sensitive: bool,
|
pub case_sensitive: bool,
|
||||||
pub use_regex: bool,
|
pub use_regex: bool,
|
||||||
|
pub date_range_enabled: bool,
|
||||||
|
pub date_from: String,
|
||||||
|
pub date_to: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SearchParams {
|
impl SearchParams {
|
||||||
@@ -99,6 +102,47 @@ pub fn start_search(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_date_range(
|
||||||
|
params: &SearchParams,
|
||||||
|
line_index: &LineIndex,
|
||||||
|
file_path: &Path,
|
||||||
|
) -> Option<(usize, usize)> {
|
||||||
|
if !params.date_range_enabled || params.date_from.is_empty() || params.date_to.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let file = File::open(file_path).ok()?;
|
||||||
|
let mut file_handle = BufReader::new(file);
|
||||||
|
|
||||||
|
let mut start_line = None;
|
||||||
|
let mut end_line = None;
|
||||||
|
|
||||||
|
// Find first line containing date_from text
|
||||||
|
for line_num in 0..line_index.total_lines {
|
||||||
|
if let Some(content) = line_index.read_line(&mut file_handle, line_num) {
|
||||||
|
if content.contains(¶ms.date_from) {
|
||||||
|
start_line = Some(line_num);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find last line containing date_to text
|
||||||
|
for line_num in (0..line_index.total_lines).rev() {
|
||||||
|
if let Some(content) = line_index.read_line(&mut file_handle, line_num) {
|
||||||
|
if content.contains(¶ms.date_to) {
|
||||||
|
end_line = Some(line_num + 1); // +1 to include this line
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match (start_line, end_line) {
|
||||||
|
(Some(start), Some(end)) if start < end => Some((start, end)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn search_lines(
|
fn search_lines(
|
||||||
params: &SearchParams,
|
params: &SearchParams,
|
||||||
line_index: &LineIndex,
|
line_index: &LineIndex,
|
||||||
@@ -110,17 +154,28 @@ fn search_lines(
|
|||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine optimal chunk size based on total lines
|
// Determine the line range to search (all lines or date range)
|
||||||
// Aim for enough chunks to utilize all cores, but not too many to avoid overhead
|
let (search_start, search_end) = if let Some((start, end)) = find_date_range(params, line_index, file_path) {
|
||||||
let num_threads = rayon::current_num_threads();
|
(start, end)
|
||||||
let min_chunk_size = 1000; // Process at least 1000 lines per chunk
|
} else {
|
||||||
let chunk_size = (total_lines / (num_threads * 4)).max(min_chunk_size);
|
(0, total_lines)
|
||||||
|
};
|
||||||
|
|
||||||
// Split line numbers into chunks
|
let lines_to_search = search_end - search_start;
|
||||||
let chunks: Vec<(usize, usize)> = (0..total_lines)
|
if lines_to_search == 0 {
|
||||||
|
return Vec::new();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine optimal chunk size based on lines to search
|
||||||
|
let num_threads = rayon::current_num_threads();
|
||||||
|
let min_chunk_size = 1000;
|
||||||
|
let chunk_size = (lines_to_search / (num_threads * 4)).max(min_chunk_size);
|
||||||
|
|
||||||
|
// Split line numbers into chunks within the search range
|
||||||
|
let chunks: Vec<(usize, usize)> = (search_start..search_end)
|
||||||
.step_by(chunk_size)
|
.step_by(chunk_size)
|
||||||
.map(|start| {
|
.map(|start| {
|
||||||
let end = (start + chunk_size).min(total_lines);
|
let end = (start + chunk_size).min(search_end);
|
||||||
(start, end)
|
(start, end)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
@@ -143,7 +198,14 @@ fn search_lines(
|
|||||||
|
|
||||||
// Process each line - only store line numbers, not content
|
// Process each line - only store line numbers, not content
|
||||||
for (line_number, content) in lines {
|
for (line_number, content) in lines {
|
||||||
if params.matches_line(&content, ®ex_matcher) {
|
// If date range is enabled and query is empty, include all lines in range
|
||||||
|
let should_include = if params.date_range_enabled && params.query.is_empty() {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
params.matches_line(&content, ®ex_matcher)
|
||||||
|
};
|
||||||
|
|
||||||
|
if should_include {
|
||||||
chunk_results.push(FilteredLine { line_number });
|
chunk_results.push(FilteredLine { line_number });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ pub struct SearchPanelState {
|
|||||||
pub case_sensitive: bool,
|
pub case_sensitive: bool,
|
||||||
pub use_regex: bool,
|
pub use_regex: bool,
|
||||||
pub history: Vec<String>,
|
pub history: Vec<String>,
|
||||||
|
pub date_range_enabled: bool,
|
||||||
|
pub date_from: String,
|
||||||
|
pub date_to: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SearchPanelActions {
|
pub struct SearchPanelActions {
|
||||||
@@ -75,8 +78,9 @@ pub fn render_search_panel(
|
|||||||
.checkbox(&mut state.case_sensitive, "Case sensitive")
|
.checkbox(&mut state.case_sensitive, "Case sensitive")
|
||||||
.changed();
|
.changed();
|
||||||
let regex_changed = ui.checkbox(&mut state.use_regex, "Regex").changed();
|
let regex_changed = ui.checkbox(&mut state.use_regex, "Regex").changed();
|
||||||
|
let date_range_changed = ui.checkbox(&mut state.date_range_enabled, "Date range").changed();
|
||||||
|
|
||||||
if case_changed || regex_changed {
|
if case_changed || regex_changed || date_range_changed {
|
||||||
actions.config_changed = true;
|
actions.config_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,6 +107,28 @@ pub fn render_search_panel(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Date range fields (show when date_range_enabled is true)
|
||||||
|
if state.date_range_enabled {
|
||||||
|
ui.add_space(6.0);
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.label("From:");
|
||||||
|
ui.add(
|
||||||
|
egui::TextEdit::singleline(&mut state.date_from)
|
||||||
|
.desired_width(180.0)
|
||||||
|
.hint_text("2025-01-01 00:00:00")
|
||||||
|
);
|
||||||
|
|
||||||
|
ui.add_space(8.0);
|
||||||
|
|
||||||
|
ui.label("To:");
|
||||||
|
ui.add(
|
||||||
|
egui::TextEdit::singleline(&mut state.date_to)
|
||||||
|
.desired_width(180.0)
|
||||||
|
.hint_text("2025-01-01 01:00:00")
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Progress bar
|
// Progress bar
|
||||||
if search_state.is_searching() {
|
if search_state.is_searching() {
|
||||||
ui.add_space(6.0);
|
ui.add_space(6.0);
|
||||||
|
|||||||
Reference in New Issue
Block a user