mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
SERVER-802 some optimizations
This commit is contained in:
parent
326babfe6d
commit
5e2fa26dd7
@ -63,8 +63,9 @@ namespace mongo {
|
||||
audit();
|
||||
startKey = bounds_->startKey();
|
||||
bool found;
|
||||
_boundsIterator->advance( startKey ); // handles initialization
|
||||
bucket = indexDetails.head.btree()->
|
||||
locate(indexDetails, indexDetails.head, startKey, _ordering, keyOfs, found, direction > 0 ? minDiskLoc : maxDiskLoc, direction);
|
||||
locate(indexDetails, indexDetails.head, startKey, _ordering, keyOfs, found, direction > 0 ? minDiskLoc : maxDiskLoc, direction);
|
||||
skipAndCheck();
|
||||
DEV assert( dups.size() == 0 );
|
||||
}
|
||||
@ -165,16 +166,6 @@ namespace mongo {
|
||||
}
|
||||
|
||||
void BtreeCursor::advanceTo( const BSONObj &keyBegin, int keyBeginLen, const vector< const BSONElement * > &keyEnd) {
|
||||
// log() << "curr: " << currKey() << ", advancing to: ";
|
||||
// BSONObjIterator boi( keyBegin );
|
||||
// int i;
|
||||
// for( i = 0; i < keyBeginLen; ++i ) {
|
||||
// log() << ", " << boi.next();
|
||||
// }
|
||||
// for( ;i < (int)keyEnd.size(); ++i ) {
|
||||
// log() << ", " << *keyEnd[ i ];
|
||||
// }
|
||||
// log() << endl;
|
||||
bucket.btree()->advanceTo( indexDetails, bucket, keyOfs, keyBegin, keyBeginLen, keyEnd, _ordering, direction );
|
||||
}
|
||||
|
||||
|
100
db/queryutil.cpp
100
db/queryutil.cpp
@ -932,6 +932,11 @@ namespace mongo {
|
||||
}
|
||||
|
||||
bool FieldRangeVector::matchesElement( const BSONElement &e, int i, bool forward ) const {
|
||||
int l = matchingLowElement( e, i, forward );
|
||||
return ( l % 2 == 0 ); // if we're inside an interval
|
||||
}
|
||||
|
||||
int FieldRangeVector::matchingLowElement( const BSONElement &e, int i, bool forward ) const {
|
||||
int l = -1;
|
||||
int h = _ranges[ i ].intervals().size() * 2;
|
||||
while( l + 1 < h ) {
|
||||
@ -951,11 +956,11 @@ namespace mongo {
|
||||
} else if ( cmp > 0 ) {
|
||||
h = m;
|
||||
} else {
|
||||
return true;
|
||||
return ( m % 2 == 0 ) ? m : m - 1;
|
||||
}
|
||||
}
|
||||
assert( l + 1 == h );
|
||||
return ( l % 2 == 0 ); // if we're inside an interval
|
||||
return l;
|
||||
}
|
||||
|
||||
bool FieldRangeVector::matches( const BSONObj &obj ) const {
|
||||
@ -966,7 +971,7 @@ namespace mongo {
|
||||
}
|
||||
BSONElement kk = k.next();
|
||||
int number = (int) kk.number();
|
||||
bool forward = ( ( number >= 0 ? 1 : -1 ) * ( _direction >= 0 ? 1 : -1 ) > 0 );
|
||||
bool forward = ( ( number >= 0 ? 1 : -1 ) * ( _direction >= 0 ? 1 : -1 ) > 0 ) >= 0;
|
||||
BSONElement e = obj.getField( kk.fieldName() );
|
||||
if ( e.eoo() ) {
|
||||
e = staticNull.firstElement();
|
||||
@ -990,53 +995,88 @@ namespace mongo {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO optimize more
|
||||
int FieldRangeVector::Iterator::advance( const BSONObj &curr ) {
|
||||
BSONObjIterator j( curr );
|
||||
BSONObjIterator o( _v._keyPattern );
|
||||
int latestNonEndpoint = -1;
|
||||
// log() << "direction: " << _v._direction << endl;
|
||||
// log() << "curr: " << curr << endl;
|
||||
// log() << "query: " << _v._queries[ 0 ] << endl;
|
||||
for( int i = 0; i < (int)_i.size(); ++i ) {
|
||||
// log() << "a i: " << i << endl;
|
||||
if ( i > 0 && !_v._ranges[ i - 1 ].intervals()[ _i[ i - 1 ] ].equality() ) {
|
||||
// TODO if possible avoid this certain cases when field in prev key is the same
|
||||
setMinus( i );
|
||||
}
|
||||
bool eq = false;
|
||||
BSONElement jj = j.next();
|
||||
BSONElement oo = o.next();
|
||||
while( _i[ i ] < (int)_v._ranges[ i ].intervals().size() ) {
|
||||
// cout << "a _i[ i ]: " << _i[ i ] << endl;
|
||||
// cout << "lower: " << _v._ranges[ i ].intervals()[ _i[ i ] ]._lower._bound << endl;
|
||||
// cout << "upper: " << _v._ranges[ i ].intervals()[ _i[ i ] ]._upper._bound << endl;
|
||||
int x = _v._ranges[ i ].intervals()[ _i[ i ] ]._lower._bound.woCompare( jj, false );
|
||||
if ( ( oo.number() < 0 ) ^ ( _v._direction < 0 ) ) {
|
||||
x = -x;
|
||||
}
|
||||
// cout << "x: " << x << endl;
|
||||
if ( x > 0 ) {
|
||||
setZero( i + 1 );
|
||||
bool reverse = ( ( oo.number() < 0 ) ^ ( _v._direction < 0 ) );
|
||||
BSONElement jj = j.next();
|
||||
if ( _i[ i ] == -1 ) {
|
||||
int l = _v.matchingLowElement( jj, i, !reverse );
|
||||
if ( l % 2 == 0 ) {
|
||||
_i[ i ] = l / 2;
|
||||
int diff = (int)_v._ranges[ i ].intervals().size() - _i[ i ];
|
||||
if ( diff > 1 ) {
|
||||
latestNonEndpoint = i;
|
||||
} else if ( diff == 1 ) {
|
||||
int x = _v._ranges[ i ].intervals()[ _i[ i ] ]._upper._bound.woCompare( jj, false );
|
||||
if ( x != 0 ) {
|
||||
latestNonEndpoint = i;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
if ( l == (int)_v._ranges[ i ].intervals().size() * 2 - 1 ) {
|
||||
if ( latestNonEndpoint == -1 ) {
|
||||
return -2;
|
||||
}
|
||||
setZero( latestNonEndpoint + 1 );
|
||||
// skip to curr / latestNonEndpoint + 1 / superlative
|
||||
for( int j = latestNonEndpoint + 1; j < (int)_i.size(); ++j ) {
|
||||
_cmp[ j ] = _superlative[ j ];
|
||||
}
|
||||
return latestNonEndpoint + 1;
|
||||
}
|
||||
_i[ i ] = ( l + 1 ) / 2;
|
||||
// skip to curr / i / nextbounds
|
||||
_cmp[ i ] = &_v._ranges[ i ].intervals()[ _i[ i ] ]._lower._bound;
|
||||
for( int j = i + 1; j < (int)_i.size(); ++j ) {
|
||||
_cmp[ j ] = &_v._ranges[ j ].intervals().front()._lower._bound;
|
||||
}
|
||||
return i;
|
||||
return i;
|
||||
}
|
||||
x = _v._ranges[ i ].intervals()[ _i[ i ] ]._upper._bound.woCompare( jj, false );
|
||||
if ( ( oo.number() < 0 ) ^ ( _v._direction < 0 ) ) {
|
||||
}
|
||||
while( _i[ i ] < (int)_v._ranges[ i ].intervals().size() ) {
|
||||
int x = _v._ranges[ i ].intervals()[ _i[ i ] ]._upper._bound.woCompare( jj, false );
|
||||
if ( reverse ) {
|
||||
x = -x;
|
||||
}
|
||||
// cout << "x: " << x << endl;
|
||||
if ( x >= 0 ) {
|
||||
if ( x == 0 ) {
|
||||
eq = true;
|
||||
}
|
||||
if ( x == 0 ) {
|
||||
eq = true;
|
||||
break;
|
||||
}
|
||||
if ( x > 0 ) {
|
||||
if ( !_v._ranges[ i ].intervals()[ _i[ i ] ].equality() ) {
|
||||
x = _v._ranges[ i ].intervals()[ _i[ i ] ]._lower._bound.woCompare( jj, false );
|
||||
if ( reverse ) {
|
||||
x = -x;
|
||||
}
|
||||
}
|
||||
if ( x > 0 ) {
|
||||
setZero( i + 1 );
|
||||
// skip to curr / i / nextbounds
|
||||
_cmp[ i ] = &_v._ranges[ i ].intervals()[ _i[ i ] ]._lower._bound;
|
||||
for( int j = i + 1; j < (int)_i.size(); ++j ) {
|
||||
_cmp[ j ] = &_v._ranges[ j ].intervals().front()._lower._bound;
|
||||
}
|
||||
return i;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
++_i[ i ];
|
||||
setZero( i + 1 );
|
||||
// mark need to check lower bound?
|
||||
}
|
||||
int diff = (int)_v._ranges[ i ].intervals().size() - _i[ i ];
|
||||
// log() << "a diff: " << diff << endl;
|
||||
if ( diff > 1 || ( !eq && diff == 1 ) ) {
|
||||
latestNonEndpoint = i;
|
||||
} else if ( diff == 0 ) {
|
||||
@ -1050,10 +1090,6 @@ namespace mongo {
|
||||
}
|
||||
return latestNonEndpoint + 1;
|
||||
}
|
||||
if ( !_v._ranges[ i ].intervals()[ _i[ i ] ].equality() ) {
|
||||
// todo don't zero it if already have
|
||||
setZero( i + 1 );
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -32,8 +32,8 @@ namespace mongo {
|
||||
};
|
||||
|
||||
struct FieldInterval {
|
||||
FieldInterval(){}
|
||||
FieldInterval( const BSONElement& e ){
|
||||
FieldInterval() : _cachedEquality( -1 ) {}
|
||||
FieldInterval( const BSONElement& e ) : _cachedEquality( -1 ) {
|
||||
_lower._bound = _upper._bound = e;
|
||||
_lower._inclusive = _upper._inclusive = true;
|
||||
}
|
||||
@ -43,7 +43,13 @@ namespace mongo {
|
||||
int cmp = _lower._bound.woCompare( _upper._bound, false );
|
||||
return ( cmp < 0 || ( cmp == 0 && _lower._inclusive && _upper._inclusive ) );
|
||||
}
|
||||
bool equality() const { return _lower._inclusive && _upper._inclusive && _lower._bound.woCompare( _upper._bound, false ) == 0; }
|
||||
bool equality() const {
|
||||
if ( _cachedEquality == -1 ) {
|
||||
_cachedEquality = ( _lower._inclusive && _upper._inclusive && _lower._bound.woCompare( _upper._bound, false ) == 0 );
|
||||
}
|
||||
return _cachedEquality;
|
||||
}
|
||||
mutable int _cachedEquality;
|
||||
};
|
||||
|
||||
// range of a field's value that may be determined from query -- used to
|
||||
@ -346,7 +352,7 @@ namespace mongo {
|
||||
bool matches( const BSONObj &obj ) const;
|
||||
class Iterator {
|
||||
public:
|
||||
Iterator( const FieldRangeVector &v ) : _v( v ), _i( _v._ranges.size(), 0 ), _cmp( _v._ranges.size(), 0 ), _superlative( _v._ranges.size(), 0 ) {
|
||||
Iterator( const FieldRangeVector &v ) : _v( v ), _i( _v._ranges.size(), -1 ), _cmp( _v._ranges.size(), 0 ), _superlative( _v._ranges.size(), 0 ) {
|
||||
static BSONObj minObj = minObject();
|
||||
static BSONElement minElt = minObj.firstElement();
|
||||
static BSONObj maxObj = maxObject();
|
||||
@ -394,6 +400,11 @@ namespace mongo {
|
||||
_i[ j ] = 0;
|
||||
}
|
||||
}
|
||||
void setMinus( int i ) {
|
||||
for( int j = i; j < (int)_i.size(); ++j ) {
|
||||
_i[ j ] = -1;
|
||||
}
|
||||
}
|
||||
bool ok() {
|
||||
return _i[ 0 ] < (int)_v._ranges[ 0 ].intervals().size();
|
||||
}
|
||||
@ -422,6 +433,7 @@ namespace mongo {
|
||||
vector< const BSONElement* > _superlative;
|
||||
};
|
||||
private:
|
||||
int matchingLowElement( const BSONElement &e, int i, bool direction ) const;
|
||||
bool matchesElement( const BSONElement &e, int i, bool direction ) const;
|
||||
vector< FieldRange > _ranges;
|
||||
BSONObj _keyPattern;
|
||||
|
Loading…
Reference in New Issue
Block a user