0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

Faster $box queries SERVER-1392

This commit is contained in:
Mathias Stearn 2010-10-18 14:33:24 -04:00
parent fd21745be1
commit b902ee4046

View File

@ -1419,7 +1419,7 @@ namespace mongo {
_want._min = Point( _g , _bl );
_want._max = Point( _g , _tr );
uassert( 13064 , "need an area > 0 " , _want.area() > 0 );
_state = START;
@ -1430,12 +1430,14 @@ namespace mongo {
GEODEBUG( "center : " << center.toString() << "\t" << _prefix );
{
GeoHash a(0LL,32);
GeoHash b(0LL,32);
b.move(1,1);
_fudge = _g->distance(a,b);
}
{
GeoHash a(0LL,32);
GeoHash b(0LL,32);
b.move(1,1);
_fudge = _g->distance(a,b);
}
_wantLen = _fudge + std::max((_want._max._x - _want._min._x), (_want._max._y - _want._min._y));
ok();
}
@ -1470,32 +1472,47 @@ namespace mongo {
_state = DONE;
return;
}
Box cur( _g , _prefix );
if ( cur._min._x + _fudge < _want._min._x &&
cur._min._y + _fudge < _want._min._y &&
cur._max._x - _fudge > _want._max._x &&
cur._max._y - _fudge > _want._max._y ){
_state = DONE;
GeoHash temp = _prefix.commonPrefix( cur._max.hash( _g ) );
GEODEBUG( "box done : " << cur.toString() << " prefix:" << _prefix << " common:" << temp );
if ( temp == _prefix )
return;
_prefix = temp;
GEODEBUG( "\t one more loop" );
continue;
}
else {
if (_g->sizeEdge(_prefix) < _wantLen){
_prefix = _prefix.up();
} else {
for (int i=-1; i<=1; i++){
for (int j=-1; j<=1; j++){
if (i == 0 && j == 0)
continue; // main box
GeoHash newBox = _prefix;
newBox.move(i, j);
PREFIXDEBUG(newBox, _g);
Box cur( _g , newBox );
if (_want.intersects(cur)){
// TODO consider splitting into quadrants
getPointsForPrefix(newBox);
} else {
GEODEBUG("skipping box");
}
}
}
_state = DONE;
}
}
return;
}
}
void getPointsForPrefix(const GeoHash& prefix){
if ( ! BtreeLocation::initial( *_id , _spec , _min , _max , prefix , _found , this ) ){
return;
}
while ( _min.hasPrefix( prefix ) && _min.advance( -1 , _found , this ) );
while ( _max.hasPrefix( prefix ) && _max.advance( 1 , _found , this ) );
}
virtual bool checkDistance( const GeoHash& h , double& d ){
bool res = _want.inside( Point( _g , h ) , _fudge );
@ -1508,6 +1525,7 @@ namespace mongo {
GeoHash _bl;
GeoHash _tr;
Box _want;
double _wantLen;
int _found;