mirror of https://github.com/mongodb/mongo
elim dups
This commit is contained in:
parent
31311aeb81
commit
ace493f36f
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
10
db/pdfile.h
10
db/pdfile.h
|
|
@ -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 {
|
||||
|
|
|
|||
20
db/query.cpp
20
db/query.cpp
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue