mirror of
https://github.com/KingDuckZ/dindexer.git
synced 2025-02-17 11:45:50 +00:00
Use boost::regex and implement delete_all_tags by regex.
std::regex doesn't understand the (?i) modifier, which makes it throw an exception on regex generated by the frontend. I can't change the frontend, or the postgre plugin would break... thankfully boost comes to the rescue :)
This commit is contained in:
parent
83fe7c75d6
commit
016f357704
2 changed files with 61 additions and 6 deletions
|
@ -5,6 +5,7 @@ set(DINDEXER_REDIS_SCRIPTS_PATH "${CMAKE_INSTALL_PREFIX}/${bare_name}/redis" CAC
|
|||
find_package(hiredis 0.11.0 REQUIRED)
|
||||
find_package(CryptoPP 5.6)
|
||||
find_package(libev 4.0 REQUIRED)
|
||||
find_package(Boost 1.53.0 REQUIRED COMPONENTS regex)
|
||||
|
||||
add_library(${PROJECT_NAME} SHARED
|
||||
backend_redis.cpp
|
||||
|
@ -23,6 +24,7 @@ target_include_directories(${PROJECT_NAME} SYSTEM
|
|||
PRIVATE ${HIREDIS_INCLUDE_DIRS}
|
||||
PRIVATE ${CMAKE_SOURCE_DIR}/lib/better-enums
|
||||
PRIVATE ${LIBEV_INCLUDE_DIRS}
|
||||
PRIVATE ${Boost_INCLUDE_DIRS}
|
||||
)
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
|
||||
|
@ -33,6 +35,7 @@ target_link_libraries(${PROJECT_NAME}
|
|||
PUBLIC ${bare_name}-core
|
||||
PRIVATE ${HIREDIS_LIBRARIES}
|
||||
PRIVATE ${LIBEV_LIBRARIES}
|
||||
PRIVATE ${Boost_LIBRARIES}
|
||||
)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "dindexer-core/split_tags.hpp"
|
||||
#include <sstream>
|
||||
#include <tuple>
|
||||
#include <regex>
|
||||
#include <boost/regex.hpp>
|
||||
#include <unordered_set>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
|
@ -41,13 +41,13 @@ namespace dindb {
|
|||
return PROGRAM_NAME ":file:" + dinhelp::lexical_cast<std::string>(parID);
|
||||
}
|
||||
|
||||
std::vector<std::regex> compile_regexes (const std::vector<std::string>& parRegexes) {
|
||||
std::vector<std::regex> retval;
|
||||
std::vector<boost::regex> compile_regexes (const std::vector<std::string>& parRegexes) {
|
||||
std::vector<boost::regex> retval;
|
||||
retval.reserve(parRegexes.size());
|
||||
for (const auto& str : parRegexes) {
|
||||
retval.emplace_back(std::regex(
|
||||
retval.emplace_back(boost::regex(
|
||||
str,
|
||||
std::regex_constants::optimize | std::regex_constants::nosubs | std::regex_constants::ECMAScript
|
||||
boost::regex_constants::optimize | boost::regex_constants::nosubs | boost::regex_constants::perl
|
||||
));
|
||||
}
|
||||
assert(retval.size() == parRegexes.size());
|
||||
|
@ -83,7 +83,7 @@ namespace dindb {
|
|||
|
||||
auto batch = parRedis.make_batch();
|
||||
for (const auto ®ex : regexes) {
|
||||
if (not std::regex_search(path, regex))
|
||||
if (not boost::regex_search(path, regex))
|
||||
continue;
|
||||
|
||||
for (const auto &tag : parTags) {
|
||||
|
@ -92,10 +92,17 @@ namespace dindb {
|
|||
const std::string tag_key = oss.str();
|
||||
parTagIfInSet.run(batch, std::make_tuple(tag_key, file_key), std::make_tuple(set_key));
|
||||
}
|
||||
break;
|
||||
}
|
||||
batch.throw_if_failed();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T id_from_redis_key (const std::string& parKey) {
|
||||
assert(not parKey.empty());
|
||||
return dinhelp::lexical_cast<T>(dincore::split_and_trim(parKey, ':').back());
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
void tag_files (redis::Command& parRedis, redis::Script& parTagIfInSet, const std::vector<uint64_t>& parFiles, const std::vector<boost::string_ref>& parTags, GroupIDType parSet) {
|
||||
|
@ -135,6 +142,51 @@ namespace dindb {
|
|||
}
|
||||
|
||||
void delete_all_tags (redis::Command& parRedis, redis::Script& parDeleIfInSet, const std::vector<std::string>& parRegexes, GroupIDType parSet) {
|
||||
using dinhelp::lexical_cast;
|
||||
|
||||
const std::string set_key = (parSet != InvalidGroupID ? PROGRAM_NAME ":set:" + lexical_cast<std::string>(parSet) : "");
|
||||
const auto regexes = compile_regexes(parRegexes);
|
||||
|
||||
std::set<std::string> dele_tags;
|
||||
std::vector<uint64_t> ids;
|
||||
|
||||
for (const auto& itm : parRedis.scan(PROGRAM_NAME ":file:*")) {
|
||||
const auto& file_key = itm;
|
||||
auto file_reply = parRedis.run("HMGET", file_key, "path", "tags", "group_id");
|
||||
auto& file_replies = redis::get_array(file_reply);
|
||||
assert(file_replies.size() == 3);
|
||||
const auto group_id = id_from_redis_key<GroupIDType>(redis::get_string(file_replies[2]));
|
||||
if (parSet != InvalidGroupID and parSet != group_id)
|
||||
continue;
|
||||
|
||||
const auto path = redis::get_string(file_replies[0]);
|
||||
const auto tags_str = (file_replies[1].which() == redis::RedisVariantType_Nil ? std::string() : redis::get_string(file_replies[1]));
|
||||
const auto tags = dincore::split_tags(tags_str);
|
||||
const auto file_id = id_from_redis_key<FileIDType>(file_key);
|
||||
|
||||
for (const auto ®ex : regexes) {
|
||||
if (not boost::regex_search(path, regex))
|
||||
continue;
|
||||
|
||||
ids.push_back(file_id);
|
||||
|
||||
for (const auto &tag : tags) {
|
||||
dele_tags.insert(std::string(tag.data(), tag.size()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<boost::string_ref> dele_tags_vec;
|
||||
dele_tags_vec.reserve(dele_tags.size());
|
||||
std::transform(
|
||||
dele_tags.begin(),
|
||||
dele_tags.end(),
|
||||
std::back_inserter(dele_tags_vec),
|
||||
[](const std::string& parS) { return boost::string_ref(parS); }
|
||||
);
|
||||
|
||||
delete_tags(parRedis, parDeleIfInSet, ids, dele_tags_vec, parSet);
|
||||
}
|
||||
} //namespace dindb
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue