capnproto-catrank.c++ (4456B)
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 "catrank.capnp.h" 23 #include "capnproto-common.h" 24 25 namespace capnp { 26 namespace benchmark { 27 namespace capnp { 28 29 struct ScoredResult { 30 double score; 31 SearchResult::Reader result; 32 33 ScoredResult() = default; 34 ScoredResult(double score, SearchResult::Reader result): score(score), result(result) {} 35 36 inline bool operator<(const ScoredResult& other) const { return score > other.score; } 37 }; 38 39 class CatRankTestCase { 40 public: 41 typedef SearchResultList Request; 42 typedef SearchResultList Response; 43 typedef int Expectation; 44 45 static int setupRequest(SearchResultList::Builder request) { 46 int count = fastRand(1000); 47 int goodCount = 0; 48 49 auto list = request.initResults(count); 50 51 for (int i = 0; i < count; i++) { 52 SearchResult::Builder result = list[i]; 53 result.setScore(1000 - i); 54 int urlSize = fastRand(100); 55 56 static const char URL_PREFIX[] = "http://example.com/"; 57 size_t urlPrefixLength = strlen(URL_PREFIX); 58 auto url = result.initUrl(urlSize + urlPrefixLength); 59 60 strcpy(url.begin(), URL_PREFIX); 61 char* pos = url.begin() + urlPrefixLength; 62 for (int j = 0; j < urlSize; j++) { 63 *pos++ = 'a' + fastRand(26); 64 } 65 66 bool isCat = fastRand(8) == 0; 67 bool isDog = fastRand(8) == 0; 68 goodCount += isCat && !isDog; 69 70 static std::string snippet; 71 snippet.clear(); 72 snippet.push_back(' '); 73 74 int prefix = fastRand(20); 75 for (int j = 0; j < prefix; j++) { 76 snippet.append(WORDS[fastRand(WORDS_COUNT)]); 77 } 78 79 if (isCat) snippet.append("cat "); 80 if (isDog) snippet.append("dog "); 81 82 int suffix = fastRand(20); 83 for (int j = 0; j < suffix; j++) { 84 snippet.append(WORDS[fastRand(WORDS_COUNT)]); 85 } 86 87 result.setSnippet(Text::Reader(snippet.c_str(), snippet.size())); 88 } 89 90 return goodCount; 91 } 92 93 static void handleRequest(SearchResultList::Reader request, SearchResultList::Builder response) { 94 std::vector<ScoredResult> scoredResults; 95 96 for (auto result: request.getResults()) { 97 double score = result.getScore(); 98 if (strstr(result.getSnippet().cStr(), " cat ") != nullptr) { 99 score *= 10000; 100 } 101 if (strstr(result.getSnippet().cStr(), " dog ") != nullptr) { 102 score /= 10000; 103 } 104 scoredResults.emplace_back(score, result); 105 } 106 107 std::sort(scoredResults.begin(), scoredResults.end()); 108 109 auto list = response.initResults(scoredResults.size()); 110 auto iter = list.begin(); 111 for (auto result: scoredResults) { 112 iter->setScore(result.score); 113 iter->setUrl(result.result.getUrl()); 114 iter->setSnippet(result.result.getSnippet()); 115 ++iter; 116 } 117 } 118 119 static bool checkResponse(SearchResultList::Reader response, int expectedGoodCount) { 120 int goodCount = 0; 121 for (auto result: response.getResults()) { 122 if (result.getScore() > 1001) { 123 ++goodCount; 124 } else { 125 break; 126 } 127 } 128 129 return goodCount == expectedGoodCount; 130 } 131 }; 132 133 } // namespace capnp 134 } // namespace benchmark 135 } // namespace capnp 136 137 int main(int argc, char* argv[]) { 138 return capnp::benchmark::benchmarkMain< 139 capnp::benchmark::capnp::BenchmarkTypes, 140 capnp::benchmark::capnp::CatRankTestCase>(argc, argv); 141 }