capnproto-carsales.c++ (4603B)
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 "carsales.capnp.h" 23 #include "capnproto-common.h" 24 25 namespace capnp { 26 namespace benchmark { 27 namespace capnp { 28 29 template <typename ReaderOrBuilder> 30 uint64_t carValue(ReaderOrBuilder car) { 31 // Do not think too hard about realism. 32 33 uint64_t result = 0; 34 35 result += car.getSeats() * 200; 36 result += car.getDoors() * 350; 37 for (auto wheel: car.getWheels()) { 38 result += wheel.getDiameter() * wheel.getDiameter(); 39 result += wheel.getSnowTires() ? 100 : 0; 40 } 41 42 result += car.getLength() * car.getWidth() * car.getHeight() / 50; 43 44 auto engine = car.getEngine(); 45 result += engine.getHorsepower() * 40; 46 if (engine.getUsesElectric()) { 47 if (engine.getUsesGas()) { 48 // hybrid 49 result += 5000; 50 } else { 51 result += 3000; 52 } 53 } 54 55 result += car.getHasPowerWindows() ? 100 : 0; 56 result += car.getHasPowerSteering() ? 200 : 0; 57 result += car.getHasCruiseControl() ? 400 : 0; 58 result += car.getHasNavSystem() ? 2000 : 0; 59 60 result += car.getCupHolders() * 25; 61 62 return result; 63 } 64 65 void randomCar(Car::Builder car) { 66 // Do not think too hard about realism. 67 68 static const char* const MAKES[] = { "Toyota", "GM", "Ford", "Honda", "Tesla" }; 69 static const char* const MODELS[] = { "Camry", "Prius", "Volt", "Accord", "Leaf", "Model S" }; 70 71 car.setMake(MAKES[fastRand(sizeof(MAKES) / sizeof(MAKES[0]))]); 72 car.setModel(MODELS[fastRand(sizeof(MODELS) / sizeof(MODELS[0]))]); 73 74 car.setColor((Color)fastRand((uint)Color::SILVER + 1)); 75 car.setSeats(2 + fastRand(6)); 76 car.setDoors(2 + fastRand(3)); 77 78 for (auto wheel: car.initWheels(4)) { 79 wheel.setDiameter(25 + fastRand(15)); 80 wheel.setAirPressure(30 + fastRandDouble(20)); 81 wheel.setSnowTires(fastRand(16) == 0); 82 } 83 84 car.setLength(170 + fastRand(150)); 85 car.setWidth(48 + fastRand(36)); 86 car.setHeight(54 + fastRand(48)); 87 car.setWeight(car.getLength() * car.getWidth() * car.getHeight() / 200); 88 89 auto engine = car.initEngine(); 90 engine.setHorsepower(100 * fastRand(400)); 91 engine.setCylinders(4 + 2 * fastRand(3)); 92 engine.setCc(800 + fastRand(10000)); 93 engine.setUsesGas(true); 94 engine.setUsesElectric(fastRand(2)); 95 96 car.setFuelCapacity(10.0 + fastRandDouble(30.0)); 97 car.setFuelLevel(fastRandDouble(car.getFuelCapacity())); 98 car.setHasPowerWindows(fastRand(2)); 99 car.setHasPowerSteering(fastRand(2)); 100 car.setHasCruiseControl(fastRand(2)); 101 car.setCupHolders(fastRand(12)); 102 car.setHasNavSystem(fastRand(2)); 103 } 104 105 class CarSalesTestCase { 106 public: 107 typedef ParkingLot Request; 108 typedef TotalValue Response; 109 typedef uint64_t Expectation; 110 111 static uint64_t setupRequest(ParkingLot::Builder request) { 112 uint64_t result = 0; 113 for (auto car: request.initCars(fastRand(200))) { 114 randomCar(car); 115 result += carValue(car); 116 } 117 return result; 118 } 119 static void handleRequest(ParkingLot::Reader request, TotalValue::Builder response) { 120 uint64_t result = 0; 121 for (auto car: request.getCars()) { 122 result += carValue(car); 123 } 124 response.setAmount(result); 125 } 126 static inline bool checkResponse(TotalValue::Reader response, uint64_t expected) { 127 return response.getAmount() == expected; 128 } 129 }; 130 131 } // namespace capnp 132 } // namespace benchmark 133 } // namespace capnp 134 135 int main(int argc, char* argv[]) { 136 return capnp::benchmark::benchmarkMain< 137 capnp::benchmark::capnp::BenchmarkTypes, 138 capnp::benchmark::capnp::CarSalesTestCase>(argc, argv); 139 }