1 #include "../common.hpp"
6 #include <boost/concept_check.hpp>
8 #include "bdb_database.hpp"
10 namespace swarm {
namespace log {
12 using gpulog::logrecord;
14 const int CACHESIZE = 1024*1024*64 ;
16 const char* fileFormatVersion =
"1";
17 const char* swarmngVersion =
"1.1";
20 bool operator <(
const pkey_t& a,
const pkey_t& b){
22 return a.system_event_id < b.system_event_id;
24 return a.time < b.time;
36 data->set_flags(DB_DBT_APPMALLOC);
37 data->set_size(
sizeof(T));
38 data->set_data(
new T(t));
52 pkey_t& pkey = *(pkey_t*) key->get_data();
57 int lr_extract_evtid(Db *secondary,
const Dbt *key,
const Dbt *data, Dbt *result) {
58 pkey_t& pkey = *(pkey_t*) key->get_data();
63 int lr_extract_time(Db *secondary,
const Dbt *key,
const Dbt *data, Dbt *result) {
64 pkey_t& pkey = *(pkey_t*) key->get_data();
76 if(k1->size < k2->size)
78 else if(k1->size > k2->size)
81 if( (k1->size ==
sizeof(T)) && (k2->size ==
sizeof(T)) ) {
82 T& a = *(T*)(k1->data);
83 T& b = *(T*)(k2->data);
85 else if(b < a)
return 1;
93 const int create_mode = 00600;
95 void bdb_database::openEnv(
const std::string& basedir){
96 std::cerr <<
"Initializing BDB environment in `" << basedir <<
"`" << std::endl;
97 env->open(basedir.c_str(),DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL,create_mode);
100 DbEnv* bdb_database::createDefaultEnv(){
101 DbEnv* env =
new DbEnv(0);
102 env->set_cachesize(0,CACHESIZE,0);
106 std::string directory_name(
const std::string& s){
108 char* w = strdup(s.c_str());
109 std::string d(dirname(w));
115 std::string base_name(
const std::string& s){
117 char* w = strdup(s.c_str());
118 std::string d(basename(w));
124 void bdb_database::openInternal(
const std::string& pathName,
int open_mode){
126 openEnv(directory_name(pathName));
127 std::string fileName = base_name(pathName);
129 const char * fn = fileName.c_str();
131 metadata.open(NULL, fn,
"metadata", DB_BTREE, open_mode, create_mode);
133 primary.set_bt_compare(bdb_compare<pkey_t>);
134 primary.open(NULL, fn,
"primary", DB_BTREE, open_mode, create_mode);
139 system_idx.set_flags(DB_DUP | DB_DUPSORT);
140 system_idx.set_bt_compare(bdb_compare<sysid_t>);
141 system_idx.set_dup_compare(bdb_compare<pkey_t>);
142 system_idx.open(NULL, fn,
"system_idx", DB_BTREE, open_mode , create_mode);
148 time_idx.set_flags(DB_DUP | DB_DUPSORT);
149 time_idx.set_bt_compare(bdb_compare<float>);
150 time_idx.set_dup_compare(bdb_compare<pkey_t>);
151 time_idx.open(NULL, fn,
"time_idx", DB_BTREE, open_mode , create_mode);
154 event_idx.set_flags(DB_DUP | DB_DUPSORT);
155 event_idx.set_bt_compare(bdb_compare<evtid_t>);
156 event_idx.set_dup_compare(bdb_compare<pkey_t>);
157 event_idx.open(NULL, fn,
"event_idx", DB_BTREE, open_mode , create_mode);
163 primary.associate(NULL, &time_idx , &lr_extract_time , DB_IMMUTABLE_KEY);
164 primary.associate(NULL, &event_idx , &lr_extract_evtid, DB_IMMUTABLE_KEY);
167 void bdb_database::openForReading(
const std::string& fileName) {
168 openInternal(fileName, DB_RDONLY);
169 validateVersionInfo();
172 void bdb_database::create(
const std::string& fileName){
173 openInternal(fileName, DB_CREATE);
177 void bdb_database::createEmpty(
const std::string& fileName){
178 openInternal(fileName, DB_CREATE );
182 void bdb_database::put(logrecord& lr){
184 double time;
int sys;
188 case 1:
case 2:
case 11:
case 15:
case 16:
194 time = std::numeric_limits<double>::quiet_NaN();
198 pkey_t pkey( (
float) time, sys, lr.msgid());
200 Dbt key(&pkey,
sizeof(pkey));
201 Dbt data((
void*)lr.ptr,lr.len());
202 primary.put(NULL,&key,&data,0);
205 void bdb_database::addMetaData(
const std::string name,
const std::string value){
206 Dbt key((
void *)name.data(),name.size()), data((
void*)value.data(), value.size());
207 metadata.put(NULL,&key,&data,0);
209 std::
string bdb_database::getMetaData(const
std::
string name) {
210 Dbt key((
void*)name.data(),name.size()), data;
211 data.set_flags(DB_DBT_MALLOC);
213 metadata.get(NULL,&key,&data,0);
216 size_t n = data.get_size();
217 char* ptr = (
char*) data.get_data();
218 std::string value(data.get_size(),0);
219 std::copy(ptr, ptr+n, value.begin());
220 free(ptr); data.set_data(0);
225 void bdb_database::fillVersionInfo() {
226 addMetaData(
"fileFormatVersion", fileFormatVersion);
227 addMetaData(
"swarmngVersion", swarmngVersion);
229 bool bdb_database::validateVersionInfo() {
230 return (getMetaData(
"fileFormatVersion") == fileFormatVersion ) ;
234 Pprimary_cursor_t bdb_database::primary_cursor(){
235 shared_ptr<primary_cursor_t>
c(
new primary_cursor_t);
236 primary.cursor(0,&
c->_c,0);
240 void bdb_database::close(){
249 void primary_cursor_t::close(){
253 bool primary_cursor_t::get(pkey_t& key, lrw_t& lr, uint32_t flags){
258 k.set_ulen(
sizeof(key));
260 d.set_flags(DB_DBT_USERMEM);
261 k.set_flags(DB_DBT_USERMEM);
262 return _c->get(&k,&d,flags) == 0;
265 bool primary_cursor_t::position_at(pkey_t& key,lrw_t& lr){
270 k.set_ulen(
sizeof(key));
272 d.set_flags(DB_DBT_USERMEM);
273 k.set_flags(DB_DBT_USERMEM);
274 k.set_size(
sizeof(key));
275 return _c->get(&k,&d,DB_SET_RANGE) == 0;
279 void bdb_database::flush()
282 primary.sync(0);time_idx.sync(0); event_idx.sync(0); system_idx.sync(0);