mongodb连接池c++封转

from : http://www.oschina.net/code/snippet_116907_16529

001

//函数返回0:成功 >0 出错

002

class cmongo{

 

003

    public:

004

        //默认构造函数,默认连接数为1

 

005

        cmongo();

006

        //传入连接数到构造函数,默认连接数为size

 

007

        cmongo(int size);

008

        //析构函数

 

009

        ~cmongo();

010

    public:

 

011

        //设置tcp读写超时时间

012

        int set_wr_timeout(double t);

 

013

        //连接

014

        int conn(string mhost="127.0.0.1",int mport=27017);

 

015

        //设置db collection

016

        int setdb(string mdb,string mcollection);

 

017

 

018

        int setindex(string key);

 

019

        //查询

020

        int get(map<string,string>& out,vector<string> in,string key,string key_val);

 

021

        //投递一批要查询的字段,fields为要查询哪些字段

022

        int gets(map< string,map<string,string> >& rout,vector<string> fields,vector<string> in,string key);

 

023

        //dump key-value dumpkey对应一个value

024

        int dumpkey(map< string,string >& rout,string key,string val);

 

025

        //dump key->map<key,value> dumpkey对应一组value

026

        int dumpvals(map< string,map<string,string> >& rout,vector<string> in,string key);

 

027

        //写入

028

        int set(map<string,string> in,string key,string key_val);

 

029

        //批量写入

030

        //更新接口,批量更新key="id"

 

031

        //  "123456":<key,value>,<key,value>

032

        //  "123457":<key,value>,<key,value>

 

033

        int sets(map< string,map<string,string> > in,string key);

034

        //删除

 

035

        int remove(string key,string key_val);

036

    private:

 

037

        string doc;

038

        //tcp读写超时时间

 

039

        double wr_timeout;

040

        pthread_mutex_t _jobmux;

 

041

        sem_t _jobsem;

042

        map<DBClientConnection*,bool> _joblst;

 

043

        pthread_mutex_t _dbmux;

044

 

 

045

};

046

 

 

047

 

048

 

 

049

cmongo::cmongo(int size){

050

    //doc

 

051

    doc=string(DB_DB)+"."+string(DB_COLLECTION);

052

    wr_timeout=3;

 

053

    //最大连接0-200

054

    if(size<0){

 

055

        size=1;

056

    }

 

057

    if(size>200){

058

        size=200;

 

059

    }

060

    if(_joblst.size()>0){

 

061

        return;

062

    }

 

063

    bool auto_conn=true;

064

    pthread_mutex_init(&_jobmux,NULL);

 

065

    if((sem_init(&_jobsem,0,0))<0){

066

        return;

 

067

    }

068

    pthread_mutex_lock(&_jobmux);

 

069

    for(int i=0;i<size;++i){

070

        DBClientConnection* pconn = newDBClientConnection(auto_conn,0,wr_timeout);

 

071

        if(pconn != NULL){

072

            _joblst[pconn]=false;

 

073

        }

074

    }

 

075

    pthread_mutex_unlock(&_jobmux);

076

 

 

077

 

078

}

 

079

cmongo::~cmongo(){

080

    doc="";

 

081

    pthread_mutex_lock(&_jobmux);

082

    map<DBClientConnection*,bool>::iterator it=_joblst.begin();

 

083

    while(it != _joblst.end()){

084

        delete it->first;

 

085

        it++;

086

    }

 

087

    pthread_mutex_unlock(&_jobmux);

088

}

 

089

int cmongo::set_wr_timeout(double t){

090

    wr_timeout=t;

 

091

    return RET_OK;

092

}

 

093

int cmongo::conn(string mhost,int mport){

094

    pthread_mutex_lock(&_jobmux);

 

095

    map<DBClientConnection*,bool>::iterator it=_joblst.begin();

096

    while(it!=_joblst.end()){

 

097

        string errmsg="";

098

        HostAndPort hp(mhost,mport);

 

099

        if(!(it->first->connect(hp,errmsg))){

100

            cerr<<"connect mhost:"<<mhost<<" mport:"<<mport<<" msg:"<<errmsg<<endl;

 

101

            it->second=true;

102

        }

 

103

        sem_post(&_jobsem);

104

        it++;

 

105

    }

106

    pthread_mutex_unlock(&_jobmux);

 

107

    return RET_OK;

108

}

 

109

int cmongo::setdb(string mdb,string mcollection){

110

    if(mdb.empty() || mcollection.empty()){

 

111

        return RET_PARERR;

112

    }

 

113

    doc=mdb+"."+mcollection;

114

    return RET_OK;

 

115

}

116

int cmongo::setindex(string key){

 

117

    if(key.empty()){

118

        return RET_PARERR;

 

119

    }  

120

    sem_wait(&_jobsem);

 

121

    pthread_mutex_lock(&_jobmux);

122

    map<DBClientConnection*,bool>::iterator it=_joblst.begin();

 

123

    while(it!=_joblst.end()){

124

        if(it->second == false){

 

125

            it->second=true;

126

            break;

 

127

        }

128

        it++;

 

129

    }

130

    pthread_mutex_unlock(&_jobmux);

 

131

    string bindex="{"+key+":1}";

132

    it->first->ensureIndex(doc,fromjson(bindex));

 

133

 

134

    pthread_mutex_lock(&_jobmux);

 

135

    it->second=false;

136

    pthread_mutex_unlock(&_jobmux);

 

137

    sem_post(&_jobsem);

138

 

 

139

    return RET_OK;

140

}

 

141

//out为检索出来的key-value数据对应,in 为要检索的字段,key,key_value为要检索的条件,暂不支持多条件检索

142

//单列查询

 

143

int cmongo::get(map<string,string>& out,vector<string> in,string key,string key_val){

144

    //key key_val 要检索字段

 

145

    if(key.empty() || key_val.empty() || in.size()<=0){

146

        return RET_PARERR;

 

147

    }

148

    BSONObjBuilder b;

 

149

    for(vector<string>::iterator iter=in.begin();iter!=in.end();++iter){

150

        b.append(*iter,1);

 

151

    }

152

 

 

153

    sem_wait(&_jobsem);

154

    pthread_mutex_lock(&_jobmux);

 

155

    map<DBClientConnection*,bool>::iterator it=_joblst.begin();

156

    while(it!=_joblst.end()){

 

157

        if(it->second == false){

158

            it->second=true;

 

159

            break;

160

        }

 

161

        it++;

162

    }

 

163

    pthread_mutex_unlock(&_jobmux);

164

    BSONObj ob=b.obj();

 

165

 

166

    BSONObj p=it->first->findOne(doc,QUERY(key<<key_val),&ob);

 

167

 

168

    map<string,string> temp;

 

169

    for(vector<string>::iterator iter=in.begin();iter!=in.end();++iter){

170

        string mkey=*iter;

 

171

        temp[*iter]=p.getStringField(mkey.c_str());

172

    }

 

173

    out=temp;

174

 

 

175

    pthread_mutex_lock(&_jobmux);

176

    it->second=false;

 

177

    pthread_mutex_unlock(&_jobmux);

178

    sem_post(&_jobsem);

 

179

 

180

    return RET_OK;

 

181

}

182

//查询key为key的一批数据的 某些字段

 

183

//fields为要查询的字段集

184

//key="id" 值为in 一批key

 

185

//返回key->map<key,value>

186

int cmongo::gets(map< string,map<string,string> >& rout,vector<string> fields,vector<string> in,string key){

 

187

    if(key.empty()){

188

        return RET_PARERR;

 

189

    }

190

    sem_wait(&_jobsem);

 

191

    pthread_mutex_lock(&_jobmux);

192

    map<DBClientConnection*,bool>::iterator it=_joblst.begin();

 

193

    while(it!=_joblst.end()){

194

        if(it->second == false){

 

195

            it->second=true;

196

            break;

 

197

        }

198

        it++;

 

199

    }

200

    pthread_mutex_unlock(&_jobmux);

 

201

 

202

    BSONObjBuilder b;

 

203

    b.append(key,1);

204

    for(vector<string>::iterator iter=fields.begin();iter!=fields.end();++iter){

 

205

        b.append(*iter,1);

206

    }

 

207

 

208

    BSONObj p=b.obj();

 

209

    for(vector<string>::iterator iter2=in.begin();iter2!=in.end();++iter2){

210

        BSONObj ob=it->first->findOne(doc,QUERY(key<<*iter2),&p);

 

211

        map<string,string> temp;

212

        for(vector<string>::iterator iter=fields.begin();iter!=fields.end();++iter){

 

213

            string mkey=*iter;

214

            temp[*iter]=ob.getStringField(mkey.c_str());   

 

215

        }

216

        rout[ob.getStringField(key.c_str())]=temp;

 

217

    }

218

 

 

219

    pthread_mutex_lock(&_jobmux);

220

    it->second=false;

 

221

    pthread_mutex_unlock(&_jobmux);

222

    sem_post(&_jobsem);

 

223

 

224

    return RET_OK;

 

225

}

226

//dumpkey key-value 返回 key对应的val值

 

227

//key val

228

int cmongo::dumpkey(map< string,string >& rout,string key,string val){

 

229

    if(key.empty()){

230

        return RET_PARERR;

 

231

    }

232

    sem_wait(&_jobsem);

 

233

    pthread_mutex_lock(&_jobmux);

234

    map<DBClientConnection*,bool>::iterator it=_joblst.begin();

 

235

    while(it!=_joblst.end()){

236

        if(it->second == false){

 

237

            it->second=true;

238

            break;

 

239

        }

240

        it++;

 

241

    }

242

    pthread_mutex_unlock(&_jobmux);

 

243

 

244

    BSONObjBuilder b;

 

245

    b.append(key,1);

246

    if(!val.empty()){

 

247

        b.append(val,1);

248

    }

 

249

 

250

    BSONObj p=b.obj();

 

251

 

252

    pthread_mutex_lock(&_dbmux);

 

253

    auto_ptr<DBClientCursor> cursor = it->first->query(doc,Query(),0,0,&p);

254

    while(cursor->more()){

 

255

        BSONObj ob=cursor->next();

256

        rout[ob.getStringField(key.c_str())]=ob.getStringField(val.c_str());

 

257

    }

258

    pthread_mutex_unlock(&_dbmux);

 

259

 

260

    pthread_mutex_lock(&_jobmux);

 

261

    it->second=false;

262

    pthread_mutex_unlock(&_jobmux);

 

263

    sem_post(&_jobsem);

264

 

 

265

    return RET_OK;

266

}

 

267

//dumpkey key对应多个value

268

//key->map<key,value>.

 

269

//其实dumpvals接口完全可以包含dumpkey,为了方便运用独立出来

270

//out 返回的key 对应的map<key,value>

 

271

//in 每个key需要对应的返回哪些字段

272

//key="id"

 

273

int cmongo::dumpvals(map< string,map<string,string> >& rout,vector<string> in,string key){

274

    if(key.empty()){

 

275

        return RET_PARERR;

276

    }

 

277

    sem_wait(&_jobsem);

278

    pthread_mutex_lock(&_jobmux);

 

279

    map<DBClientConnection*,bool>::iterator it=_joblst.begin();

280

    while(it!=_joblst.end()){

 

281

        if(it->second == false){

282

            it->second=true;

 

283

            break;

284

        }

 

285

        it++;

286

    }

 

287

    pthread_mutex_unlock(&_jobmux);

288

 

 

289

    BSONObjBuilder b;

290

    b.append(key,1);

 

291

    for(vector<string>::iterator iter=in.begin();iter!=in.end();++iter){

292

        b.append(*iter,1);

 

293

    }

294

 

 

295

    BSONObj p=b.obj();

296

 

 

297

    pthread_mutex_lock(&_dbmux);

298

    auto_ptr<DBClientCursor> cursor = it->first->query(doc,Query(),0,0,&p);

 

299

    while(cursor->more()){

300

        BSONObj ob=cursor->next();

 

301

        map<string,string> temp;

302

        for(vector<string>::iterator iter=in.begin();iter!=in.end();++iter){

 

303

            string val=*iter;

304

            temp[val]=ob.getStringField(val.c_str());

 

305

        }

306

        rout[ob.getStringField(key.c_str())]=temp;

 

307

        temp.clear();

308

    }

 

309

    pthread_mutex_unlock(&_dbmux);

310

 

 

311

    pthread_mutex_lock(&_jobmux);

312

    it->second=false;

 

313

    pthread_mutex_unlock(&_jobmux);

314

    sem_post(&_jobsem);

 

315

 

316

    return RET_OK;

 

317

}

318

//更新接口,暂不支持key对应多条记录的更新

 

319

int cmongo::set(map<string,string> in,string key,string key_val){

320

    //如果map没有数据,返回参数错误

 

321

    if(in.size()<=0 || key.empty() || key_val.empty()){

322

        return RET_PARERR;

 

323

    }

324

    BSONObjBuilder b;

 

325

    map<string,string>::iterator iter;

326

    for(iter=in.begin();iter!=in.end();++iter){

 

327

        b.append(iter->first,iter->second);

328

    }

 

329

     

330

    sem_wait(&_jobsem);

 

331

    pthread_mutex_lock(&_jobmux);

332

    map<DBClientConnection*,bool>::iterator it=_joblst.begin();

 

333

    while(it!=_joblst.end()){

334

        if(it->second == false){

 

335

            it->second=true;

336

            break;

 

337

        }

338

        it++;

 

339

    }

340

    pthread_mutex_unlock(&_jobmux);

 

341

    BSONObj ob=b.obj();

342

    it->first->update(doc,QUERY(key<<key_val),BSON("$set"<<ob),true);

 

343

 

344

    int ret=RET_OK;

 

345

    string errmsg=it->first->getLastError();

346

    if(!errmsg.empty()){

 

347

        ret=RET_ERR;

348

    }

 

349

 

350

    pthread_mutex_lock(&_jobmux);

 

351

    it->second=false;

352

    pthread_mutex_unlock(&_jobmux);

 

353

    sem_post(&_jobsem);

354

 

 

355

    return ret;

356

}

 

357

//更新接口,批量更新key="id"

358

//  "123456":<key,value>,<key,value>

 

359

//  "123457":<key,value>,<key,value>

360

int cmongo::sets(map< string,map<string,string> > in,string key){

 

361

    //如果map没有数据,返回参数错误

362

    if(in.size()<=0 || key.empty() ){

 

363

        return RET_PARERR;

364

    }

 

365

 

366

    sem_wait(&_jobsem);

 

367

    pthread_mutex_lock(&_jobmux);

368

    map<DBClientConnection*,bool>::iterator it=_joblst.begin();

 

369

    while(it!=_joblst.end()){

370

        if(it->second == false){

 

371

            it->second=true;

372

            break;

 

373

        }

374

        it++;

 

375

    }

376

    pthread_mutex_unlock(&_jobmux);

 

377

 

378

    int ret=RET_OK;

 

379

    map< string,map<string,string> >::iterator iter;

380

    for(iter=in.begin();iter!=in.end();++iter){

 

381

        BSONObjBuilder b;

382

        for(map<string,string>::iterator iter2=iter->second.begin();iter2!=iter->second.end();++iter2){

 

383

            b.append(iter2->first,iter2->second);

384

        }

 

385

        BSONObj ob=b.obj();

386

        it->first->update(doc,QUERY(key<<iter->first),BSON("$set"<<ob),true);

 

387

        string errmsg=it->first->getLastError();

388

        if(!errmsg.empty()){

 

389

            ret=RET_ERR;

390

        }

 

391

    }

392

     

 

393

 

394

    pthread_mutex_lock(&_jobmux);

 

395

    it->second=false;

396

    pthread_mutex_unlock(&_jobmux);

 

397

    sem_post(&_jobsem);

398

 

 

399

    return ret;

400

}

 

401

//删除接口,删除记录 key=id key_val=587.即删除id="587"的记录

402

int cmongo::remove(string key,string key_val){

 

403

 

404

    if(key.empty() || key_val.empty()){

 

405

        return RET_PARERR;

406

    }

 

407

    sem_wait(&_jobsem);

408

    pthread_mutex_lock(&_jobmux);

 

409

    map<DBClientConnection*,bool>::iterator it=_joblst.begin();

410

    while(it!=_joblst.end()){

 

411

        if(it->second == false){

412

            it->second=true;

 

413

            break;

414

        }

 

415

        it++;

416

    }

 

417

    pthread_mutex_unlock(&_jobmux);

418

 

 

419

    it->first->remove(doc,BSON(key << key_val));

420

 

 

421

    pthread_mutex_lock(&_jobmux);

422

    it->second=false;

 

423

    pthread_mutex_unlock(&_jobmux);

424

    sem_post(&_jobsem);

 

425

 

426

    return RET_OK;

 

427

}

 


最近重构并优化了一套后端服务的代码: 1. 设计并开发高效的C++对象池算法,时间复杂度为 O(1) 在整个重构框架中,对象池是负责管理内存的底层基本模块 2. 利用命令模式的思想开发 Redis 子模块 抽象出方便高效的接口提供给上层程序员使用 3. 利用组合模式和装饰模式的思想开发 MongoDB 数据库查询条件装饰器 将查询条件和数据库 MongodbModule 数据模型进行解耦合 4. 抽象出一套 MongoDB Module 结果集接口 通过模板和特化技术实现 string/int 等不同索引型的结果集 5. 开发 AbstractMongodbModule 处理通用的 MongoDB 数据库表数据操作 数据库中不同的表都有自己的 AbstractMongodbModule 子对应 6. 用 Perl 开发自动代码生成器,上层程序员对照数据库表结构写 .tmpl 配置文件, 自动生成该数据库表的 MongodbModule 子,减轻程序员新增表时的工作量 7. 结合 Redis 模块和 MongoDB 模块,开发 HierarchicalModule 分层数据模型 构造一个 Redis 缓存层 + MongoDB 持久层的后台 Server 架构 并通过简单方便的接口供上层程序员使用,具体的数据分层处理对上层程序员是黑盒的 8. 设计并开发整套缓存层使用的 KEY 规则,方便缓存更新 结合公司的数据订阅系统进行 Redis缓存层 + MongoDB 持久层数据更新功能 9. 重构后的分层数据架构比原有接口效率提高 5 - 400 倍(返回数据记录条数从 150 - 5 条) 绝大部分时间后端接口需要获取记录个数在 50 以内,所以效率提升在 100 倍左右
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值