Skip to content

Commit e074150

Browse files
added rubis
1 parent 7fd863e commit e074150

File tree

2 files changed

+342
-0
lines changed

2 files changed

+342
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
#include <cstdio>
2+
#include <fstream>
3+
#include <iostream>
4+
#include <string>
5+
#include <thread>
6+
7+
#include "rubis.hpp"
8+
//------------opcode------- number of parameters
9+
10+
//sellItem 0 2(id+value)
11+
//storeBuyNow 1 2(id+value) by leader
12+
//registerUser 2 1(id) by leader
13+
//openAuction 1(id) by default consider 100 auctions are open.
14+
//placeBid 3 3(auctionid+userid+value)
15+
//query 4 like movie does not consider read.
16+
17+
int main(int argc, char* argv[]) {
18+
std::string loc =
19+
"/users/jsaber/binHamband/workload/";
20+
21+
int nr_procs = static_cast<int>(std::atoi(argv[1]));
22+
int num_ops = static_cast<int>(std::atoi(argv[2]));
23+
double write_percentage = static_cast<double>(std::atoi(argv[3]));
24+
25+
loc += std::to_string(nr_procs) + "-" + std::to_string(num_ops) + "-" +
26+
std::to_string(static_cast<int>(write_percentage));
27+
loc += "/rubis/";
28+
29+
std::ofstream* outfile = new std::ofstream[nr_procs];
30+
std::vector<std::string>* calls = new std::vector<std::string>[nr_procs];
31+
for (int i = 0; i < nr_procs; i++) {
32+
remove((loc + std::to_string(i + 1) + ".txt").c_str());
33+
outfile[i].open(loc + std::to_string(i + 1) + ".txt", std::ios_base::app);
34+
calls[i] = std::vector<std::string>();
35+
}
36+
37+
Rubis* test = new Rubis();
38+
39+
// MethodCallFactory factory = MethodCallFactory(test, nr_procs);
40+
41+
write_percentage /= 100;
42+
int num_replicas = nr_procs;
43+
double total_writes = num_ops * write_percentage;
44+
int queries = num_ops - total_writes;
45+
46+
int num_conflicting_write_methods = 2;
47+
int num_nonconflicting_write_methods = 2;
48+
int num_read_methods = 0;
49+
50+
std::cout << "ops: " << num_ops << std::endl;
51+
std::cout << "write_perc: " << write_percentage << std::endl;
52+
std::cout << "writes: " << total_writes << std::endl;
53+
std::cout << "reads: " << queries << std::endl;
54+
55+
int expected_calls_per_update_method =
56+
total_writes /
57+
(num_conflicting_write_methods + num_nonconflicting_write_methods);
58+
std::cout << "expected #calls per update method "
59+
<< expected_calls_per_update_method << std::endl;
60+
61+
std::cout << "expected #calls per conflicting writes in leader "
62+
<< expected_calls_per_update_method << std::endl;
63+
std::cout << "total conflicting #calls in leader "
64+
<< expected_calls_per_update_method * num_conflicting_write_methods
65+
<< std::endl;
66+
67+
int expected_nonconflicting_write_calls_per_follower =
68+
(total_writes -
69+
expected_calls_per_update_method * num_conflicting_write_methods) /
70+
(nr_procs - 1);
71+
72+
std::cout << "expected #calls per nonconflicting writes in followers "
73+
<< expected_nonconflicting_write_calls_per_follower << std::endl;
74+
std::cout << "total nonconflicting #calls in followers "
75+
<< expected_nonconflicting_write_calls_per_follower *
76+
num_nonconflicting_write_methods * (nr_procs - 1)
77+
<< std::endl;
78+
79+
int write_calls =
80+
expected_calls_per_update_method * num_conflicting_write_methods +
81+
expected_nonconflicting_write_calls_per_follower *
82+
num_nonconflicting_write_methods * (nr_procs - 1);
83+
84+
// first allocating writes operations to the nodes
85+
for (int i = 1; i <= num_replicas; i++) {
86+
// first leader
87+
if (i == 1) {
88+
for (int type = 0; type <= 0; type++) {
89+
int count = 0;
90+
for (; count < expected_calls_per_update_method;) {
91+
// storeBuyNow
92+
std::string callStr;
93+
if (type == 0) {
94+
std::string b_id = std::to_string(1 + std::rand() % 100);
95+
std::string value = std::to_string(std::rand() % 1000);
96+
callStr = "1 " + b_id + "-" + value;
97+
}
98+
MethodCall call = ReplicatedObject::createCall("id", callStr);
99+
if (test->isPermissible(call)) {
100+
test->execute(call);
101+
calls[i - 1].push_back(callStr);
102+
count++;
103+
}
104+
}
105+
}
106+
}
107+
// second leader
108+
else if (i == 2) {
109+
for (int type = 0; type <= 0; type++) {
110+
int count = 0;
111+
for (; count < expected_calls_per_update_method;) {
112+
// registerUser
113+
std::string callStr;
114+
if (type == 0) {
115+
std::string u_id = std::to_string(1+ std::rand() % 100);
116+
callStr = "2 " + u_id;
117+
}
118+
MethodCall call = ReplicatedObject::createCall("id", callStr);
119+
if (test->isPermissible(call)) {
120+
test->execute(call);
121+
calls[i - 1].push_back(callStr);
122+
count++;
123+
}
124+
}
125+
}
126+
}
127+
// follower
128+
else {
129+
// non-conflicting write method
130+
for (int type = 0; type <= 1; type++) {
131+
for (int count = 0; count <
132+
expected_nonconflicting_write_calls_per_follower; count++) {
133+
std::string callStr;
134+
if (type == 0) {
135+
// sellitem
136+
std::string s_id = std::to_string(1+ std::rand() % 100);
137+
std::string value = std::to_string(std::rand() % 1000);
138+
callStr = "0 " + s_id+ "-"+ value;
139+
}
140+
if (type == 1) {
141+
// placeBid
142+
std::string a_id = std::to_string(1+ std::rand() % 100); //auction id
143+
std::string u_id = std::to_string(1+ std::rand() % 100); //user id
144+
std::string value = std::to_string(std::rand() % 1000); //bid value
145+
146+
callStr = "3 " + a_id + "-" + u_id + "-" + value;
147+
}
148+
149+
MethodCall call = ReplicatedObject::createCall("id", callStr);
150+
test->execute(call);
151+
calls[i - 1].push_back(callStr);
152+
}
153+
}
154+
}
155+
}
156+
157+
// allocate reads to the nodes
158+
int q = num_ops - write_calls;
159+
std::cout << "q: " << q << std::endl;
160+
161+
// if(calls[0].size() > calls[1].size())
162+
int read_calls = q;
163+
int index = 0;
164+
165+
std::cout << "after adding writes nodes" << std::endl;
166+
for (int i = 0; i < nr_procs; i++)
167+
std::cout << i + 1 << " size: " << calls[i].size() << std::endl;
168+
169+
for (int i = 0; i < nr_procs; i++) {
170+
calls[i].insert(calls[i].begin(),
171+
std::string("#" + std::to_string(write_calls)));
172+
std::random_shuffle(calls[i].begin() + 1, calls[i].end());
173+
}
174+
175+
for (int i = 0; i < nr_procs; i++) {
176+
for (int x = 0; x < calls[i].size(); x++)
177+
outfile[i] << calls[i][x] << std::endl;
178+
outfile[i].close();
179+
}
180+
181+
std::cout << "expected calls to receive: " << write_calls << std::endl;
182+
return 0;
183+
}

wellcoordination/benchmark/rubis.hpp

+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
2+
#include <iostream>
3+
#include <sstream>
4+
#include <string>
5+
#include <vector>
6+
#include <cstdarg>
7+
#include <cstring>
8+
#include <unordered_set>
9+
10+
#include "../src/replicated_object.hpp"
11+
12+
13+
typedef unsigned char uint8_t;
14+
15+
class Rubis : public ReplicatedObject
16+
{
17+
18+
//sellItem 0 2(id+value)
19+
//storeBuyNow 1 2(id+value) by leader
20+
//registerUser 2 1(id) by leader
21+
//openAuction 1(id) by default consider 100 auctions are open.
22+
//placeBid 3 3(auctionid+userid+value)
23+
//query 4 like movie does not consider read.
24+
private:
25+
26+
public:
27+
28+
enum MethodType{
29+
SELL_ITEM = 0,
30+
STORE_BUY_NOW = 1,
31+
REGISTER_USER = 2,
32+
PLACE_BID = 3,
33+
QUERY = 4
34+
};
35+
std::atomic<int> auction [100][3]={{0}}; //auctionid-quantity-user propsed max value-max value
36+
bool registeredusers [100]={false};
37+
int userscounter=0;
38+
//std::set<std::string> movies;
39+
//std::set<std::string> customers;
40+
41+
42+
Rubis() {
43+
read_methods.push_back(static_cast<int>(MethodType::QUERY));
44+
45+
update_methods.push_back(static_cast<int>(MethodType::SELL_ITEM));
46+
update_methods.push_back(static_cast<int>(MethodType::STORE_BUY_NOW));
47+
update_methods.push_back(static_cast<int>(MethodType::REGISTER_USER));
48+
update_methods.push_back(static_cast<int>(MethodType::PLACE_BID));
49+
50+
method_args.insert(std::make_pair(static_cast<int>(MethodType::SELL_ITEM), 2));
51+
method_args.insert(std::make_pair(static_cast<int>(MethodType::STORE_BUY_NOW), 2));
52+
method_args.insert(std::make_pair(static_cast<int>(MethodType::REGISTER_USER), 1));
53+
method_args.insert(std::make_pair(static_cast<int>(MethodType::PLACE_BID), 3));
54+
method_args.insert(std::make_pair(static_cast<int>(MethodType::QUERY), 0));
55+
56+
// conflicts
57+
std::vector<int> g1;
58+
g1.push_back(static_cast<int>(MethodType::STORE_BUY_NOW));
59+
//g1.push_back(static_cast<int>(MethodType::REMOVE_MOVIE));
60+
synch_groups.push_back(g1);
61+
std::vector<int> g2;
62+
g2.push_back(static_cast<int>(MethodType::REGISTER_USER));
63+
//g2.push_back(static_cast<int>(MethodType::REMOVE_CUSTOMER));
64+
synch_groups.push_back(g2);
65+
}
66+
67+
Rubis(Rubis &obj) : ReplicatedObject(obj)
68+
{
69+
//state
70+
std::memcpy(auction, obj.auction, sizeof(auction));
71+
std::memcpy(registeredusers, obj.registeredusers, sizeof(registeredusers));
72+
userscounter =obj.userscounter;
73+
//auction = obj.auction;
74+
//registeredusers = obj.registeredusers;
75+
}
76+
77+
virtual void toString()
78+
{
79+
std::cout << "#users_counter: " << userscounter << std::endl;
80+
//std::cout << "#customer_elements: " << customers.size() << std::endl;
81+
}
82+
83+
84+
// 0
85+
void sellItem(int s_id, int value)
86+
{
87+
auction[s_id][0]=value;
88+
}
89+
// 1
90+
void storeBuyNow(int s_id, int value)
91+
{
92+
if (auction[s_id][0]>value)
93+
auction[s_id][0]=auction[s_id][0]-value;
94+
}
95+
// 2
96+
void registeruser(int u_id)
97+
{
98+
registeredusers[u_id]=true;
99+
userscounter++;
100+
}
101+
// 3
102+
void placeBid(int a_id, int u_id, int value)
103+
{
104+
if(registeredusers[u_id]){
105+
if(auction[a_id][2]<value){
106+
auction[a_id][1]=u_id;
107+
auction[a_id][2]=value;
108+
}
109+
}
110+
}
111+
112+
Rubis query() { return *this; }
113+
114+
115+
virtual ReplicatedObject* execute(MethodCall call)
116+
{
117+
switch (static_cast<MethodType>(call.method_type))
118+
{
119+
case MethodType::SELL_ITEM:
120+
size_t index = call.arg.find_first_of('-');
121+
int s_id = std::stoi(call.arg.substr(0, index));
122+
int value = std::stoi(call.arg.substr(index + 1, call.arg.length()));
123+
sellItem(int s_id, int value);
124+
break;
125+
case MethodType::STORE_BUY_NOW:
126+
size_t index = call.arg.find_first_of('-');
127+
int s_id = std::stoi(call.arg.substr(0, index));
128+
int value = std::stoi(call.arg.substr(index + 1, call.arg.length()));
129+
storeBuyNow(int s_id, int value);
130+
break;
131+
case MethodType::REGISTER_USER:
132+
registeruser(std::stoi(call.arg));
133+
break;
134+
case MethodType::PLACE_BID:
135+
size_t index = call.arg.find_first_of('-');
136+
int a_id = std::stoi(call.arg.substr(0, index));
137+
std::string sub_arg = call.arg.substr(index + 1, call.arg.length());
138+
index = sub_arg.find_first_of('-');
139+
int u_id = std::stoi(sub_arg.substr(0, index));
140+
int value = std::stoi(sub_arg.substr(index + 1, sub_arg.length()));
141+
placeBid(a_id, u_id, value)
142+
break;
143+
case MethodType::QUERY:
144+
return this;
145+
break;
146+
default:
147+
std::cout << "wrong method name" << std::endl;
148+
break;
149+
}
150+
return this;
151+
}
152+
153+
154+
155+
virtual bool isPermissible(MethodCall call)
156+
{
157+
return true;
158+
}
159+
};

0 commit comments

Comments
 (0)