Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
uda-test-harness.h
Go to the documentation of this file.
1 // Copyright 2012 Cloudera Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 
16 #ifndef IMPALA_UDA_TEST_HARNESS_H
17 #define IMPALA_UDA_TEST_HARNESS_H
18 
19 #include <string>
20 #include <sstream>
21 #include <vector>
22 
23 #include <boost/scoped_ptr.hpp>
24 #include <boost/shared_ptr.hpp>
25 
26 #include "udf/udf.h"
27 #include "udf/udf-debug.h"
28 #include "udf/udf-test-harness.h"
29 
30 namespace impala_udf {
31 
33  ALL = 0,
35  ONE_LEVEL = 2,
36  TWO_LEVEL = 3,
37 };
38 
39 template<typename RESULT, typename INTERMEDIATE>
41  public:
42  typedef void (*InitFn)(FunctionContext* context, INTERMEDIATE* result);
43 
44  typedef void (*MergeFn)(FunctionContext* context, const INTERMEDIATE& src,
45  INTERMEDIATE* dst);
46 
47  typedef const INTERMEDIATE (*SerializeFn)(FunctionContext* context,
48  const INTERMEDIATE& type);
49 
50  typedef RESULT (*FinalizeFn)(FunctionContext* context, const INTERMEDIATE& value);
51 
55  typedef bool (*ResultComparator)(const RESULT& x, const RESULT& y);
56 
59  }
60 
62  void SetIntermediateSize(int byte_size) {
63  fixed_buffer_byte_size_ = byte_size;
64  }
65 
67  const std::string& GetErrorMsg() const { return error_msg_; }
68 
69  protected:
70  UdaTestHarnessBase(InitFn init_fn, MergeFn merge_fn,
71  SerializeFn serialize_fn, FinalizeFn finalize_fn)
72  : init_fn_(init_fn),
73  merge_fn_(merge_fn),
74  serialize_fn_(serialize_fn),
75  finalize_fn_(finalize_fn),
78  }
79 
82  : context_(context), harness_(harness) { }
83 
87  delete context_;
88  }
89 
90  FunctionContext* get() { return context_; }
91 
92  private:
95  };
96 
98  bool Execute(const RESULT& expected, UdaExecutionMode mode);
99 
101  bool CheckContext(FunctionContext* context);
102 
104  bool CheckResult(const RESULT& x, const RESULT& y);
105 
108  RESULT ExecuteSingleNode(ScopedFunctionContext* result_context);
109 
113  RESULT ExecuteOneLevel(int num_nodes, ScopedFunctionContext* result_context);
114 
117  RESULT ExecuteTwoLevel(int num1, int num2, ScopedFunctionContext* result_context);
118 
119  virtual void Update(int idx, FunctionContext* context, INTERMEDIATE* dst) = 0;
120 
126 
129 
132 
135 
137  std::string error_msg_;
138 };
139 
140 template<typename RESULT, typename INTERMEDIATE, typename INPUT>
141 class UdaTestHarness : public UdaTestHarnessBase<RESULT, INTERMEDIATE> {
142  public:
143  typedef void (*UpdateFn)(FunctionContext* context, const INPUT& input,
144  INTERMEDIATE* result);
145 
147 
149  typename BaseClass::InitFn init_fn,
150  UpdateFn update_fn,
151  typename BaseClass::MergeFn merge_fn,
152  typename BaseClass::SerializeFn serialize_fn,
153  typename BaseClass::FinalizeFn finalize_fn)
154  : BaseClass(init_fn, merge_fn, serialize_fn, finalize_fn),
155  update_fn_(update_fn) {
156  }
157 
159  bool Execute(const std::vector<INPUT>& values, const RESULT& expected,
160  UdaExecutionMode mode = ALL);
161 
164  template<typename T>
165  bool Execute(const std::vector<T>& values, const RESULT& expected,
166  UdaExecutionMode mode = ALL) {
167  input_.resize(values.size());
169  for (int i = 0; i < values.size(); ++i) {
170  input_[i] = &values[i];
171  }
172  return BaseClass::Execute(expected, mode);
173  }
174 
175  protected:
176  virtual void Update(int idx, FunctionContext* context, INTERMEDIATE* dst);
177 
178  private:
181  std::vector<const INPUT*> input_;
182 };
183 
184 template<typename RESULT, typename INTERMEDIATE, typename INPUT1, typename INPUT2>
185 class UdaTestHarness2 : public UdaTestHarnessBase<RESULT, INTERMEDIATE> {
186  public:
187  typedef void (*UpdateFn)(FunctionContext* context, const INPUT1& input1,
188  const INPUT2& input2, INTERMEDIATE* result);
189 
191 
193  typename BaseClass::InitFn init_fn,
194  UpdateFn update_fn,
195  typename BaseClass::MergeFn merge_fn,
196  typename BaseClass::SerializeFn serialize_fn,
197  typename BaseClass::FinalizeFn finalize_fn)
198  : BaseClass(init_fn, merge_fn, serialize_fn, finalize_fn),
199  update_fn_(update_fn) {
200  }
201 
203  bool Execute(const std::vector<INPUT1>& values1, const std::vector<INPUT2>& values2,
204  const RESULT& expected, UdaExecutionMode mode = ALL);
205 
206  protected:
207  virtual void Update(int idx, FunctionContext* context, INTERMEDIATE* dst);
208 
209  private:
211  const std::vector<INPUT1>* input1_;
212  const std::vector<INPUT2>* input2_;
213 };
214 
215 template<typename RESULT, typename INTERMEDIATE, typename INPUT1, typename INPUT2,
216  typename INPUT3>
217 class UdaTestHarness3 : public UdaTestHarnessBase<RESULT, INTERMEDIATE> {
218  public:
219  typedef void (*UpdateFn)(FunctionContext* context, const INPUT1& input1,
220  const INPUT2& input2, const INPUT3& input3, INTERMEDIATE* result);
221 
223 
225  typename BaseClass::InitFn init_fn,
226  UpdateFn update_fn,
227  typename BaseClass::MergeFn merge_fn,
228  typename BaseClass::SerializeFn serialize_fn,
229  typename BaseClass::FinalizeFn finalize_fn)
230  : BaseClass(init_fn, merge_fn, serialize_fn, finalize_fn),
231  update_fn_(update_fn) {
232  }
233 
235  bool Execute(const std::vector<INPUT1>& values1, const std::vector<INPUT2>& values2,
236  const std::vector<INPUT3>& values3,
237  const RESULT& expected, UdaExecutionMode mode = ALL);
238 
239  protected:
240  virtual void Update(int idx, FunctionContext* context, INTERMEDIATE* dst);
241 
242  private:
244  const std::vector<INPUT1>* input1_;
245  const std::vector<INPUT2>* input2_;
246  const std::vector<INPUT3>* input3_;
247 };
248 
249 template<typename RESULT, typename INTERMEDIATE, typename INPUT1, typename INPUT2,
250  typename INPUT3, typename INPUT4>
251 class UdaTestHarness4 : public UdaTestHarnessBase<RESULT, INTERMEDIATE> {
252  public:
253  typedef void (*UpdateFn)(FunctionContext* context, const INPUT1& input1,
254  const INPUT2& input2, const INPUT3& input3, const INPUT4& input4,
255  INTERMEDIATE* result);
256 
258 
260  typename BaseClass::InitFn init_fn,
261  UpdateFn update_fn,
262  typename BaseClass::MergeFn merge_fn,
263  typename BaseClass::SerializeFn serialize_fn,
264  typename BaseClass::FinalizeFn finalize_fn)
265  : BaseClass(init_fn, merge_fn, serialize_fn, finalize_fn),
266  update_fn_(update_fn) {
267  }
268 
270  bool Execute(const std::vector<INPUT1>& values1, const std::vector<INPUT2>& values2,
271  const std::vector<INPUT3>& values3, const std::vector<INPUT4>& values4,
272  const RESULT& expected, UdaExecutionMode mode = ALL);
273 
274  protected:
275  virtual void Update(int idx, FunctionContext* context, INTERMEDIATE* dst);
276 
277  private:
279  const std::vector<INPUT1>* input1_;
280  const std::vector<INPUT2>* input2_;
281  const std::vector<INPUT3>* input3_;
282  const std::vector<INPUT4>* input4_;
283 };
284 
285 }
286 
288 
289 #endif
bool Execute(const std::vector< INPUT1 > &values1, const std::vector< INPUT2 > &values2, const std::vector< INPUT3 > &values3, const std::vector< INPUT4 > &values4, const RESULT &expected, UdaExecutionMode mode=ALL)
Runs the UDA in all the modes, validating the result is 'expected' each time.
UdaTestHarnessBase< RESULT, INTERMEDIATE > BaseClass
void SetResultComparator(ResultComparator fn)
void(* UpdateFn)(FunctionContext *context, const INPUT1 &input1, const INPUT2 &input2, INTERMEDIATE *result)
void SetIntermediateSize(int byte_size)
This must be called if the INTERMEDIATE is TYPE_FIXED_BUFFER.
bool Execute(const std::vector< INPUT1 > &values1, const std::vector< INPUT2 > &values2, const RESULT &expected, UdaExecutionMode mode=ALL)
Runs the UDA in all the modes, validating the result is 'expected' each time.
virtual void Update(int idx, FunctionContext *context, INTERMEDIATE *dst)
int fixed_buffer_byte_size_
Buffer len for intermediate results if the type is TYPE_FIXED_BUFFER.
const std::vector< INPUT2 > * input2_
const std::vector< INPUT2 > * input2_
const std::vector< INPUT1 > * input1_
UdaTestHarness(typename BaseClass::InitFn init_fn, UpdateFn update_fn, typename BaseClass::MergeFn merge_fn, typename BaseClass::SerializeFn serialize_fn, typename BaseClass::FinalizeFn finalize_fn)
const std::vector< INPUT3 > * input3_
virtual void Update(int idx, FunctionContext *context, INTERMEDIATE *dst)=0
UdaTestHarness2(typename BaseClass::InitFn init_fn, UpdateFn update_fn, typename BaseClass::MergeFn merge_fn, typename BaseClass::SerializeFn serialize_fn, typename BaseClass::FinalizeFn finalize_fn)
void(* UpdateFn)(FunctionContext *context, const INPUT &input, INTERMEDIATE *result)
RESULT ExecuteOneLevel(int num_nodes, ScopedFunctionContext *result_context)
UdaTestHarness4(typename BaseClass::InitFn init_fn, UpdateFn update_fn, typename BaseClass::MergeFn merge_fn, typename BaseClass::SerializeFn serialize_fn, typename BaseClass::FinalizeFn finalize_fn)
const std::vector< INPUT2 > * input2_
const std::vector< INPUT1 > * input1_
bool Execute(const std::vector< INPUT1 > &values1, const std::vector< INPUT2 > &values2, const std::vector< INPUT3 > &values3, const RESULT &expected, UdaExecutionMode mode=ALL)
Runs the UDA in all the modes, validating the result is 'expected' each time.
virtual void Update(int idx, FunctionContext *context, INTERMEDIATE *dst)
int num_input_values_
Set during Execute() by subclass.
bool CheckResult(const RESULT &x, const RESULT &y)
Verifies x == y, using the custom comparator if set.
bool CheckContext(FunctionContext *context)
Returns false if there is an error set in the context.
RESULT(* FinalizeFn)(FunctionContext *context, const INTERMEDIATE &value)
virtual void Update(int idx, FunctionContext *context, INTERMEDIATE *dst)
UdaTestHarnessBase< RESULT, INTERMEDIATE > BaseClass
const std::vector< INPUT3 > * input3_
RESULT ExecuteTwoLevel(int num1, int num2, ScopedFunctionContext *result_context)
bool Execute(const RESULT &expected, UdaExecutionMode mode)
Runs the UDA in all the modes, validating the result is 'expected' each time.
bool Execute(const std::vector< INPUT > &values, const RESULT &expected, UdaExecutionMode mode=ALL)
Runs the UDA in all the modes, validating the result is 'expected' each time.
UdaTestHarnessBase< RESULT, INTERMEDIATE > BaseClass
ResultComparator result_comparator_fn_
Customer comparator, NULL if default == should be used.
ScopedFunctionContext(FunctionContext *context, UdaTestHarnessBase *harness)
std::string error_msg_
Error message if anything went wrong during the execution.
InitFn init_fn_
UDA functions.
bool Execute(const std::vector< T > &values, const RESULT &expected, UdaExecutionMode mode=ALL)
UdaTestHarness3(typename BaseClass::InitFn init_fn, UpdateFn update_fn, typename BaseClass::MergeFn merge_fn, typename BaseClass::SerializeFn serialize_fn, typename BaseClass::FinalizeFn finalize_fn)
const std::vector< INPUT4 > * input4_
void(* MergeFn)(FunctionContext *context, const INTERMEDIATE &src, INTERMEDIATE *dst)
UdaTestHarnessBase(InitFn init_fn, MergeFn merge_fn, SerializeFn serialize_fn, FinalizeFn finalize_fn)
const std::string & GetErrorMsg() const
Returns the failure string if any.
virtual void Update(int idx, FunctionContext *context, INTERMEDIATE *dst)
UdaTestHarnessBase< RESULT, INTERMEDIATE > BaseClass
RESULT ExecuteSingleNode(ScopedFunctionContext *result_context)
const std::vector< INPUT1 > * input1_
bool(* ResultComparator)(const RESULT &x, const RESULT &y)
void(* UpdateFn)(FunctionContext *context, const INPUT1 &input1, const INPUT2 &input2, const INPUT3 &input3, const INPUT4 &input4, INTERMEDIATE *result)
const INTERMEDIATE(* SerializeFn)(FunctionContext *context, const INTERMEDIATE &type)
void(* UpdateFn)(FunctionContext *context, const INPUT1 &input1, const INPUT2 &input2, const INPUT3 &input3, INTERMEDIATE *result)
void(* InitFn)(FunctionContext *context, INTERMEDIATE *result)
static void CloseContext(FunctionContext *context)
std::vector< const INPUT * > input_
Set during Execute()