6 #include "../../btree_choice.h"
7 #include "../../thread.h"
8 #include "../../spinbarrier.h"
9 #include "../../varkey.h"
10 #include "kvrandom.hh"
25 inline quick_istr(unsigned long x, int minlen = 0)
31 set(unsigned long x, int minlen = 0)
33 bbuf_ = buf_ + sizeof(buf_) - 1;
35 *--bbuf_ = (x % 10) + '0';
37 } while (--minlen > 0 || x != 0);
43 buf_[sizeof(buf_) - 1] = 0;
56 return (buf_ + sizeof(buf_) - 1) - bbuf_;
62 return varkey((const uint8_t *) bbuf_, size());
67 class kvtest_worker : public ndb_thread {
69 kvtest_worker(btree &btr,
72 const volatile bool *phases)
73 : ndb_thread(false, string("kvtest-worker")),
74 btr(&btr), b(&b), id(id), phases(phases) {}
81 T()(*btr, id, phases);
88 const volatile bool *phases;
94 kvtest_runner(unsigned int nthreads)
95 : nthreads(nthreads) {}
101 spin_barrier barrier(nthreads);
102 volatile bool phases[T::NPhases] = {0};
103 vector<kvtest_worker<T> *> workers;
104 for (unsigned int i = 0; i < nthreads; i++)
105 workers.push_back(new kvtest_worker<T>(btr, barrier, i, phases));
106 for (unsigned int i = 0; i < nthreads; i++)
108 for (unsigned int i = 0; i < T::NPhases; i++) {
109 sleep(T::PhaseRuntimes[i]);
111 __sync_synchronize();
113 for (unsigned int i = 0; i < nthreads; i++) {
120 unsigned int nthreads;
124 static const size_t NPhases = 2;
125 static const unsigned long PhaseRuntimes[NPhases];
127 typedef kvrandom_lcg_nr rand_type;
130 operator()(btree &btr, unsigned int id, const volatile bool *phases) const
132 const int seed = 31949 + id % 48;
136 for (n = 0; !phases[0]; ++n) {
137 const int32_t x = (int32_t) r.next();
138 const quick_istr key(x), value(x + 1);
139 btree::value_type v = (btree::value_type) malloc(value.size());
140 NDB_MEMCPY(v, value.data(), value.size());
141 btr.insert(key.key(), v, 0, 0);
143 const double put_ms = t.lap_ms();
144 int32_t *a = (int32_t *) malloc(sizeof(int32_t) * n);
146 for (unsigned i = 0; i < n; i++)
147 a[i] = (int32_t) r.next();
148 for (unsigned i = 0; i < n; ++i)
149 swap(a[i], a[r.next() % n]);
153 for (g = 0; g < n && !phases[1]; ++g) {
154 const quick_istr key(a[g]), value(a[g] + 1);
155 btree::value_type v = 0;
156 ALWAYS_ASSERT(btr.search(key.key(), v));
157 ALWAYS_ASSERT(memcmp(value.data(), v, value.size()) == 0);
159 const double get_ms = t.lap_ms();
161 cout << "puts: " << n << ", rate: " << (double(n) / (put_ms / 1000.0)) << " ops/sec/core" << endl;
162 cout << "gets: " << g << ", rate: " << (double(g) / (get_ms / 1000.0)) << " ops/sec/core" << endl;
164 // XXX(stephentu): free btree values
168 const unsigned long kvtest_rw1::PhaseRuntimes[NPhases] = { 10, 10 }; // seconds
171 main(int argc, char **argv)
173 ALWAYS_ASSERT(argc == 2);
174 int nthreads = atoi(argv[1]);
175 ALWAYS_ASSERT(nthreads > 0);
176 kvtest_runner<kvtest_rw1> r(nthreads);