capnproto

FORK: Cap'n Proto serialization/RPC system - core tools and C++ library
git clone https://git.neptards.moe/neptards/capnproto.git
Log | Files | Refs | README | LICENSE

null-eval.c++ (4371B)


      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 "null-common.h"
     23 
     24 namespace capnp {
     25 namespace benchmark {
     26 namespace null {
     27 
     28 enum class Operation {
     29   ADD,
     30   SUBTRACT,
     31   MULTIPLY,
     32   DIVIDE,
     33   MODULUS
     34 };
     35 uint OPERATION_RANGE = static_cast<uint>(Operation::MODULUS) + 1;
     36 
     37 struct Expression {
     38   Operation op;
     39 
     40   bool leftIsValue;
     41   bool rightIsValue;
     42 
     43   union {
     44     int32_t leftValue;
     45     Expression* leftExpression;
     46   };
     47 
     48   union {
     49     int32_t rightValue;
     50     Expression* rightExpression;
     51   };
     52 };
     53 
     54 int32_t makeExpression(Expression* exp, uint depth) {
     55   exp->op = (Operation)(fastRand(OPERATION_RANGE));
     56 
     57   int32_t left, right;
     58 
     59   if (fastRand(8) < depth) {
     60     exp->leftIsValue = true;
     61     left = fastRand(128) + 1;
     62     exp->leftValue = left;
     63   } else {
     64     exp->leftIsValue = false;
     65     exp->leftExpression = allocate<Expression>();
     66     left = makeExpression(exp->leftExpression, depth + 1);
     67   }
     68 
     69   if (fastRand(8) < depth) {
     70     exp->rightIsValue = true;
     71     right = fastRand(128) + 1;
     72     exp->rightValue = right;
     73   } else {
     74     exp->rightIsValue = false;
     75     exp->rightExpression = allocate<Expression>();
     76     right = makeExpression(exp->rightExpression, depth + 1);
     77   }
     78 
     79   switch (exp->op) {
     80     case Operation::ADD:
     81       return left + right;
     82     case Operation::SUBTRACT:
     83       return left - right;
     84     case Operation::MULTIPLY:
     85       return left * right;
     86     case Operation::DIVIDE:
     87       return div(left, right);
     88     case Operation::MODULUS:
     89       return mod(left, right);
     90   }
     91   throw std::logic_error("Can't get here.");
     92 }
     93 
     94 int32_t evaluateExpression(const Expression& exp) {
     95   uint32_t left, right;
     96 
     97   if (exp.leftIsValue) {
     98     left = exp.leftValue;
     99   } else {
    100     left = evaluateExpression(*exp.leftExpression);
    101   }
    102 
    103   if (exp.rightIsValue) {
    104     right = exp.rightValue;
    105   } else {
    106     right = evaluateExpression(*exp.rightExpression);
    107   }
    108 
    109   switch (exp.op) {
    110     case Operation::ADD:
    111       return left + right;
    112     case Operation::SUBTRACT:
    113       return left - right;
    114     case Operation::MULTIPLY:
    115       return left * right;
    116     case Operation::DIVIDE:
    117       return div(left, right);
    118     case Operation::MODULUS:
    119       return mod(left, right);
    120   }
    121   throw std::logic_error("Can't get here.");
    122 }
    123 
    124 class ExpressionTestCase {
    125 public:
    126   typedef Expression Request;
    127   typedef int32_t Response;
    128   typedef int32_t Expectation;
    129 
    130   static inline int32_t setupRequest(Expression* request) {
    131     return makeExpression(request, 0);
    132   }
    133   static inline void handleRequest(const Expression& request, int32_t* response) {
    134     *response = evaluateExpression(request);
    135   }
    136   static inline bool checkResponse(int32_t response, int32_t expected) {
    137     return response == expected;
    138   }
    139 
    140   static size_t spaceUsed(const Expression& expression) {
    141     return sizeof(Expression) +
    142         (expression.leftExpression == nullptr ? 0 : spaceUsed(*expression.leftExpression)) +
    143         (expression.rightExpression == nullptr ? 0 : spaceUsed(*expression.rightExpression));
    144   }
    145 };
    146 
    147 }  // namespace null
    148 }  // namespace benchmark
    149 }  // namespace capnp
    150 
    151 int main(int argc, char* argv[]) {
    152   return capnp::benchmark::benchmarkMain<
    153       capnp::benchmark::null::BenchmarkTypes,
    154       capnp::benchmark::null::ExpressionTestCase>(argc, argv);
    155 }