Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions assets/org.deepin.anything.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,17 @@
"description[zh_CN]": "提交持久化索引超时时间",
"permissions": "readwrite",
"visibility": "public"
},
"pending_events_trigger_updating": {
"value": 5000,
"serial": 0,
"flags": [],
"name": "Number of events that trigger updating",
"name[zh_CN]": "触发 updating 的事件数",
"description": "Number of events that trigger updating",
"description[zh_CN]": "触发 updating 的事件数",
"permissions": "readwrite",
"visibility": "public"
}
}
}
2 changes: 2 additions & 0 deletions src/daemon/include/core/base_event_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ class base_event_handler
std::atomic<bool> stop_scan_directory_;

std::mutex config_access_mtx_;

gint batch_count_;
};

#endif // ANYTHING_BASE_EVENT_HANDLER_H_
2 changes: 2 additions & 0 deletions src/daemon/include/core/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ struct event_handler_config {
std::map<std::string, std::string> file_type_mapping_original;
int commit_volatile_index_timeout;
int commit_persistent_index_timeout;
int pending_events_trigger_updating;
};

void print_event_handler_config(const event_handler_config &config);
Expand Down Expand Up @@ -54,6 +55,7 @@ class Config {
std::string log_level_;
int commit_volatile_index_timeout_;
int commit_persistent_index_timeout_;
int pending_events_trigger_updating_;

void* dbus_connection_;
std::string resource_path_;
Expand Down
4 changes: 4 additions & 0 deletions src/daemon/include/core/file_index_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ enum class index_status {
loading,
scanning,
monitoring,
updating,
closed,
};

Expand Down Expand Up @@ -75,6 +76,9 @@ class file_index_manager {
bool refresh_indexes(const std::vector<std::string>& blacklist_paths, bool nrt, bool check_exist);

void set_index_invalid();

void set_index_updating();

private:
/// Refresh the index reader if there are changes
void try_refresh_reader(bool nrt = false);
Expand Down
20 changes: 19 additions & 1 deletion src/daemon/src/core/base_event_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ base_event_handler::base_event_handler(const event_handler_config &config)
commit_persistent_index_timeout_(config_.commit_persistent_index_timeout),
index_status_(anything::index_status::loading),
event_process_thread_count_(0),
stop_scan_directory_(false) {
stop_scan_directory_(false),
batch_count_(0) {
index_dirty_ = index_manager_.refresh_indexes(get_blacklist_paths(), false, true);

// The timer thread is started only after all initialization is completed
Expand Down Expand Up @@ -71,6 +72,13 @@ bool base_event_handler::handle_config_change(const std::string &key, const even
if (key == "blacklist_paths") {
set_blacklist_paths(new_config.blacklist_paths);
return true;
} else if (key == "pending_events_trigger_updating") {
// 简单数据类型更新不加锁
spdlog::info("pending_events_trigger_updating updated: {} -> {}",
config_.pending_events_trigger_updating,
new_config.pending_events_trigger_updating);
config_.pending_events_trigger_updating = new_config.pending_events_trigger_updating;
return true;
} else {
spdlog::info("Dynamic updates of config are not supported: {}", key);
return false;
Expand Down Expand Up @@ -162,13 +170,21 @@ void base_event_handler::eat_jobs(std::vector<anything::index_job>& jobs, std::s
std::make_move_iterator(jobs.begin()),
std::make_move_iterator(jobs.begin() + number));
jobs.erase(jobs.begin(), jobs.begin() + number);
g_atomic_int_inc(&batch_count_);
pool_.enqueue_detach([this, processing_jobs = std::move(processing_jobs)]() {
g_atomic_int_inc(&this->event_process_thread_count_);
for (const auto& job : processing_jobs) {
eat_job(job);
}
g_atomic_int_dec_and_test(&this->event_process_thread_count_);
g_atomic_int_dec_and_test(&this->batch_count_);
});

if ((g_atomic_int_get(&batch_count_)*(int)batch_size_) >= config_.pending_events_trigger_updating &&
index_status_ == anything::index_status::monitoring) {
index_status_ = anything::index_status::updating;
index_manager_.set_index_updating();
}
}

void base_event_handler::eat_job(const anything::index_job& job) {
Expand Down Expand Up @@ -287,6 +303,8 @@ void base_event_handler::timer_worker(int64_t interval) {
--commit_volatile_index_timeout_;
if (commit_volatile_index_timeout_ == 0 && jobs_.empty() && !pool_.busy() &&
g_atomic_int_get(&event_process_thread_count_) == 0) {
if (index_status_ == anything::index_status::updating)
index_status_ = anything::index_status::monitoring;
if (!index_manager_.commit(index_status_)) {
spdlog::info("Failed to commit index");
set_index_invalid_and_restart();
Expand Down
12 changes: 12 additions & 0 deletions src/daemon/src/core/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
#define COMMIT_PERSISTENT_INDEX_TIMEOUT_MIN 60
#define COMMIT_PERSISTENT_INDEX_TIMEOUT_MAX 3600

#define PENDING_EVENTS_TRIGGER_UPDATING_DEFAULT (5 * 1000)
#define PENDING_EVENTS_TRIGGER_UPDATING_MIN 200
#define PENDING_EVENTS_TRIGGER_UPDATING_MAX (100 * 1000)

void print_event_handler_config(const event_handler_config &config) {
spdlog::info("Persistent index dir: {}", config.persistent_index_dir);
spdlog::info("Volatile index dir: {}", config.volatile_index_dir);
Expand All @@ -37,6 +41,7 @@
}
spdlog::info("Commit volatile index timeout: {}", config.commit_volatile_index_timeout);
spdlog::info("Commit persistent index timeout: {}", config.commit_persistent_index_timeout);
spdlog::info("Number of events that trigger updating: {}", config.pending_events_trigger_updating);
}

// 获取dconfig资源路径
Expand Down Expand Up @@ -264,6 +269,7 @@
}
config.commit_volatile_index_timeout = commit_volatile_index_timeout_;
config.commit_persistent_index_timeout = commit_persistent_index_timeout_;
config.pending_events_trigger_updating = pending_events_trigger_updating_;

return config;
}
Expand Down Expand Up @@ -371,7 +377,13 @@
commit_persistent_index_timeout_ = COMMIT_PERSISTENT_INDEX_TIMEOUT_DEFAULT;
}

pending_events_trigger_updating_ = get_config_int64((GDBusConnection*)dbus_connection_, resource_path_, "pending_events_trigger_updating");

Check warning on line 380 in src/daemon/src/core/config.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

C-style pointer casting detected. C++ offers four different kinds of casts as replacements: static_cast, const_cast, dynamic_cast and reinterpret_cast. A C-style cast could evaluate to any of those automatically, thus it is considered safer if the programmer explicitly states which kind of cast is expected.
if (pending_events_trigger_updating_ < PENDING_EVENTS_TRIGGER_UPDATING_MIN ||
pending_events_trigger_updating_ > PENDING_EVENTS_TRIGGER_UPDATING_MAX) {
pending_events_trigger_updating_ = PENDING_EVENTS_TRIGGER_UPDATING_DEFAULT;
}

log_level_ = get_config_string((GDBusConnection*)dbus_connection_, resource_path_, LOG_LEVEL_KEY);

Check warning on line 386 in src/daemon/src/core/config.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

C-style pointer casting detected. C++ offers four different kinds of casts as replacements: static_cast, const_cast, dynamic_cast and reinterpret_cast. A C-style cast could evaluate to any of those automatically, thus it is considered safer if the programmer explicitly states which kind of cast is expected.

return true;
}
Expand Down
3 changes: 2 additions & 1 deletion src/daemon/src/core/default_event_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,8 @@ bool default_event_handler::handle_config_change(const std::string &key, const e
if (!base_event_handler::handle_config_change(key, new_config))
return false;

bool handled = (key == "blacklist_paths" && handle_blacklist_paths_change(config_, new_config));
bool handled = (key == "blacklist_paths" && handle_blacklist_paths_change(config_, new_config)) ||
key == "pending_events_trigger_updating"; // 不需额外处理

if (handled)
config_ = new_config;
Expand Down
8 changes: 8 additions & 0 deletions src/daemon/src/core/file_index_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,11 @@ void file_index_manager::set_index_invalid()
}
}

void file_index_manager::set_index_updating()
{
save_index_status(index_status::updating);
}

void file_index_manager::try_refresh_reader(bool nrt) {
std::lock_guard<std::mutex> lock(reader_mtx_);
if (nrt) {
Expand Down Expand Up @@ -701,6 +706,9 @@ void file_index_manager::save_index_status(index_status status) {
case index_status::monitoring:
status_str = "monitoring";
break;
case index_status::updating:
status_str = "updating";
break;
case index_status::closed:
status_str = "closed";
break;
Expand Down
1 change: 1 addition & 0 deletions src/searcher/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ target_link_libraries(deepin-anything-searcher
${LUCENE_CONTRIB_LIBRARIES}
Threads::Threads
${Boost_LIBRARIES}
stdc++fs
)

# Install
Expand Down
108 changes: 96 additions & 12 deletions src/searcher/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
// SPDX-License-Identifier: GPL-3.0-or-later

#include "searcher.h"
#include <iostream>

Check warning on line 7 in src/searcher/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <iostream> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <string>

Check warning on line 8 in src/searcher/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <string> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <vector>

Check warning on line 9 in src/searcher/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <vector> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <fstream>

Check warning on line 10 in src/searcher/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <fstream> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <sstream>

Check warning on line 11 in src/searcher/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <sstream> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <filesystem>

Check warning on line 12 in src/searcher/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <filesystem> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <algorithm>

Check warning on line 13 in src/searcher/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <algorithm> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <glib.h>

Check warning on line 14 in src/searcher/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <glib.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <unistd.h>

void printUsage(const char* programName) {
Expand All @@ -21,10 +26,92 @@
std::cout << " " << programName << " \"txt\" (searches in /)" << std::endl;
}

void search_by_index(const std::string &path,
const std::string &query,
int max_results,
bool wildcard_query,
const std::string &index_path,
std::vector<std::string> &results)
{
// 创建搜索器实例
anything::Searcher searcher;

// 初始化搜索器
if (!searcher.initialize(index_path)) {
std::cerr << "Failed to initialize searcher" << std::endl;
return;
}

// 执行搜索
results = searcher.search(path, query, max_results, wildcard_query);
}

void search_by_scan(const std::string &path,
const std::string &query,
std::vector<std::string> &results)
{
// 在目录 path 下, 查找包含 query 字符串的文件名和目录名, 将查找结果保存到 results
try {
// 检查路径是否存在且为目录
if (!std::filesystem::exists(path) || !std::filesystem::is_directory(path)) {
std::cerr << "Path does not exist or is not a directory: " << path << std::endl;
return;
}

// 递归遍历目录
for (const auto& entry : std::filesystem::recursive_directory_iterator(
path, std::filesystem::directory_options::skip_permission_denied)) {

// 获取文件名(不包含路径)
std::string filename = entry.path().filename().string();

if (filename.find(query) != std::string::npos) {
// 将完整路径添加到结果中
results.push_back(entry.path().string());
}
}
} catch (const std::filesystem::filesystem_error& ex) {
std::cerr << "Filesystem error while scanning: " << ex.what() << std::endl;
} catch (const std::exception& ex) {
std::cerr << "Error while scanning: " << ex.what() << std::endl;
}
}

void search(const std::string &path,
const std::string &query,
int max_results,
bool wildcard_query,
const std::string &index_path,
std::vector<std::string> &results)
{
// 查看指定文件中是否包含 '"status": "updating"' 字符串
std::string status_file = index_path + "/status.json";
std::ifstream file(status_file);
if (!file.is_open()) {
std::cerr << "Fail to open status file: " << status_file << std::endl;
return;
}

std::stringstream buffer;
buffer << file.rdbuf();
std::string content = buffer.str();

bool found = content.find("\"status\": \"updating\"") != std::string::npos;

// 决定搜索方式
if (found) {
std::cout << "Index is updating, using scan search." << std::endl;
search_by_scan(path, query, results);
} else {
std::cout << "Index is ready, using index search." << std::endl;
search_by_index(path, query, max_results, wildcard_query, index_path, results);
}
}

int main(int argc, char* argv[]) {
std::string default_index_path = std::string(g_get_user_runtime_dir()) + "/deepin-anything-server";
const char* index_path = default_index_path.c_str();
const char* search_path = "/";
g_autofree char* search_path = nullptr;
const char* query = nullptr;
bool wildcard_query = false;
int opt;
Expand Down Expand Up @@ -53,23 +140,20 @@

// 获取搜索路径和查询
if (remaining_args == 2) {
search_path = argv[optind];
search_path = g_canonicalize_filename (argv[optind], NULL);
if (!search_path) {
std::cerr << "Fail to canonicalize search path: " << argv[optind] << std::endl;
return 1;
}
query = argv[optind + 1];
} else {
search_path = g_strdup("/");
query = argv[optind];
}

// 创建搜索器实例
anything::Searcher searcher;

// 初始化搜索器
if (!searcher.initialize(index_path)) {
std::cerr << "Failed to initialize searcher" << std::endl;
return 1;
}

// 执行搜索
auto results = searcher.search(search_path, query, 0, wildcard_query);
std::vector<std::string> results;
search(search_path, query, 0, wildcard_query, index_path, results);

// 输出结果
if (results.empty()) {
Expand Down