-
Notifications
You must be signed in to change notification settings - Fork 1
/
ycsbc.cc
140 lines (129 loc) · 4.42 KB
/
ycsbc.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//
// ycsbc.cc
// YCSB-C
//
// Created by Jinglei Ren on 12/19/14.
// Copyright (c) 2014 Jinglei Ren <jinglei@ren.systems>.
// Modified by Yongping Luo on 3/4/22
// Copyright (c) 2022 Yongping Luo <ypluo18@qq.com>
//
#include <cstring>
#include <string>
#include <iostream>
#include <vector>
#include "utils.h"
#include "basic_db.h"
#include "core_workload.h"
using namespace std;
using namespace ycsbc;
bool query_only = false;
void UsageMessage(const char *command) {
cout << "Usage: " << command << " [options]" << endl;
cout << "Options:" << endl;
cout << "-P propertyfile: load properties from the given file. Multiple files can" << endl;
cout << " be specified, and will be processed in the order specified" << endl;
cout << "-F datasetfile: using keys from a given file" << endl;
cout << "--query_only: do not generate dataset file" << endl;
}
void ParseCommandLine(int argc, const char *argv[], utils::Properties &props) {
int argindex = 1;
while (argindex < argc) {
if (strcmp(argv[argindex], "-P") == 0) {
argindex++;
if (argindex >= argc) {
UsageMessage(argv[0]);
exit(0);
}
ifstream input(argv[argindex]);
try {
props.Load(input);
} catch (const string &message) {
cout << message << endl;
exit(0);
}
input.close();
argindex++;
}
else if (strcmp(argv[argindex], "-F") == 0) {
argindex++;
if (argindex >= argc) {
UsageMessage(argv[0]);
exit(0);
}
props.SetProperty("dataset_file", argv[argindex]);
argindex++;
}
else if (strcmp(argv[argindex], "--query_only") == 0) {
argindex++;
query_only = true;
}
else {
cout << "Unknown option '" << argv[argindex] << "'" << endl;
exit(0);
}
}
if (argindex == 1 || argindex != argc) {
UsageMessage(argv[0]);
exit(0);
}
}
int main(const int argc, const char *argv[]) {
utils::Properties props;
ParseCommandLine(argc, argv, props);
const string filename = props.GetProperty("dataset_file", "");
const int insertstart = stoi(props.GetProperty(CoreWorkload::INSERT_START_PROPERTY, CoreWorkload::INSERT_START_DEFAULT));
const int recordcount = stoi(props.GetProperty(CoreWorkload::RECORD_COUNT_PROPERTY, "1000"));
const int operationcount = stoi(props.GetProperty(CoreWorkload::OPERATION_COUNT_PROPERTY, "1000"));
const float insert_ratio = stof(props.GetProperty(CoreWorkload::INSERT_PROPORTION_PROPERTY, "0"));
ycsbc::CoreWorkload wl(filename, insertstart + recordcount + operationcount * (insert_ratio + 0.1));
wl.Init(props);
// generate load
std::string key;
std::vector<KVPair> values;
// generate load
if(query_only == false) {
BasicDB db_load("dataset.dat");
for(int i = 0; i < recordcount; i++) {
key = wl.NextSequenceKey();
db_load.Insert(key, values);
}
} else {
// do not generate a dataset file
for(int i = 0; i < recordcount; i++) {
key = wl.NextSequenceKey();
}
}
// generate query workload
BasicDB db_txn("query.dat");
std::vector<KVPair> result;
std::vector<std::vector<KVPair>> scanresult;
int len;
for(int i = 0; i < operationcount; i++) {
switch(wl.NextOperation()) {
case READ:
key = wl.NextTransactionKey();
db_txn.Read(key, result);
break;
case UPDATE:
key = wl.NextTransactionKey();
db_txn.Update(key, values);
break;
case INSERT:
key = wl.NextSequenceKey(true);
db_txn.Insert(key, values);
break;
case SCAN:
key = wl.NextTransactionKey();
len = wl.NextScanLength();
db_txn.Scan(key, len, scanresult);
break;
case READMODIFYWRITE:
key = wl.NextTransactionKey();
db_txn.Read(key, result);
db_txn.Update(key, values);
break;
default:
throw utils::Exception("Operation request is not recognized!");
}
}
}