mirror of
https://github.com/capnproto/pycapnp.git
synced 2025-03-04 08:24:43 +01:00
112 lines
2.6 KiB
Python
112 lines
2.6 KiB
Python
![]() |
#!/usr/bin/env python
|
||
|
|
||
|
from common import rand_int, rand_double, rand_bool, from_bytes_helper
|
||
|
from random import choice
|
||
|
import eval_pb2
|
||
|
|
||
|
MAX_INT = 2**31 - 1
|
||
|
MIN_INT = -(2**31)
|
||
|
|
||
|
OPERATIONS = [
|
||
|
"add",
|
||
|
"subtract",
|
||
|
"multiply",
|
||
|
"divide",
|
||
|
"modulus"]
|
||
|
|
||
|
def clamp(res):
|
||
|
if res > MAX_INT:
|
||
|
return MAX_INT
|
||
|
elif res < MIN_INT:
|
||
|
return MIN_INT
|
||
|
else:
|
||
|
return res
|
||
|
|
||
|
def div(a, b):
|
||
|
if b == 0:
|
||
|
return MAX_INT
|
||
|
if a == MIN_INT and b == -1:
|
||
|
return MAX_INT
|
||
|
|
||
|
return a / b
|
||
|
|
||
|
def mod(a, b):
|
||
|
if b == 0:
|
||
|
return MAX_INT
|
||
|
if a == MIN_INT and b == -1:
|
||
|
return MAX_INT
|
||
|
|
||
|
return a % b
|
||
|
|
||
|
def make_expression(exp, depth):
|
||
|
exp.op = rand_int(len(OPERATIONS))
|
||
|
|
||
|
if rand_int(8) < depth:
|
||
|
left = rand_int(128) + 1
|
||
|
exp.left_value = left
|
||
|
else:
|
||
|
left = make_expression(exp.left_expression, depth+1)
|
||
|
|
||
|
if rand_int(8) < depth:
|
||
|
right = rand_int(128) + 1
|
||
|
exp.right_value = right
|
||
|
else:
|
||
|
right = make_expression(exp.right_expression, depth+1)
|
||
|
|
||
|
op = exp.op
|
||
|
if op == 0:
|
||
|
return clamp(left + right)
|
||
|
elif op == 1:
|
||
|
return clamp(left - right)
|
||
|
elif op == 2:
|
||
|
return clamp(left * right)
|
||
|
elif op == 3:
|
||
|
return div(left, right)
|
||
|
elif op == 4:
|
||
|
return mod(left, right)
|
||
|
raise RuntimeError("op wasn't a valid value: " + str(op))
|
||
|
|
||
|
def evaluate_expression(exp):
|
||
|
left = 0
|
||
|
right = 0
|
||
|
|
||
|
if exp.HasField('left_value'):
|
||
|
left = exp.left_value
|
||
|
else:
|
||
|
left = evaluate_expression(exp.left_expression)
|
||
|
|
||
|
if exp.HasField('right_value'):
|
||
|
right = exp.right_value
|
||
|
else:
|
||
|
right = evaluate_expression(exp.right_expression)
|
||
|
|
||
|
|
||
|
op = exp.op
|
||
|
if op == 0:
|
||
|
return clamp(left + right)
|
||
|
elif op == 1:
|
||
|
return clamp(left - right)
|
||
|
elif op == 2:
|
||
|
return clamp(left * right)
|
||
|
elif op == 3:
|
||
|
return div(left, right)
|
||
|
elif op == 4:
|
||
|
return mod(left, right)
|
||
|
raise RuntimeError("op wasn't a valid value: " + str(op))
|
||
|
|
||
|
class Benchmark:
|
||
|
def __init__(self, compression):
|
||
|
self.Request = eval_pb2.Expression
|
||
|
self.Response = eval_pb2.EvaluationResult
|
||
|
self.from_bytes_request = from_bytes_helper(eval_pb2.Expression)
|
||
|
self.from_bytes_response = from_bytes_helper(eval_pb2.EvaluationResult)
|
||
|
self.to_bytes = lambda x: x.SerializeToString()
|
||
|
|
||
|
def setup(self, request):
|
||
|
return make_expression(request, 0)
|
||
|
|
||
|
def handle(self, request, response):
|
||
|
response.value = evaluate_expression(request)
|
||
|
|
||
|
def check(self, response, expected):
|
||
|
return response.value == expected
|