capnproto-eval.c++ (3924B)
1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors 2 // Licensed under the MIT License: 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a copy 5 // of this software and associated documentation files (the "Software"), to deal 6 // in the Software without restriction, including without limitation the rights 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 // copies of the Software, and to permit persons to whom the Software is 9 // furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 // THE SOFTWARE. 21 22 #include "eval.capnp.h" 23 #include "capnproto-common.h" 24 25 namespace capnp { 26 namespace benchmark { 27 namespace capnp { 28 29 int32_t makeExpression(Expression::Builder exp, uint depth) { 30 exp.setOp((Operation)(fastRand((int)Operation::MODULUS + 1))); 31 32 uint32_t left, right; 33 34 if (fastRand(8) < depth) { 35 left = fastRand(128) + 1; 36 exp.getLeft().setValue(left); 37 } else { 38 left = makeExpression(exp.getLeft().initExpression(), depth + 1); 39 } 40 41 if (fastRand(8) < depth) { 42 right = fastRand(128) + 1; 43 exp.getRight().setValue(right); 44 } else { 45 right = makeExpression(exp.getRight().initExpression(), depth + 1); 46 } 47 48 switch (exp.getOp()) { 49 case Operation::ADD: 50 return left + right; 51 case Operation::SUBTRACT: 52 return left - right; 53 case Operation::MULTIPLY: 54 return left * right; 55 case Operation::DIVIDE: 56 return div(left, right); 57 case Operation::MODULUS: 58 return mod(left, right); 59 } 60 throw std::logic_error("Can't get here."); 61 } 62 63 int32_t evaluateExpression(Expression::Reader exp) { 64 int32_t left = 0, right = 0; 65 66 switch (exp.getLeft().which()) { 67 case Expression::Left::VALUE: 68 left = exp.getLeft().getValue(); 69 break; 70 case Expression::Left::EXPRESSION: 71 left = evaluateExpression(exp.getLeft().getExpression()); 72 break; 73 } 74 75 switch (exp.getRight().which()) { 76 case Expression::Right::VALUE: 77 right = exp.getRight().getValue(); 78 break; 79 case Expression::Right::EXPRESSION: 80 right = evaluateExpression(exp.getRight().getExpression()); 81 break; 82 } 83 84 switch (exp.getOp()) { 85 case Operation::ADD: 86 return left + right; 87 case Operation::SUBTRACT: 88 return left - right; 89 case Operation::MULTIPLY: 90 return left * right; 91 case Operation::DIVIDE: 92 return div(left, right); 93 case Operation::MODULUS: 94 return mod(left, right); 95 } 96 throw std::logic_error("Can't get here."); 97 } 98 99 class ExpressionTestCase { 100 public: 101 typedef Expression Request; 102 typedef EvaluationResult Response; 103 typedef int32_t Expectation; 104 105 static inline int32_t setupRequest(Expression::Builder request) { 106 return makeExpression(request, 0); 107 } 108 static inline void handleRequest(Expression::Reader request, EvaluationResult::Builder response) { 109 response.setValue(evaluateExpression(request)); 110 } 111 static inline bool checkResponse(EvaluationResult::Reader response, int32_t expected) { 112 return response.getValue() == expected; 113 } 114 }; 115 116 } // namespace capnp 117 } // namespace benchmark 118 } // namespace capnp 119 120 int main(int argc, char* argv[]) { 121 return capnp::benchmark::benchmarkMain< 122 capnp::benchmark::capnp::BenchmarkTypes, 123 capnp::benchmark::capnp::ExpressionTestCase>(argc, argv); 124 }