This commit is contained in:
Dwight 2007-11-04 16:17:44 -05:00
parent 78bba21722
commit 94b2fe996f
5 changed files with 131 additions and 18 deletions

View File

@ -56,6 +56,13 @@ public:
nextjsobj += 4;
return i;
}
long long pullInt64() {
if( nextjsobj == data )
nextjsobj += strlen(data) + 1; // skip namespace
long long i = *((long long *)nextjsobj);
nextjsobj += 8;
return i;
}
OID* getOID() {
return (OID *) (data + strlen(data) + 1); // skip namespace
@ -135,7 +142,6 @@ void receivedDelete(Message& m) {
void receivedQuery(Message& m) {
DbMessage d(m);
const char *ns = d.getns();
int ntoreturn = d.pullInt();
assert( d.moreJSObjs() );
@ -145,6 +151,17 @@ void receivedQuery(Message& m) {
dbMsgPort.reply(m, resp);
}
void receivedGetMore(Message& m) {
DbMessage d(m);
const char *ns = d.getns();
int ntoreturn = d.pullInt();
long long cursorid = d.pullInt64();
QueryResult* msgdata = getMore(ns, ntoreturn, cursorid);
Message resp;
resp.setData(msgdata, true);
dbMsgPort.reply(m, resp);
}
/*void getbyoid(Message& m) {
DbMessage d(m);
Record *r = findByOID(d.getns(), d.getOID());

Binary file not shown.

View File

@ -91,19 +91,16 @@ JSMatcher::JSMatcher(JSObj &_jsobj) :
struct RXTest {
RXTest() {
// pcre_compile(0, 0, 0, 0, 0);
//pcre_compile(const char *, int, const char **, int *,
// const unsigned char *);
/*
/*
static const boost::regex e("(\\d{4}[- ]){3}\\d{4}");
static const boost::regex b(".....");
cout << "regex result: " << regex_match("hello", e) << endl;
cout << "regex result: " << regex_match("abcoo", b) << endl;
*/
pcrecpp::RE re("h.*o");
cout << "regex test: " << re.FullMatch("hello") << endl;
cout << "regex test: " << re.FullMatch("blah") << endl;
*/
pcrecpp::RE re1(")({a}h.*o");
pcrecpp::RE re("h.llo");
assert( re.FullMatch("hello") );
assert( !re1.FullMatch("hello") );
}
} rxtest;

View File

@ -5,6 +5,7 @@
#include "pdfile.h"
#include "jsobj.h"
#include "../util/builder.h"
#include <time.h>
int nextCursorId = 1;
@ -65,13 +66,28 @@ void updateObjects(const char *ns, JSObj updateobj, JSObj pattern, bool upsert)
theDataFileMgr.insert(ns, (void*) updateobj.objdata(), updateobj.objsize());
}
typedef map<long long, ClientCursor*> CCMap;
CCMap clientCursors;
long long allocCursorId() {
long long x;
while( 1 ) {
x = (((long long)rand()) << 32);
x = x | time(0);
if( clientCursors.count(x) == 0 )
break;
}
return x;
}
QueryResult* runQuery(const char *ns, int ntoreturn, JSObj jsobj) {
cout << "runQuery ns:" << ns << " ntoreturn:" << ntoreturn << " queryobjsize:" <<
jsobj.objsize() << endl;
BufBuilder b;
JSMatcher matcher(jsobj);
auto_ptr<JSMatcher> matcher(new JSMatcher(jsobj));
QueryResult *qr = 0;
b.skip(sizeof(QueryResult));
@ -79,17 +95,28 @@ QueryResult* runQuery(const char *ns, int ntoreturn, JSObj jsobj) {
int n = 0;
auto_ptr<Cursor> c =
// strcmp(ns, "system.namespaces") == 0 ?
// makeNamespaceCursor() :
// strcmp(ns, "system.namespaces") == 0 ?
// makeNamespaceCursor() :
theDataFileMgr.findAll(ns);
long long cursorid = 0;
while( c->ok() ) {
JSObj js = c->current();
if( matcher.matches(js) ) {
if( matcher->matches(js) ) {
b.append((void*) js.objdata(), js.objsize());
n++;
if( n >= ntoreturn && ntoreturn != 0 )
if( n >= ntoreturn && ntoreturn != 0 ) {
// more...so save a cursor
ClientCursor *cc = new ClientCursor();
cc->c = c;
cursorid = allocCursorId();
cc->cursorid = cursorid;
cc->matcher = matcher;
cc->ns = ns;
cc->pos = n;
clientCursors[cursorid] = cc;
break;
}
}
c->advance();
}
@ -98,10 +125,68 @@ QueryResult* runQuery(const char *ns, int ntoreturn, JSObj jsobj) {
qr->len = b.len();
qr->reserved = 0;
qr->operation = opReply;
qr->cursorId = 0; //nextCursorId++;
qr->cursorId = cursorid;
qr->startingFrom = 0;
qr->nReturned = n;
b.decouple();
return qr;
}
QueryResult* getMore(const char *ns, int ntoreturn, long long cursorid) {
cout << "getMore ns:" << ns << " ntoreturn:" << ntoreturn << " cursorid:" <<
cursorid << endl;
BufBuilder b;
ClientCursor *cc = 0;
CCMap::iterator it = clientCursors.find(cursorid);
if( it == clientCursors.end() ) {
cout << "Cursor not found in map. cursorid: " << cursorid << endl;
}
else {
cc = it->second;
}
b.skip(sizeof(QueryResult));
int start = 0;
int n = 0;
if( cc ) {
start = cc->pos;
Cursor *c = cc->c.get();
while( 1 ) {
if( !c->ok() ) {
// done! kill cursor.
cursorid = 0;
clientCursors.erase(it);
delete cc;
cc = 0;
break;
}
JSObj js = c->current();
if( cc->matcher->matches(js) ) {
b.append((void*) js.objdata(), js.objsize());
n++;
if( n >= ntoreturn && ntoreturn != 0 ) {
cc->pos += n;
break;
}
}
}
c->advance();
}
QueryResult *qr = (QueryResult *) b.buf();
qr->cursorId = cursorid;
qr->startingFrom = start;
qr->len = b.len();
qr->reserved = 0;
qr->operation = opReply;
qr->nReturned = n;
b.decouple();
return qr;
}

View File

@ -25,9 +25,10 @@
int nToReturn; // how many you want back as the beginning of the cursor data
JSObject query;
dbGetMore:
int reserved;;
int64 cursorID;
int reserved;
string collection; // redundant, might use for security.
int nToReturn;
int64 cursorID;
Note that on Update, there is only one object, which is different
from insert where you can pass a list of objects to insert in the db.
@ -51,7 +52,20 @@ struct QueryResult : public MsgData {
const char *data() { return (char *) (((int *)&nReturned)+1); }
};
QueryResult* getMore(const char *ns, int ntoreturn, long long cursorid);
QueryResult* runQuery(const char *ns, int ntoreturn, JSObj);
void updateObjects(const char *ns, JSObj updateobj, JSObj pattern, bool upsert);
void deleteObjects(const char *ns, JSObj pattern, bool justOne);
class Cursor;
class ClientCursor {
public:
ClientCursor() { cursorid=0; pos=0; }
long long cursorid;
string ns;
auto_ptr<JSMatcher> matcher;
auto_ptr<Cursor> c;
int pos;
};