From 84bae572d353b03ecb3498df83ba301a456b6c6f Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Thu, 21 Dec 2017 15:18:48 -0500 Subject: Added mask filters and fixed the synonym query refs #1 --- lib/filter.cpp | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/filter.h | 22 +++++++- lib/statement.cpp | 12 +++++ lib/word.cpp | 24 +++++---- 4 files changed, 193 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/lib/filter.cpp b/lib/filter.cpp index 1472eeb..fec0fd3 100644 --- a/lib/filter.cpp +++ b/lib/filter.cpp @@ -92,6 +92,15 @@ namespace verbly { break; } + + case type::mask: + { + new(&mask_.name) std::string(other.mask_.name); + mask_.internal = other.mask_.internal; + new(&mask_.subfilter) std::unique_ptr(new filter(*other.mask_.subfilter)); + + break; + } } } @@ -122,6 +131,9 @@ namespace verbly { field tempCompareField; std::list tempChildren; bool tempOrlogic; + std::string tempMaskName; + bool tempMaskInternal; + std::unique_ptr tempMaskSubfilter; switch (tempType) { @@ -201,6 +213,15 @@ namespace verbly { break; } + + case type::mask: + { + tempMaskName = std::move(first.mask_.name); + tempMaskInternal = first.mask_.internal; + tempMaskSubfilter = std::move(first.mask_.subfilter); + + break; + } } first.~filter(); @@ -285,6 +306,15 @@ namespace verbly { break; } + + case type::mask: + { + new(&first.mask_.name) std::string(std::move(second.mask_.name)); + first.mask_.internal = second.mask_.internal; + new(&first.mask_.subfilter) std::unique_ptr(std::move(second.mask_.subfilter)); + + break; + } } second.~filter(); @@ -369,6 +399,15 @@ namespace verbly { break; } + + case type::mask: + { + new(&first.mask_.name) std::string(std::move(tempMaskName)); + first.mask_.internal = tempMaskInternal; + new(&first.mask_.subfilter) std::unique_ptr(std::move(tempMaskSubfilter)); + + break; + } } } @@ -444,6 +483,17 @@ namespace verbly { break; } + + case type::mask: + { + using string_type = std::string; + using ptr_type = std::unique_ptr; + + mask_.name.~string_type(); + mask_.subfilter.~ptr_type(); + + break; + } } } @@ -1024,6 +1074,44 @@ namespace verbly { } } + filter::filter(std::string name, bool internal, filter subfilter) : + type_(type::mask) + { + new(&mask_.name) std::string(std::move(name)); + mask_.internal = internal; + new(&mask_.subfilter) std::unique_ptr(new filter(std::move(subfilter))); + } + + const std::string& filter::getMaskName() const + { + if (type_ == type::mask) + { + return mask_.name; + } else { + throw std::domain_error("This filter is not a mask filter"); + } + } + + bool filter::isMaskInternal() const + { + if (type_ == type::mask) + { + return mask_.internal; + } else { + throw std::domain_error("This filter is not a mask filter"); + } + } + + const filter& filter::getMaskFilter() const + { + if (type_ == type::mask) + { + return *mask_.subfilter; + } else { + throw std::domain_error("This filter is not a mask filter"); + } + } + filter filter::operator!() const { switch (type_) @@ -1145,6 +1233,11 @@ namespace verbly { return result; } + + case type::mask: + { + return {mask_.name, mask_.internal, !*mask_.subfilter}; + } } } @@ -1168,6 +1261,7 @@ namespace verbly { } case type::singleton: + case type::mask: { filter result(false); result.group_.children.push_back(*this); @@ -1205,6 +1299,7 @@ namespace verbly { } case type::singleton: + case type::mask: { filter result(true); result.group_.children.push_back(*this); @@ -1232,6 +1327,11 @@ namespace verbly { } } + filter filter::mask(std::string name, filter subfilter) + { + return {std::move(name), false, std::move(subfilter)}; + } + filter filter::normalize(object context) const { { @@ -1408,6 +1508,7 @@ namespace verbly { filter result(group_.orlogic); std::map positiveJoins; std::map negativeJoins; + std::map, filter> masks; for (const filter& child : group_.children) { @@ -1502,6 +1603,20 @@ namespace verbly { break; } + + case type::mask: + { + auto maskId = std::tie(normalized.mask_.name, normalized.mask_.internal); + + if (!masks.count(maskId)) + { + masks[maskId] = filter(group_.orlogic); + } + + masks.at(maskId) += std::move(*normalized.mask_.subfilter); + + break; + } } } @@ -1521,8 +1636,22 @@ namespace verbly { result += !(joinOn %= joinCondition.normalize(joinOn.getJoinObject())); } + for (auto& mapping : masks) + { + const std::string& name = std::get<0>(mapping.first); + bool internal = std::get<1>(mapping.first); + filter& subfilter = mapping.second; + + result += {name, internal, std::move(subfilter)}; + } + return result; } + + case type::mask: + { + return {mask_.name, mask_.internal, mask_.subfilter->normalize(context)}; + } } } } @@ -1552,10 +1681,27 @@ namespace verbly { if (result.group_.children.empty()) { result = {}; + } else if (result.group_.children.size() == 1) + { + filter tempChild = std::move(result.group_.children.front()); + + result = std::move(tempChild); } return result; } + + case type::mask: + { + filter subfilter = mask_.subfilter->compact(); + + if (subfilter.type_ == type::empty) + { + return {}; + } else { + return {mask_.name, mask_.internal, std::move(subfilter)}; + } + } } } diff --git a/lib/filter.h b/lib/filter.h index a12a822..942fe18 100644 --- a/lib/filter.h +++ b/lib/filter.h @@ -14,7 +14,8 @@ namespace verbly { enum class type { empty, singleton, - group + group, + mask }; enum class comparison { @@ -106,6 +107,16 @@ namespace verbly { const_iterator end() const; + // Mask + + filter(std::string name, bool internal, filter subfilter); + + const std::string& getMaskName() const; + + bool isMaskInternal() const; + + const filter& getMaskFilter() const; + // Negation filter operator!() const; @@ -118,6 +129,10 @@ namespace verbly { filter& operator&=(filter condition); filter& operator|=(filter condition); + // Maskifying + + static filter mask(std::string name, filter subfilter); + // Utility filter normalize(object context) const; @@ -141,6 +156,11 @@ namespace verbly { std::list children; bool orlogic; } group_; + struct { + std::string name; + bool internal; + std::unique_ptr subfilter; + } mask_; }; type type_ = type::empty; diff --git a/lib/statement.cpp b/lib/statement.cpp index e84a402..5dd3789 100644 --- a/lib/statement.cpp +++ b/lib/statement.cpp @@ -594,6 +594,18 @@ namespace verbly { return grp; } + + case filter::type::mask: + { + condition result = parseFilter(clause.getMaskFilter()); + + if (result.getType() == condition::type::empty) + { + return {}; + } else { + return result; + } + } } } diff --git a/lib/word.cpp b/lib/word.cpp index dc269c9..6f0fe22 100644 --- a/lib/word.cpp +++ b/lib/word.cpp @@ -172,20 +172,24 @@ namespace verbly { filter word::synonyms_field::operator%=(filter joinCondition) const { - return (verbly::notion::words %= ( - std::move(joinCondition) - && (filter( - verbly::word::id, - filter::comparison::field_does_not_equal, - verbly::word::id)))); + return (verbly::word::notions %= + filter("synonyms", true, + (verbly::notion::words %= ( + std::move(joinCondition) + && (filter( + verbly::word::id, + filter::comparison::field_does_not_equal, + verbly::word::id)))))); } word::synonyms_field::operator filter() const { - return (verbly::notion::words %= filter( - verbly::word::id, - filter::comparison::field_does_not_equal, - verbly::word::id)); + return (verbly::word::notions %= + filter("synonyms", true, + (verbly::notion::words %= filter( + verbly::word::id, + filter::comparison::field_does_not_equal, + verbly::word::id)))); } }; -- cgit 1.4.1