blob: 71c9e10dbe19909bc8498c653675cf7de0d48926 [file] [log] [blame]
Junxiao Shi85d17fc2015-01-21 22:18:17 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2015, Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26#include "table/cs.hpp"
27#include <ndn-cxx/security/key-chain.hpp>
28
29#include "tests/test-common.hpp"
30
31namespace nfd {
32namespace tests {
33
34class CsBenchmarkFixture : public BaseFixture
35{
36protected:
37 CsBenchmarkFixture()
38 {
39#ifdef _DEBUG
40 BOOST_TEST_MESSAGE("Benchmark compiled in debug mode is unreliable, "
41 "please compile in release mode.");
42#endif // _DEBUG
43
44 cs.setLimit(CS_CAPACITY);
45 }
46
47 time::microseconds
48 timedRun(std::function<void()> f)
49 {
50 time::steady_clock::TimePoint t1 = time::steady_clock::now();
51 f();
52 time::steady_clock::TimePoint t2 = time::steady_clock::now();
53 return time::duration_cast<time::microseconds>(t2 - t1);
54 }
55
56protected:
57 typedef std::function<Name(size_t)> NameGenerator;
58
59 class SimpleNameGenerator
60 {
61 public:
62 explicit
63 SimpleNameGenerator(const Name& prefix = "/cs/benchmark")
64 : m_prefix(prefix)
65 {
66 }
67
68 Name
69 operator()(size_t i) const
70 {
71 Name name(m_prefix);
72 name.appendNumber(i % 4);
73 name.appendNumber(i);
74 return name;
75 }
76
77 private:
78 Name m_prefix;
79 };
80
81 std::vector<shared_ptr<Interest>>
82 makeInterestWorkload(size_t count, const NameGenerator& genName = SimpleNameGenerator())
83 {
84 std::vector<shared_ptr<Interest>> workload(count);
85 for (size_t i = 0; i < count; ++i) {
86 Name name = genName(i);
87 workload[i] = makeInterest(name);
88 }
89 return workload;
90 }
91
92 std::vector<shared_ptr<Data>>
93 makeDataWorkload(size_t count, const NameGenerator& genName = SimpleNameGenerator())
94 {
95 std::vector<shared_ptr<Data>> workload(count);
96 for (size_t i = 0; i < count; ++i) {
97 Name name = genName(i);
98 workload[i] = makeData(name);
99 }
100 return workload;
101 }
102
103protected:
104 Cs cs;
105 static const size_t CS_CAPACITY = 50000;
106};
107
108BOOST_FIXTURE_TEST_SUITE(TableCsBenchmark, CsBenchmarkFixture)
109
110// find miss, then insert
111BOOST_AUTO_TEST_CASE(FindMissInsert)
112{
113 std::vector<shared_ptr<Interest>> interestWorkload = makeInterestWorkload(CS_CAPACITY);
114 const size_t REPEAT = 4;
115 std::vector<shared_ptr<Data>> dataWorkload[REPEAT];
116 for (size_t j = 0; j < REPEAT; ++j) {
117 dataWorkload[j] = makeDataWorkload(CS_CAPACITY);
118 }
119
120 time::microseconds d = timedRun([&] {
121 for (size_t j = 0; j < REPEAT; ++j) {
122 for (size_t i = 0; i < CS_CAPACITY; ++i) {
123 cs.find(*interestWorkload[i]);
124 cs.insert(*dataWorkload[j][i], false);
125 }
126 }
127 });
128 BOOST_TEST_MESSAGE("find(miss)-insert " << (CS_CAPACITY * REPEAT) << ": " << d);
129}
130
131// insert, then find hit
132BOOST_AUTO_TEST_CASE(InsertFindHit)
133{
134 std::vector<shared_ptr<Interest>> interestWorkload = makeInterestWorkload(CS_CAPACITY);
135 const size_t REPEAT = 4;
136 std::vector<shared_ptr<Data>> dataWorkload[REPEAT];
137 for (size_t j = 0; j < REPEAT; ++j) {
138 dataWorkload[j] = makeDataWorkload(CS_CAPACITY);
139 }
140
141 time::microseconds d = timedRun([&] {
142 for (size_t j = 0; j < REPEAT; ++j) {
143 for (size_t i = 0; i < CS_CAPACITY; ++i) {
144 cs.insert(*dataWorkload[j][i], false);
145 cs.find(*interestWorkload[i]);
146 }
147 }
148 });
149 BOOST_TEST_MESSAGE("insert-find(hit) " << (CS_CAPACITY * REPEAT) << ": " << d);
150}
151
152// find(leftmost) hit
153BOOST_AUTO_TEST_CASE(Leftmost)
154{
155 const size_t N_CHILDREN = 10;
156 const size_t N_INTERESTS = CS_CAPACITY / N_CHILDREN;
157 std::vector<shared_ptr<Interest>> interestWorkload = makeInterestWorkload(N_INTERESTS);
158 for (auto&& interest : interestWorkload) {
159 interest->setChildSelector(0);
160 for (size_t j = 0; j < N_CHILDREN; ++j) {
161 Name name = interest->getName();
162 name.appendNumber(j);
163 shared_ptr<Data> data = makeData(name);
164 cs.insert(*data, false);
165 }
166 }
167 BOOST_REQUIRE(cs.size() == N_INTERESTS * N_CHILDREN);
168
169 const size_t REPEAT = 4;
170
171 time::microseconds d = timedRun([&] {
172 for (size_t j = 0; j < REPEAT; ++j) {
173 for (const auto& interest : interestWorkload) {
174 cs.find(*interest);
175 }
176 }
177 });
178 BOOST_TEST_MESSAGE("find(leftmost) " << (N_INTERESTS * N_CHILDREN * REPEAT) << ": " << d);
179}
180
181// find(rightmost) hit
182BOOST_AUTO_TEST_CASE(Rightmost)
183{
184 const size_t N_CHILDREN = 10;
185 const size_t N_INTERESTS = CS_CAPACITY / N_CHILDREN;
186 std::vector<shared_ptr<Interest>> interestWorkload = makeInterestWorkload(N_INTERESTS);
187 for (auto&& interest : interestWorkload) {
188 interest->setChildSelector(1);
189 for (size_t j = 0; j < N_CHILDREN; ++j) {
190 Name name = interest->getName();
191 name.appendNumber(j);
192 shared_ptr<Data> data = makeData(name);
193 cs.insert(*data, false);
194 }
195 }
196 BOOST_REQUIRE(cs.size() == N_INTERESTS * N_CHILDREN);
197
198 const size_t REPEAT = 4;
199
200 time::microseconds d = timedRun([&] {
201 for (size_t j = 0; j < REPEAT; ++j) {
202 for (const auto& interest : interestWorkload) {
203 cs.find(*interest);
204 }
205 }
206 });
207 BOOST_TEST_MESSAGE("find(rightmost) " << (N_INTERESTS * N_CHILDREN * REPEAT) << ": " << d);
208}
209
210BOOST_AUTO_TEST_SUITE_END()
211
212} // namespace tests
213} // namespace nfd