-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathplg_berkeley.cpp
executable file
·147 lines (130 loc) · 5.36 KB
/
plg_berkeley.cpp
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
141
142
143
144
145
146
147
//
// Created by fl on 3/22/21.
//
#include "plg_berkeley.h"
bool assert_opr_success(bool eql, double latency){
if(!eql){
throw latency;
}
return(eql);
}
int plg_berkeley::opendb(){
//env.open("/home/fl/Desktop/replayer/tmp/", DB_CREATE | DB_INIT_MPOOL, 0);
pdb = new Db(NULL, 0);
//pdb->set_flags(DB_DUP);
int pstatus=pdb->set_pagesize(1024); //1024 bytes
int cstatus=pdb->set_cachesize(0,256*1024*1024,1); //256MB
int ostatus=pdb->open(NULL, "./tmp/access.db", NULL, DB_BTREE, DB_CREATE, 0);
assert_opr_success(ostatus==0, 0);
assert_opr_success(pstatus==0, 0);
assert_opr_success(cstatus==0, 0);
printf("berkeleydb opened \n");
return(0);
}
int plg_berkeley::closedb(){
//TODO: don't to any logging
if (pdb != NULL) {
pdb->close(0);
delete pdb;
// You have to close and delete an exisiting handle, then create a new one before you can use it to remove a database (file).
pdb = new Db(NULL, 0);
pdb->remove("./tmp/access.db", NULL, 0);
//delete pdb;
}
printf("berkeleydb closed \n");
return(0);
}
double plg_berkeley::opr_insert(uint64_t ikey, const char* val){
unsigned char xkey[8];
memcpy(xkey,&ikey,sizeof(ikey));
auto tp0 = std::chrono::high_resolution_clock::now();
Dbt dkey(const_cast<unsigned char*>(xkey), 8);
Dbt dval(const_cast<char*>(val), strlen(val));
int istatus=pdb->put(NULL, &dkey, &dval, 0);
//std::cout<<"berkeleydb insert keysize=="<< (sizeof(xkey))<<" "<<"valsize=="<<strlen(val)<<" "<<xkey<<"____"<<val<<"\n"; //DEBUG
auto tp1 = std::chrono::high_resolution_clock::now();
std::chrono::nanoseconds time_span = tp1 - tp0;
double tps = (double)time_span.count()/1000; // us
assert(istatus == 0);
return(tps);
}
double plg_berkeley::opr_update(uint64_t ikey, const char* val){ //manually get then put
unsigned char xkey[8];
memcpy(xkey,&ikey,sizeof(ikey));
auto tp0 = std::chrono::high_resolution_clock::now();
Dbt dkey(const_cast<unsigned char*>(xkey), 8);
Dbt dval;
std:size_t oldValueSize;
int gstatus = pdb->get(NULL, &dkey, &dval, 0);
if (gstatus == 0) {// successful
//std::cout << "make the other value" << std::endl;
// raed it
oldValueSize = dval.get_size();
//std::cout << "dval size" << oldValueSize << std::endl;
//std::cout << " dval data: " << (char *)dval.get_data()<< std::endl;
// append a new value
char buffer[oldValueSize + VALUESIZE];
std::memcpy(buffer, dval.get_data(), oldValueSize );
std::memset(buffer + oldValueSize,'1', VALUESIZE);
// write the new value
Dbt dval(buffer, oldValueSize + VALUESIZE);
int pstatus = pdb->put(NULL, &dkey, &dval, 0);
assert(pstatus == 0);
//std::cout << " --------------- " << std::endl;
} else { // this is the first merge
//std::cout << "make the firts value" << std::endl;
char buffer[VALUESIZE];
std::memset(buffer, '0', VALUESIZE);
Dbt dval(buffer, VALUESIZE);
int pstatus = pdb->put(NULL, &dkey, &dval, 0);
assert(pstatus == 0);
//std::cout << "---------------" << std::endl;
}
auto tp1 = std::chrono::high_resolution_clock::now();
std::chrono::nanoseconds time_span = tp1 - tp0;
double tps = (double)time_span.count()/1000; // us
//assert_opr_success(ustatus!=DB_NOTFOUND, tps);
return(tps);
}
double plg_berkeley::opr_read(uint64_t ikey){
unsigned char xkey[8];
memcpy(xkey,&ikey,sizeof(ikey));
auto tp0 = std::chrono::high_resolution_clock::now();
std::size_t oldValueSize;
Dbt dkey(const_cast<unsigned char*>(xkey), 8);
Dbt dval;
//std::cout<<"berkeleydb read keysize=="<< (sizeof(xkey))<<" "<<"valsize=="<<sizeof(buffer)<<" "<<xkey<<"____"<<buffer<<"\n"; //DEBUG
int rstatus = pdb->get(NULL, &dkey, &dval, 0);
oldValueSize = dval.get_size();
//std::cout << "the value size : " << oldValueSize << std::endl;
char buffer[oldValueSize];
std::memcpy(buffer, dval.get_data(), oldValueSize );
// if (status == DB_NOTFOUND) {
// cout << "Not found" << endl;
// } else {
// cout << "Found: " << buffer << endl;
// }
//std::cout<<"berkeleydb read keysize=="<< (sizeof(xkey))<<" "<<"valsize=="<<sizeof(buffer)<<" "<<xkey<<"____"<<buffer<<"\n"; //DEBUG
auto tp1 = std::chrono::high_resolution_clock::now();
std::chrono::nanoseconds time_span = tp1 - tp0;
double tps = (double)time_span.count()/1000; // us
//assert_opr_success(rstatus!=DB_NOTFOUND, tps);
return(tps);
}
double plg_berkeley::opr_delete(uint64_t ikey){
unsigned char xkey[8];
memcpy(xkey,&ikey,sizeof(ikey));
auto tp0 = std::chrono::high_resolution_clock::now();
Dbt dkey(const_cast<unsigned char*>(xkey), 8);
int dstatus = pdb->del(NULL, &dkey, 0);
auto tp1 = std::chrono::high_resolution_clock::now();
std::chrono::nanoseconds time_span = tp1 - tp0;
double tps = (double)time_span.count()/1000; // us
//assert_opr_success(dstatus!=DB_NOTFOUND, tps);
return(tps);
}
double plg_berkeley::opr_merge(uint64_t ikey, const char* val){ //build-in RMW operation
return(opr_update(ikey, val));
// No built-in RMW in berkeleyDB
// https://docs.oracle.com/cd/E17275_01/html/api_reference/C/db.html
}