]> granicus.if.org Git - icinga2/commitdiff
Implement union() and intersection() functions.
authorGunnar Beutner <gunnar.beutner@netways.de>
Thu, 20 Mar 2014 13:25:40 +0000 (14:25 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Thu, 20 Mar 2014 13:25:40 +0000 (14:25 +0100)
Fixes #5801

doc/4.1-configuration-syntax.md
lib/base/array.cpp
lib/base/array.h
lib/base/scriptfunctionwrapper.cpp
lib/base/scriptfunctionwrapper.h
lib/methods/utilityfuncs.cpp
lib/methods/utilityfuncs.h

index 4a848d88f575e1a5c6995a9e87f8ed86dbccf647..f602b5cd861de004c28ff1cd642b9c8a98306dec 100644 (file)
@@ -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.
 
 ### <a id="operators"></a> Dictionary Operators
 
index 54f3d6364bd1f578dbd6ce9e0d60bf346ed16da8..102d679e4c7716d4446ebabdd763da17e6db07c8 100644 (file)
@@ -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());
index c1ff75fc3b830dc48fb0bb01541b3761ae07706e..744c790ca9958b9d818c2b60c0b0807b08ad0f13 100644 (file)
@@ -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;
 
index 2e0b96045100146e6a59dfc564b9729d2a197040..d5d1efb5dce0d3c3a71efe2a8204f9bade14b77b 100644 (file)
@@ -32,8 +32,3 @@ boost::function<Value (const std::vector<Value>& arguments)> icinga::WrapScriptF
 {
        return boost::bind(&ScriptFunctionWrapperVV, function, _1);
 }
-
-boost::function<Value (const std::vector<Value>& arguments)> icinga::WrapScriptFunction(Value (*function)(const std::vector<Value>&))
-{
-       return boost::bind(function, _1);
-}
index 7edd2013bded3645e3665a3ebd29421304b8a1f1..c629a2e538457aea645747d603d55a4e63030628 100644 (file)
@@ -267,7 +267,11 @@ boost::function<Value (const std::vector<Value>& arguments)> WrapScriptFunction(
        return boost::bind(&ScriptFunctionWrapperR<TR, T0, T1, T2, T3, T4, T5>, function, _1);
 }
 
-boost::function<Value (const std::vector<Value>& arguments)> I2_BASE_API WrapScriptFunction(Value (*function)(const std::vector<Value>&));
+template<typename TR>
+boost::function<TR (const std::vector<Value>& arguments)> WrapScriptFunction(TR (*function)(const std::vector<Value>&))
+{
+       return boost::bind(function, _1);
+}
 
 }
 
index 71a143691e8534ac262b05abaad3ec0252fe149f..290ab157648c6977db11caa865237e9cdd71d511 100644 (file)
 #include "base/array.h"
 #include "base/dictionary.h"
 #include <boost/regex.hpp>
+#include <algorithm>
 
 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<Value>& arguments)
+{
+       std::set<Value> 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<Array>();
+       BOOST_FOREACH(const Value& value, values) {
+               result->Add(value);
+       }
+
+       return result;
+}
+
+Array::Ptr UtilityFuncs::Intersection(const std::vector<Value>& arguments)
+{
+       if (arguments.size() == 0)
+               return make_shared<Array>();
+
+       Array::Ptr result = make_shared<Array>();
+
+       Array::Ptr arr1 = static_cast<Array::Ptr>(arguments[0])->ShallowClone();
+
+       for (int i = 1; i < arguments.size(); i++) {
+               std::sort(arr1->Begin(), arr1->End());
+
+               Array::Ptr arr2 = static_cast<Array::Ptr>(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;
+}
index cdaa51da4e5f52815b821b8ea1973ca395b0e5ab..4dbbb57f40294cea500cc8d122ffa54c3ec5ab95 100644 (file)
@@ -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<Value>& arguments);
+       static Array::Ptr Intersection(const std::vector<Value>& arguments);
 
 private:
        UtilityFuncs(void);