设为首页 收藏本站
查看: 887|回复: 0

[经验分享] 非侵入式mongodb async find patch

[复制链接]

尚未签到

发表于 2016-12-2 10:11:24 | 显示全部楼层 |阅读模式
  前阵子为mongodb的cdriver添加了一个async find补丁, 不过简陋的将源码插入其中.. , 觉得怎么看怎么别扭... 如果官方更新了... 就容易悲剧了, 所以, 为了自己不用老是跟着改动, 就单独的将patch分离出来, 没什么技术含量, 仅仅作为记录.
  mongo_async.h
  //base info: create by final/*effect: mongo db async query patch***/#ifndef _MONGO_ASYNC_H_#define _MONGO_ASYNC_H_#include "mongo.h"typedef int (*mongo_async_send_handler)(const char* pbuf, size_t len, void* arg);// async mongo find interface, the param id is the callback param#define MONGO_ASYNC_READ_HEAD_LEN   (sizeof(mongo_header) + sizeof(mongo_reply_fields))void    mongo_async_init(mongo_async_send_handler pfunc);int     mongo_async_find(mongo_connection* conn, const char* ns, const bson* query, bson* fields, int nToReturn, int nToSkip, int options, int id, void* arg);mongo_cursor* mongo_async_response(mongo_connection* conn, const char* ns, mongo_reply* mm);mongo_reply * mongo_read_async_response_head(mongo_connection* conn, const char* buf, int* data_len/*out*/, int* query_id/*out*/);  // buf size must be MONGO_ASYNC_READ_HEAD_LEN and return left data lenmongo_reply* mongo_read_async_response_data(mongo_connection* conn, mongo_reply* out, const char* buf);#endif
  mongo_async.c
  //base info: create by hyz//effect: mongo db async patch#include <stdio.h>#include <stdlib.h>#include <string.h>#include "mongo_async.h"//TODO...extern mongo_message * mongo_message_create( int len , int id , int responseTo , int op );extern char * mongo_data_append( char * start , const void * data , int len );extern char * mongo_data_append32( char * start , const void * data);static mongo_async_send_handler async_handler = NULL; staticint mongo_message_async_send(mongo_connection* conn, mongo_message* mm, void* arg){mongo_header head; /* little endian */bson_little_endian32(&head.len, &mm->head.len);bson_little_endian32(&head.id, &mm->head.id);bson_little_endian32(&head.responseTo, &mm->head.responseTo);bson_little_endian32(&head.op, &mm->head.op);MONGO_TRY{if( async_handler((char*)&head, sizeof(head), arg) ){free(mm);return 1;}   if( async_handler((char*)&mm->data, mm->head.len - sizeof(head), arg) ){free(mm);return 1;}   }MONGO_CATCH{free(mm);MONGO_RETHROW();}free(mm);return 0;}void mongo_async_init(mongo_async_send_handler pfunc){if( !pfunc ){printf("mongodb async init failed/n");exit(-5);}async_handler = pfunc;}// async mongo find // note: the id must not be zero or mongo_message_create will call rand() to generateint mongo_async_find(mongo_connection* conn, const char* ns, const bson* query, bson* fields, int nToReturn, int nToSkip, int options, int id, void* arg){char * data;mongo_message * mm = mongo_message_create( 16 + /* header */4 + /*  options */strlen( ns ) + 1 + /* ns */4 + 4 + /* skip,return */bson_size( query ) +bson_size( fields ) ,id , 0 , mongo_op_query );data = &mm->data;data = mongo_data_append32( data , &options );data = mongo_data_append( data , ns , strlen( ns ) + 1 );data = mongo_data_append32( data , &nToSkip );data = mongo_data_append32( data , &nToReturn );data = mongo_data_append( data , query->data , bson_size( query ) );if ( fields )data = mongo_data_append( data , fields->data , bson_size( fields ) );bson_fatal_msg( (data == ((char*)mm) + mm->head.len), "query building fail!" );return mongo_message_async_send(conn, mm, arg);}// buf len must be >= MONGO_ASYNC_READ_HEAD_LENmongo_reply * mongo_read_async_response_head(mongo_connection* conn, const char* buf, int* data_len/*out*/, int* query_id/*out*/ ){mongo_header head; /* header from network */mongo_reply_fields fields; /* header from network */mongo_reply * out; /* native endian */int len;memcpy(&head, buf, sizeof(head));memcpy(&fields, buf + sizeof(head), sizeof(fields));bson_little_endian32(&len, &head.len);if (len < sizeof(head)+sizeof(fields) || len > 64*1024*1024)MONGO_THROW(MONGO_EXCEPT_NETWORK); /* most likely corruption */out = (mongo_reply*)bson_malloc(len);out->head.len = len;bson_little_endian32(&out->head.id, &head.id);bson_little_endian32(&out->head.responseTo, &head.responseTo);bson_little_endian32(&out->head.op, &head.op);bson_little_endian32(&out->fields.flag, &fields.flag);bson_little_endian64(&out->fields.cursorID, &fields.cursorID);bson_little_endian32(&out->fields.start, &fields.start);bson_little_endian32(&out->fields.num, &fields.num);*data_len = out->head.len - MONGO_ASYNC_READ_HEAD_LEN;*query_id = out->head.responseTo;return out;}// read response datamongo_reply* mongo_read_async_response_data(mongo_connection* conn, mongo_reply* out, const char* buf){int len = out->head.len;MONGO_TRY{memcpy(&out->objs, buf, len - MONGO_ASYNC_READ_HEAD_LEN);}MONGO_CATCH{free(out);MONGO_RETHROW();}return out;}mongo_cursor* mongo_async_response(mongo_connection* conn, const char* ns, mongo_reply* mm){int sl;volatile mongo_cursor * cursor; /* volatile due to longjmp in mongo exception handler */cursor = (mongo_cursor*)bson_malloc(sizeof(mongo_cursor));MONGO_TRY{cursor->mm = mm;}MONGO_CATCH{free((mongo_cursor*)cursor); /* cast away volatile, not changing type */MONGO_RETHROW();}sl = strlen(ns)+1;cursor->ns = bson_malloc(sl);if (!cursor->ns){free(cursor->mm);free((mongo_cursor*)cursor); /* cast away volatile, not changing type */return 0;}memcpy((void*)cursor->ns, ns, sl); /* cast needed to silence GCC warning */cursor->conn = conn;cursor->current.data = NULL;return (mongo_cursor*)cursor;}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-308586-1-1.html 上篇帖子: 非侵入式mongodb async find patch 下篇帖子: mongodb 系统(安装)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表