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-catrank.c++ (4898B)


      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 struct SearchResult {
     29   const char* url;
     30   double score;
     31   const char* snippet;
     32 };
     33 
     34 struct ScoredResult {
     35   double score;
     36   const SearchResult* result;
     37 
     38   ScoredResult() = default;
     39   ScoredResult(double score, const SearchResult* result): score(score), result(result) {}
     40 
     41   inline bool operator<(const ScoredResult& other) const { return score > other.score; }
     42 };
     43 
     44 class CatRankTestCase {
     45 public:
     46   typedef List<SearchResult> Request;
     47   typedef List<SearchResult> Response;
     48   typedef int Expectation;
     49 
     50   static int setupRequest(List<SearchResult>* request) {
     51     int count = fastRand(1000);
     52     int goodCount = 0;
     53 
     54     request->init(count);
     55     for (int i = 0; i < count; i++) {
     56       SearchResult& result = request->items[i];
     57       result.score = 1000 - i;
     58       char* pos = reinterpret_cast<char*>(arenaPos);
     59       result.url = pos;
     60 
     61       strcpy(pos, "http://example.com/");
     62       pos += strlen("http://example.com/");
     63       int urlSize = fastRand(100);
     64       for (int j = 0; j < urlSize; j++) {
     65         *pos++ = 'a' + fastRand(26);
     66       }
     67       *pos++ = '\0';
     68 
     69       // Retroactively allocate the space we used.
     70       if (allocate<char>(pos - result.url) != result.url) {
     71         throw std::bad_alloc();
     72       }
     73 
     74       bool isCat = fastRand(8) == 0;
     75       bool isDog = fastRand(8) == 0;
     76       goodCount += isCat && !isDog;
     77 
     78       pos = reinterpret_cast<char*>(arenaPos);
     79       result.snippet = pos;
     80 
     81       *pos++ = ' ';
     82 
     83       int prefix = fastRand(20);
     84       for (int j = 0; j < prefix; j++) {
     85         const char* word = WORDS[fastRand(WORDS_COUNT)];
     86         size_t len = strlen(word);
     87         memcpy(pos, word, len);
     88         pos += len;
     89       }
     90 
     91       if (isCat) {
     92         strcpy(pos, "cat ");
     93         pos += 4;
     94       }
     95       if (isDog) {
     96         strcpy(pos, "dog ");
     97         pos += 4;
     98       }
     99 
    100       int suffix = fastRand(20);
    101       for (int j = 0; j < suffix; j++) {
    102         const char* word = WORDS[fastRand(WORDS_COUNT)];
    103         size_t len = strlen(word);
    104         memcpy(pos, word, len);
    105         pos += len;
    106       }
    107       *pos++ = '\0';
    108 
    109       // Retroactively allocate the space we used.
    110       if (allocate<char>(pos - result.snippet) != result.snippet) {
    111         throw std::bad_alloc();
    112       }
    113     }
    114 
    115     return goodCount;
    116   }
    117 
    118   static void handleRequest(const List<SearchResult>& request, List<SearchResult>* response) {
    119     std::vector<ScoredResult> scoredResults;
    120     scoredResults.reserve(request.size);
    121 
    122     for (auto& result: request) {
    123       double score = result.score;
    124       if (strstr(result.snippet, " cat ") != nullptr) {
    125         score *= 10000;
    126       }
    127       if (strstr(result.snippet, " dog ") != nullptr) {
    128         score /= 10000;
    129       }
    130       scoredResults.emplace_back(score, &result);
    131     }
    132 
    133     std::sort(scoredResults.begin(), scoredResults.end());
    134 
    135     response->init(scoredResults.size());
    136     SearchResult* dst = response->items;
    137     for (auto& result: scoredResults) {
    138       dst->url = copyString(result.result->url);
    139       dst->score = result.score;
    140       dst->snippet = copyString(result.result->snippet);
    141       ++dst;
    142     }
    143   }
    144 
    145   static bool checkResponse(const List<SearchResult>& response, int expectedGoodCount) {
    146     int goodCount = 0;
    147     for (auto& result: response) {
    148       if (result.score > 1001) {
    149         ++goodCount;
    150       } else {
    151         break;
    152       }
    153     }
    154 
    155     return goodCount == expectedGoodCount;
    156   }
    157 };
    158 
    159 }  // namespace null
    160 }  // namespace benchmark
    161 }  // namespace capnp
    162 
    163 int main(int argc, char* argv[]) {
    164   return capnp::benchmark::benchmarkMain<
    165       capnp::benchmark::null::BenchmarkTypes,
    166       capnp::benchmark::null::CatRankTestCase>(argc, argv);
    167 }