cursors
This commit is contained in:
97
db/query.cpp
97
db/query.cpp
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user