From: Gunnar Beutner Date: Thu, 20 Mar 2014 13:25:40 +0000 (+0100) Subject: Implement union() and intersection() functions. X-Git-Tag: v0.0.9~58 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=012c0caeec3b4f8012029dc9e5a1a08f4f95947b;p=icinga2 Implement union() and intersection() functions. Fixes #5801 --- diff --git a/doc/4.1-configuration-syntax.md b/doc/4.1-configuration-syntax.md index 4a848d88f..f602b5cd8 100644 --- a/doc/4.1-configuration-syntax.md +++ b/doc/4.1-configuration-syntax.md @@ -190,14 +190,16 @@ Functions can be called using the `()` operator: check_interval = len(MyGroups) * 1m } -Function | Description ----------------------|----------------------- -regex(pattern, text) | Returns true if the regex pattern matches the text, false otherwise. -match(pattern, text) | Returns true if the wildcard pattern matches the text, false otherwise. -len(value) | Returns the length of the value, i.e. the number of elements for an array or dictionary, or the length of the string in bytes. -string(value) | Converts the value to a string. -number(value) | Converts the value to a number. -bool(value) | Converts to value to a bool. +Function | Description +--------------------------------|----------------------- +regex(pattern, text) | Returns true if the regex pattern matches the text, false otherwise. +match(pattern, text) | Returns true if the wildcard pattern matches the text, false otherwise. +len(value) | Returns the length of the value, i.e. the number of elements for an array or dictionary, or the length of the string in bytes. +union(array, array, ...) | Returns an array containing all unique elements from the specified arrays. +intersection(array, array, ...) | Returns an array containing all unique elements which are common to all specified arrays. +string(value) | Converts the value to a string. +number(value) | Converts the value to a number. +bool(value) | Converts to value to a bool. ### Dictionary Operators diff --git a/lib/base/array.cpp b/lib/base/array.cpp index 54f3d6364..102d679e4 100644 --- a/lib/base/array.cpp +++ b/lib/base/array.cpp @@ -149,6 +149,14 @@ void Array::Remove(Array::Iterator it) m_Data.erase(it); } +void Array::Resize(size_t new_size) +{ + ASSERT(!OwnsLock()); + ObjectLock olock(this); + + m_Data.resize(new_size); +} + void Array::CopyTo(const Array::Ptr& dest) const { ASSERT(!OwnsLock()); diff --git a/lib/base/array.h b/lib/base/array.h index c1ff75fc3..744c790ca 100644 --- a/lib/base/array.h +++ b/lib/base/array.h @@ -55,6 +55,8 @@ public: void Remove(unsigned int index); void Remove(Iterator it); + void Resize(size_t new_size); + void CopyTo(const Array::Ptr& dest) const; Array::Ptr ShallowClone(void) const; diff --git a/lib/base/scriptfunctionwrapper.cpp b/lib/base/scriptfunctionwrapper.cpp index 2e0b96045..d5d1efb5d 100644 --- a/lib/base/scriptfunctionwrapper.cpp +++ b/lib/base/scriptfunctionwrapper.cpp @@ -32,8 +32,3 @@ boost::function& arguments)> icinga::WrapScriptF { return boost::bind(&ScriptFunctionWrapperVV, function, _1); } - -boost::function& arguments)> icinga::WrapScriptFunction(Value (*function)(const std::vector&)) -{ - return boost::bind(function, _1); -} diff --git a/lib/base/scriptfunctionwrapper.h b/lib/base/scriptfunctionwrapper.h index 7edd2013b..c629a2e53 100644 --- a/lib/base/scriptfunctionwrapper.h +++ b/lib/base/scriptfunctionwrapper.h @@ -267,7 +267,11 @@ boost::function& arguments)> WrapScriptFunction( return boost::bind(&ScriptFunctionWrapperR, function, _1); } -boost::function& arguments)> I2_BASE_API WrapScriptFunction(Value (*function)(const std::vector&)); +template +boost::function& arguments)> WrapScriptFunction(TR (*function)(const std::vector&)) +{ + return boost::bind(function, _1); +} } diff --git a/lib/methods/utilityfuncs.cpp b/lib/methods/utilityfuncs.cpp index 71a143691..290ab1576 100644 --- a/lib/methods/utilityfuncs.cpp +++ b/lib/methods/utilityfuncs.cpp @@ -24,12 +24,15 @@ #include "base/array.h" #include "base/dictionary.h" #include +#include using namespace icinga; REGISTER_SCRIPTFUNCTION(regex, &UtilityFuncs::Regex); REGISTER_SCRIPTFUNCTION(match, &Utility::Match); REGISTER_SCRIPTFUNCTION(len, &UtilityFuncs::Len); +REGISTER_SCRIPTFUNCTION(union, &UtilityFuncs::Union); +REGISTER_SCRIPTFUNCTION(intersection, &UtilityFuncs::Intersection); bool UtilityFuncs::Regex(const String& pattern, const String& text) { @@ -49,4 +52,48 @@ int UtilityFuncs::Len(const Value& value) } else { return Convert::ToString(value).GetLength(); } -} \ No newline at end of file +} + +Array::Ptr UtilityFuncs::Union(const std::vector& arguments) +{ + std::set values; + + BOOST_FOREACH(const Value& varr, arguments) { + Array::Ptr arr = varr; + + BOOST_FOREACH(const Value& value, arr) { + values.insert(value); + } + } + + Array::Ptr result = make_shared(); + BOOST_FOREACH(const Value& value, values) { + result->Add(value); + } + + return result; +} + +Array::Ptr UtilityFuncs::Intersection(const std::vector& arguments) +{ + if (arguments.size() == 0) + return make_shared(); + + Array::Ptr result = make_shared(); + + Array::Ptr arr1 = static_cast(arguments[0])->ShallowClone(); + + for (int i = 1; i < arguments.size(); i++) { + std::sort(arr1->Begin(), arr1->End()); + + Array::Ptr arr2 = static_cast(arguments[i])->ShallowClone(); + std::sort(arr2->Begin(), arr2->End()); + + result->Resize(std::max(arr1->GetLength(), arr2->GetLength())); + Array::Iterator it = std::set_intersection(arr1->Begin(), arr1->End(), arr2->Begin(), arr2->End(), result->Begin()); + result->Resize(it - result->Begin()); + arr1 = result; + } + + return result; +} diff --git a/lib/methods/utilityfuncs.h b/lib/methods/utilityfuncs.h index cdaa51da4..4dbbb57f4 100644 --- a/lib/methods/utilityfuncs.h +++ b/lib/methods/utilityfuncs.h @@ -22,6 +22,7 @@ #include "methods/i2-methods.h" #include "base/qstring.h" +#include "base/array.h" namespace icinga { @@ -34,6 +35,8 @@ class I2_METHODS_API UtilityFuncs public: static bool Regex(const String& pattern, const String& text); static int Len(const Value& value); + static Array::Ptr Union(const std::vector& arguments); + static Array::Ptr Intersection(const std::vector& arguments); private: UtilityFuncs(void);