From af7443c48b8cc7b2fef9d9bed6b44d6fcaa1025f Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Sun, 10 Jul 2016 14:00:51 +0100 Subject: [PATCH] Implement tagging by regex. --- src/backends/redis/backend_redis.cpp | 1 + src/backends/redis/tag.cpp | 32 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/backends/redis/backend_redis.cpp b/src/backends/redis/backend_redis.cpp index 822b4e0..491d34a 100644 --- a/src/backends/redis/backend_redis.cpp +++ b/src/backends/redis/backend_redis.cpp @@ -128,6 +128,7 @@ namespace dindb { } void BackendRedis::tag_files (const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet) { + dindb::tag_files(m_redis, m_tag_if_in_set, parRegexes, parTags, parSet); } void BackendRedis::delete_tags (const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) { diff --git a/src/backends/redis/tag.cpp b/src/backends/redis/tag.cpp index 99fbba1..dfcfa35 100644 --- a/src/backends/redis/tag.cpp +++ b/src/backends/redis/tag.cpp @@ -25,6 +25,18 @@ namespace dindb { namespace { + std::vector compile_regexes (const std::vector& parRegexes) { + std::vector retval; + retval.reserve(parRegexes.size()); + for (const auto& str : parRegexes) { + retval.emplace_back(std::regex( + str, + std::regex_constants::optimize | std::regex_constants::nosubs | std::regex_constants::ECMAScript + )); + } + assert(retval.size() == parRegexes.size()); + return retval; + } } //unnamed namespace void tag_files (redis::Command& parRedis, redis::Script& parTagIfInSet, const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) { @@ -46,6 +58,26 @@ namespace dindb { } void tag_files (redis::Command& parRedis, redis::Script& parTagIfInSet, const std::vector& parRegexes, const std::vector& parTags, GroupIDType parSet) { + using dinhelp::lexical_cast; + + auto batch = parRedis.make_batch(); + const std::string set_key = (parSet != InvalidGroupID ? PROGRAM_NAME ":set:" + lexical_cast(parSet) : ""); + const auto regexes = compile_regexes(parRegexes); + for (const auto& itm : parRedis.scan(PROGRAM_NAME ":file:*")) { + const auto& file_key = itm; + const auto path = redis::get_string(parRedis.run("HGET", file_key, "path")); + for (const auto& regex : regexes) { + if (not std::regex_search(path, regex)) + continue; + + for (const auto &tag : parTags) { + std::ostringstream oss; + oss << PROGRAM_NAME ":tag:" << tag; + const std::string tag_key = oss.str(); + parTagIfInSet.run(batch, std::make_tuple(tag_key, file_key), std::make_tuple(set_key)); + } + } + } } void delete_tags (redis::Command& parRedis, redis::Script& parDeleIfInSet, const std::vector& parFiles, const std::vector& parTags, GroupIDType parSet) {