elim dups

This commit is contained in:
Dwight 2007-11-24 16:15:09 -05:00
parent 31311aeb81
commit ace493f36f
5 changed files with 40 additions and 11 deletions

View File

@ -182,7 +182,9 @@ JSMatcher::JSMatcher(JSObj &_jsobj) :
}
}
bool JSMatcher::matches(JSObj& jsobj) {
bool JSMatcher::matches(JSObj& jsobj, bool *deep) {
if( deep )
*deep = false;
/* assuming there is usually only one thing to match. if more this
could be slow sometimes. */
@ -214,8 +216,11 @@ bool JSMatcher::matches(JSObj& jsobj) {
if( e.type() == Array && strcmp(e.fieldName(), m.fieldName()) == 0 ) {
JSElemIter ai(e.embeddedObject());
while( ai.more() ) {
if( ai.next().valuesEqual(m) )
if( ai.next().valuesEqual(m) ) {
if( deep )
*deep = true;
goto ok;
}
}
}
}

View File

@ -329,7 +329,7 @@ class JSMatcher {
public:
JSMatcher(JSObj& pattern);
bool matches(JSObj& j);
bool matches(JSObj& j, bool *deep = 0);
private:
JSObj& jsobj;
vector<Element> toMatch;

View File

@ -207,6 +207,16 @@ public:
/* called before query getmore block is iterated */
virtual void checkLocation() { }
/* used for multikey index traversal to avoid sending back dups. see JSMatcher::matches() */
set<DiskLoc> dups;
bool dup(DiskLoc loc) {
/* to save mem only call this when there is risk of dups (e.g. when 'deep'/multikey) */
if( dups.count(loc) > 0 )
return true;
dups.insert(loc);
return false;
}
};
class BasicCursor : public Cursor {

View File

@ -72,11 +72,13 @@ void deleteObjects(const char *ns, JSObj pattern, bool justOne) {
DiskLoc rloc = c->currLoc();
c->advance(); // must advance before deleting as the next ptr will die
JSObj js(r);
if( !matcher.matches(js) ) {
bool deep;
if( !matcher.matches(js, &deep) ) {
if( c->tempStopOnMiss() )
break;
}
else {
else {
assert( !deep || !c->dup(rloc) ); // can't be a dup, we deleted it!
cout << " found match to delete" << endl;
if( !justOne )
c->noteLocation();
@ -111,6 +113,10 @@ void updateObjects(const char *ns, JSObj updateobj, JSObj pattern, bool upsert)
break;
}
else {
/* note: we only update one row and quit. if you do multiple later,
be careful or multikeys in arrays could break things badly. best
to only allow updating a single row with a multikey lookup.
*/
cout << " found match to update" << endl;
theDataFileMgr.update(ns, r, c->currLoc(), updateobj.objdata(), updateobj.objsize());
return;
@ -155,11 +161,12 @@ QueryResult* runQuery(const char *ns, int ntoreturn, JSObj jsobj, auto_ptr< set<
long long cursorid = 0;
while( c->ok() ) {
JSObj js = c->current();
if( !matcher->matches(js) ) {
bool deep;
if( !matcher->matches(js, &deep) ) {
if( c->tempStopOnMiss() )
break;
}
else {
else if( !deep || !c->dup(c->currLoc()) ) {
bool ok = true;
if( filter.get() ) {
JSObj x;
@ -244,11 +251,12 @@ done:
break;
}
JSObj js = c->current();
if( !cc->matcher->matches(js) ) {
bool deep;
if( !cc->matcher->matches(js, &deep) ) {
if( c->tempStopOnMiss() )
goto done;
}
else {
else if( !deep || !c->dup(c->currLoc()) ) {
bool ok = true;
if( cc->filter.get() ) {
JSObj x;

View File

@ -2,8 +2,10 @@
#pragma once
const bool dumpIP = false;
const bool dumpBytesDetailed = false;
/* packet dumping level of detail. */
const bool dumpPackets = false; // this must be true to get anything at all
const bool dumpIP = false; // output the ip address
const bool dumpBytesDetailed = false; // more data output
#include "message.h"
@ -46,6 +48,8 @@ struct Fragment {
#pragma pack(pop)
inline void DUMP(Fragment& f, SockAddr& t, const char *tabs) {
if( !dumpPackets )
return;
cout << tabs << curTimeMillis() % 10000 << ' ';
short s = f.fragmentNo;
if( s == -32768 )
@ -64,6 +68,8 @@ inline void DUMP(Fragment& f, SockAddr& t, const char *tabs) {
}
inline void DUMPDATA(Fragment& f, const char *tabs) {
if( !dumpPackets )
return;
if( f.fragmentNo >= 0 ) {
cout << '\n' << tabs;
int x = f.fragmentDataLen();