diff options
Diffstat (limited to 'bench/workgen/workgen.swig')
-rw-r--r-- | bench/workgen/workgen.swig | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/bench/workgen/workgen.swig b/bench/workgen/workgen.swig new file mode 100644 index 00000000000..0f74942169c --- /dev/null +++ b/bench/workgen/workgen.swig @@ -0,0 +1,233 @@ +/*- + * Public Domain 2014-2017 MongoDB, Inc. + * Public Domain 2008-2014 WiredTiger, Inc. + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * workgen.swig + * The SWIG interface file defining the workgen python API. + */ + +%include "typemaps.i" +%include "std_vector.i" +%include "std_string.i" +%include "stdint.i" +%include "attribute.i" +%include "carrays.i" + +/* We only need to reference WiredTiger types. */ +%import "wiredtiger.h" + +%{ +#include <ostream> +#include <sstream> +#include <signal.h> +#include "wiredtiger.h" +#include "workgen.h" +#include "workgen_int.h" +%} + +%pythoncode %{ +import numbers +%} + +%exception { + try { + $action + } + catch (workgen::WorkgenException &wge) { + SWIG_exception_fail(SWIG_RuntimeError, wge._str.c_str()); + } +} + +/* + * Some functions are long running, turn off signal handling that was enabled + * by the Python interpreter. This means that a signal handler coded in Python + * won't work when spanning a call to one of these long running functions, but + * it's doubtful our test scripts need signals at all. This could be made to + * work, it's just not worth the trouble. + */ +%define InterruptableFunction(funcname) +%exception funcname { + try { + void (*savesig)(int) = signal(SIGINT, SIG_DFL); + $action + (void)signal(SIGINT, savesig); + } + catch (workgen::WorkgenException &wge) { + SWIG_exception_fail(SWIG_RuntimeError, wge._str.c_str()); + } +} +%enddef + +/* + * Define a __str__ function for all public workgen classes. + */ +%define WorkgenClass(classname) +%extend workgen::classname { + const std::string __str__() { + std::ostringstream out; + $self->describe(out); + return out.str(); + } +}; +%enddef + +/* + * To forestall errors, make it impossible to add new attributes to certain + * classes. This trick relies on the implementation of SWIG providing + * predictably named functions in the _workgen namespace to set attributes. + */ +%define WorkgenFrozenClass(classname) +%extend workgen::classname { +%pythoncode %{ + def __setattr__(self, attr, val): + if getattr(self, attr) == None: + raise AttributeError("'" + #classname + + "' object has no attribute '" + attr + "'") + f = _workgen.__dict__[#classname + '_' + attr + '_set'] + f(self, val) +%} +}; +%enddef + +InterruptableFunction(workgen::execute) +InterruptableFunction(workgen::Workload::run) + +%module workgen +/* Parse the header to generate wrappers. */ +%include "workgen.h" + +%template(OpList) std::vector<workgen::Operation>; +%template(ThreadList) std::vector<workgen::Thread>; +%array_class(uint32_t, uint32Array); +%array_class(long, longArray); + +WorkgenClass(Key) +WorkgenClass(Operation) +WorkgenClass(Stats) +WorkgenClass(Table) +WorkgenClass(TableOptions) +WorkgenClass(Thread) +WorkgenClass(ThreadOptions) +WorkgenClass(Transaction) +WorkgenClass(Value) +WorkgenClass(Workload) +WorkgenClass(WorkloadOptions) +WorkgenClass(Context) + +WorkgenFrozenClass(TableOptions) +WorkgenFrozenClass(ThreadOptions) +WorkgenFrozenClass(WorkloadOptions) + +%extend workgen::Operation { +%pythoncode %{ + def __mul__(self, other): + if not isinstance(other, numbers.Integral): + raise Exception('Operation.__mul__ requires an integral number') + op = Operation() + op._group = OpList([self]) + op._repeatgroup = other + return op + + __rmul__ = __mul__ + + def __add__(self, other): + if not isinstance(other, Operation): + raise Exception('Operation.__sum__ requires an Operation') + if self._group == None or self._repeatgroup != 1 or self._transaction != None: + op = Operation() + op._group = OpList([self, other]) + op._repeatgroup = 1 + return op + else: + self._group.append(other) + return self +%} +}; + +%extend workgen::Thread { +%pythoncode %{ + def __mul__(self, other): + if not isinstance(other, numbers.Integral): + raise Exception('Thread.__mul__ requires an integral number') + return ThreadListWrapper(ThreadList([self] * other)) + + __rmul__ = __mul__ + + def __add__(self, other): + if type(self) != type(other): + raise Exception('Thread.__sum__ requires an Thread') + return ThreadListWrapper(ThreadList([self, other])) +%} +}; + +%extend workgen::ThreadListWrapper { +%pythoncode %{ + def __mul__(self, other): + if not isinstance(other, numbers.Integral): + raise Exception('ThreadList.__mul__ requires an integral number') + tlw = ThreadListWrapper(self) + tlw.multiply(other) + return tlw + + __rmul__ = __mul__ + + def __add__(self, other): + tlw = ThreadListWrapper(self) + if isinstance(other, ThreadListWrapper): + tlw.extend(other) + elif isinstance(other, Thread): + tlw.append(other) + else: + raise Exception('ThreadList.__sum__ requires an Thread or ThreadList') + return tlw +%} +}; + +%extend workgen::Track { +%pythoncode %{ + def __longarray(self, size): + result = longArray(size) + result.__len__ = lambda: size + return result + + def us(self): + result = self.__longarray(1000) + self._get_us(result) + return result + + def ms(self): + result = self.__longarray(1000) + self._get_ms(result) + return result + + def sec(self): + result = self.__longarray(100) + self._get_sec(result) + return result +%} +}; |