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 module capnproto.benchmark.CatRank; 23 24 import capnproto.StructList; 25 import capnproto.Text; 26 27 import capnproto.benchmark.catrankschema; 28 import capnproto.benchmark.Common; 29 import capnproto.benchmark.TestCase; 30 31 void main(string[] args) 32 { 33 auto testCase = new CatRank(); 34 testCase.execute(args); 35 } 36 37 final class CatRank : TestCase!(SearchResultList, SearchResultList, int) 38 { 39 public: //Types. 40 struct ScoredResult 41 { 42 public: 43 double score; 44 SearchResult.Reader result; 45 } 46 47 public: //Methods. 48 override int setupRequest(SearchResultList.Builder request) 49 { 50 import std.array : appender; 51 52 int count = fastRand(1000); 53 int goodCount = 0; 54 55 auto list = request.initResults(count); 56 foreach(i; 0..count) 57 { 58 auto result = list[i]; 59 result.setScore(1000 - i); 60 int urlSize = fastRand(100); 61 62 static Text.Reader URL_PREFIX = "http://example.com"; 63 auto urlPrefixLength = URL_PREFIX.length; 64 auto url = result.initUrl(cast(int)(urlSize + urlPrefixLength)); 65 auto bytes = url.asByteBuffer(); 66 auto bb = URL_PREFIX.asByteBuffer(); 67 bytes.put(bb); 68 69 foreach(j; 0..urlSize) 70 bytes.put(cast(byte)(97 + fastRand(26))); 71 72 bool isCat = fastRand(8) == 0; 73 bool isDog = fastRand(8) == 0; 74 goodCount += isCat && !isDog; 75 76 static snippet = appender!(char[]); 77 snippet.clear(); 78 snippet ~= " "; 79 80 int prefix = fastRand(20); 81 foreach(j; 0..prefix) 82 snippet ~= WORDS[fastRand(cast(uint)WORDS.length)]; 83 if(isCat) 84 snippet ~= "cat "; 85 if(isDog) 86 snippet ~= "dog "; 87 88 int suffix = fastRand(20); 89 foreach(j; 0..suffix) 90 snippet ~= WORDS[fastRand(cast(uint)WORDS.length)]; 91 92 result.setSnippet(cast(string)snippet.data()); 93 } 94 95 return goodCount; 96 } 97 98 override void handleRequest(SearchResultList.Reader request, SearchResultList.Builder response) 99 { 100 import std.algorithm : sort; 101 import std.array : appender; 102 import std.string : indexOf; 103 104 static scoredResults = appender!(ScoredResult[]); 105 scoredResults.clear(); 106 107 foreach(result; request.getResults()) 108 { 109 double score = result.getScore(); 110 auto snippet = result.getSnippet(); 111 if(snippet.indexOf(" cat ") != -1) 112 score *= 10000; 113 if(snippet.indexOf(" dog ") != -1) 114 score /= 10000; 115 scoredResults ~= ScoredResult(score, result); 116 } 117 118 scoredResults.data().sort!((a,b) => a.score > b.score); 119 120 auto list = response.initResults(cast(int)scoredResults.data().length); 121 foreach(i,result; scoredResults.data()) 122 { 123 auto item = list.get(i); 124 item.setScore(result.score); 125 item.setUrl(result.result.getUrl()); 126 item.setSnippet(result.result.getSnippet()); 127 } 128 } 129 130 override bool checkResponse(SearchResultList.Reader response, int expectedGoodCount) 131 { 132 int goodCount = 0; 133 foreach(result; response.getResults()) 134 { 135 if(result.getScore() > 1001) 136 ++goodCount; 137 else 138 break; 139 } 140 return goodCount == expectedGoodCount; 141 } 142 }