10 #include "../macros.h"
11 #include "../varkey.h"
12 #include "../thread.h"
14 #include "../spinbarrier.h"
16 #include "../record/encoder.h"
24 #define ENCSTRESS_REC_KEY_FIELDS(x, y) \
26 #define ENCSTRESS_REC_VALUE_FIELDS(x, y) \
35 DO_STRUCT(encstress_rec, ENCSTRESS_REC_KEY_FIELDS, ENCSTRESS_REC_VALUE_FIELDS)
37 class encstress_worker : public bench_worker {
40 unsigned int worker_id,
41 unsigned long seed, abstract_db *db,
42 const map<string, abstract_ordered_index *> &open_tables,
43 spin_barrier *barrier_a, spin_barrier *barrier_b)
44 : bench_worker(worker_id, false, seed, db,
45 open_tables, barrier_a, barrier_b),
46 tbl(open_tables.at("table"))
53 void *txn = db->new_txn(txn_flags, arena, txn_buf());
54 const string k = u64_varkey(r.next() % nkeys).str();
57 ALWAYS_ASSERT(tbl->get(txn, k, v));
58 if (likely(db->commit_txn(txn)))
59 return txn_result(true, 0);
60 } catch (abstract_db::abstract_abort_exception &ex) {
63 return txn_result(false, 0);
67 TxnRead(bench_worker *w)
69 return static_cast<encstress_worker *>(w)->txn_read();
72 virtual workload_desc_vec
76 w.push_back(workload_desc("Read", 1.0, TxnRead));
81 abstract_ordered_index *tbl;
84 class encstress_loader : public bench_loader {
86 encstress_loader(unsigned long seed,
88 const map<string, abstract_ordered_index *> &open_tables)
89 : bench_loader(seed, db, open_tables)
96 abstract_ordered_index *tbl = open_tables.at("table");
99 const size_t batchsize = (db->txn_max_batch_size() == -1) ?
100 10000 : db->txn_max_batch_size();
101 ALWAYS_ASSERT(batchsize > 0);
102 const size_t nbatches = nkeys / batchsize;
104 void *txn = db->new_txn(txn_flags, arena, txn_buf());
105 for (size_t j = 0; j < nkeys; j++) {
106 const encstress_rec::key key(j);
107 encstress_rec::value rec;
108 rec.f0 = 1; rec.f1 = 1; rec.f2 = 1; rec.f3 = 1;
109 rec.f4 = 1; rec.f5 = 1; rec.f6 = 1; rec.f7 = 1;
111 tbl->insert(txn, Encode(key), Encode(buf, rec));
114 cerr << "batch 1/1 done" << endl;
115 ALWAYS_ASSERT(db->commit_txn(txn));
117 for (size_t i = 0; i < nbatches; i++) {
118 size_t keyend = (i == nbatches - 1) ? nkeys : (i + 1) * batchsize;
119 void *txn = db->new_txn(txn_flags, arena, txn_buf());
120 for (size_t j = i * batchsize; j < keyend; j++) {
121 const encstress_rec::key key(j);
122 encstress_rec::value rec;
123 rec.f0 = 1; rec.f1 = 1; rec.f2 = 1; rec.f3 = 1;
124 rec.f4 = 1; rec.f5 = 1; rec.f6 = 1; rec.f7 = 1;
126 tbl->insert(txn, Encode(key), Encode(buf, rec));
129 cerr << "batch " << (i + 1) << "/" << nbatches << " done" << endl;
130 ALWAYS_ASSERT(db->commit_txn(txn));
133 } catch (abstract_db::abstract_abort_exception &ex) {
134 // shouldn't abort on loading!
135 ALWAYS_ASSERT(false);
138 cerr << "[INFO] finished loading USERTABLE" << endl;
142 class encstress_bench_runner : public bench_runner {
144 encstress_bench_runner(abstract_db *db)
147 open_tables["table"] = db->open_index("table", sizeof(encstress_rec));
151 virtual vector<bench_loader *>
154 vector<bench_loader *> ret;
155 ret.push_back(new encstress_loader(0, db, open_tables));
159 virtual vector<bench_worker *>
162 fast_random r(8544290);
163 vector<bench_worker *> ret;
164 for (size_t i = 0; i < nthreads; i++)
166 new encstress_worker(
167 i, r.next(), db, open_tables,
168 &barrier_a, &barrier_b));
174 encstress_do_test(abstract_db *db, int argc, char **argv)
176 nkeys = size_t(scale_factor * 1000.0);
177 ALWAYS_ASSERT(nkeys > 0);
178 encstress_bench_runner r(db);