| client_info.h | | client_info.h | |
| | | | |
| skipping to change at line 108 | | skipping to change at line 108 | |
| void noAutoSplit() { _autoSplitOk = false; } | | void noAutoSplit() { _autoSplitOk = false; } | |
| | | | |
| static ClientInfo * get(); | | static ClientInfo * get(); | |
| const AuthenticationInfo* getAuthenticationInfo() const { return (A
uthenticationInfo*)&_ai; } | | const AuthenticationInfo* getAuthenticationInfo() const { return (A
uthenticationInfo*)&_ai; } | |
| AuthenticationInfo* getAuthenticationInfo() { return (Authenticatio
nInfo*)&_ai; } | | AuthenticationInfo* getAuthenticationInfo() { return (Authenticatio
nInfo*)&_ai; } | |
| bool isAdmin() { return _ai.isAuthorized( "admin" ); } | | bool isAdmin() { return _ai.isAuthorized( "admin" ); } | |
| | | | |
| private: | | private: | |
| AuthenticationInfo _ai; | | AuthenticationInfo _ai; | |
| struct WBInfo { | | struct WBInfo { | |
|
| WBInfo( const WriteBackListener::ConnectionIdent& c , OID o ) : | | WBInfo( const WriteBackListener::ConnectionIdent& c, OID o, boo | |
| ident( c ) , id( o ) {} | | l fromLastOperation ) | |
| | | : ident( c ), id( o ), fromLastOperation( fromLastOperation | |
| | | ) {} | |
| WriteBackListener::ConnectionIdent ident; | | WriteBackListener::ConnectionIdent ident; | |
| OID id; | | OID id; | |
|
| | | bool fromLastOperation; | |
| }; | | }; | |
| | | | |
| // for getLastError | | // for getLastError | |
|
| void _addWriteBack( vector<WBInfo>& all , const BSONObj& o ); | | void _addWriteBack( vector<WBInfo>& all , const BSONObj& o, bool fr | |
| vector<BSONObj> _handleWriteBacks( vector<WBInfo>& all , bool fromW | | omLastOperation ); | |
| riteBackListener ); | | vector<BSONObj> _handleWriteBacks( const vector<WBInfo>& all , bool | |
| | | fromWriteBackListener ); | |
| | | | |
| int _id; // unique client id | | int _id; // unique client id | |
| HostAndPort _remote; // server:port of remote socket end | | HostAndPort _remote; // server:port of remote socket end | |
| | | | |
| // we use _a and _b to store shards we've talked to on the current
request and the previous | | // we use _a and _b to store shards we've talked to on the current
request and the previous | |
| // we use 2 so we can flip for getLastError type operations | | // we use 2 so we can flip for getLastError type operations | |
| | | | |
| set<string> _a; // actual set for _cur or _prev | | set<string> _a; // actual set for _cur or _prev | |
| set<string> _b; // " | | set<string> _b; // " | |
| | | | |
| | | | |
End of changes. 3 change blocks. |
| 5 lines changed or deleted | | 9 lines changed or added | |
|
| core.h | | core.h | |
| | | | |
| skipping to change at line 23 | | skipping to change at line 23 | |
| * GNU Affero General Public License for more details. | | * GNU Affero General Public License for more details. | |
| * | | * | |
| * You should have received a copy of the GNU Affero General Public Licen
se | | * You should have received a copy of the GNU Affero General Public Licen
se | |
| * along with this program. If not, see <http://www.gnu.org/licenses/>. | | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| */ | | */ | |
| | | | |
| #pragma once | | #pragma once | |
| | | | |
| #include "mongo/pch.h" | | #include "mongo/pch.h" | |
| #include "../jsobj.h" | | #include "../jsobj.h" | |
|
| | | #include "shapes.h" | |
| | | | |
| #include <cmath> | | #include <cmath> | |
| | | | |
| #ifndef M_PI | | #ifndef M_PI | |
| # define M_PI 3.14159265358979323846 | | # define M_PI 3.14159265358979323846 | |
| #endif | | #endif | |
| | | | |
| namespace mongo { | | namespace mongo { | |
| | | | |
| class GeoBitSets { | | class GeoBitSets { | |
| | | | |
| skipping to change at line 403 | | skipping to change at line 404 | |
| } | | } | |
| | | | |
| class GeoConvert { | | class GeoConvert { | |
| public: | | public: | |
| virtual ~GeoConvert() {} | | virtual ~GeoConvert() {} | |
| | | | |
| virtual void unhash( const GeoHash& h , double& x , double& y ) con
st = 0; | | virtual void unhash( const GeoHash& h , double& x , double& y ) con
st = 0; | |
| virtual GeoHash hash( double x , double y ) const = 0; | | virtual GeoHash hash( double x , double y ) const = 0; | |
| }; | | }; | |
| | | | |
|
| class Point { | | | |
| public: | | | |
| | | | |
| Point( const GeoConvert * g , const GeoHash& hash ) { | | | |
| g->unhash( hash , _x , _y ); | | | |
| } | | | |
| | | | |
| explicit Point( const BSONElement& e ) { | | | |
| BSONObjIterator i(e.Obj()); | | | |
| _x = i.next().number(); | | | |
| _y = i.next().number(); | | | |
| } | | | |
| | | | |
| explicit Point( const BSONObj& o ) { | | | |
| BSONObjIterator i(o); | | | |
| _x = i.next().number(); | | | |
| _y = i.next().number(); | | | |
| } | | | |
| | | | |
| Point( double x , double y ) | | | |
| : _x( x ) , _y( y ) { | | | |
| } | | | |
| | | | |
| Point() : _x(0),_y(0) { | | | |
| } | | | |
| | | | |
| GeoHash hash( const GeoConvert * g ) { | | | |
| return g->hash( _x , _y ); | | | |
| } | | | |
| | | | |
| double distance( const Point& p ) const { | | | |
| double a = _x - p._x; | | | |
| double b = _y - p._y; | | | |
| | | | |
| // Avoid numerical error if possible... | | | |
| if( a == 0 ) return abs( _y - p._y ); | | | |
| if( b == 0 ) return abs( _x - p._x ); | | | |
| | | | |
| return sqrt( ( a * a ) + ( b * b ) ); | | | |
| } | | | |
| | | | |
| /** | | | |
| * Distance method that compares x or y coords when other direction | | | |
| is zero, | | | |
| * avoids numerical error when distances are very close to radius b | | | |
| ut axis-aligned. | | | |
| * | | | |
| * An example of the problem is: | | | |
| * (52.0 - 51.9999) - 0.0001 = 3.31965e-15 and 52.0 - 51.9999 > 0.0 | | | |
| 001 in double arithmetic | | | |
| * but: | | | |
| * 51.9999 + 0.0001 <= 52.0 | | | |
| * | | | |
| * This avoids some (but not all!) suprising results in $center que | | | |
| ries where points are | | | |
| * ( radius + center.x, center.y ) or vice-versa. | | | |
| */ | | | |
| bool distanceWithin( const Point& p, double radius ) const { | | | |
| double a = _x - p._x; | | | |
| double b = _y - p._y; | | | |
| | | | |
| if( a == 0 ) { | | | |
| // | | | |
| // Note: For some, unknown reason, when a 32-bit g++ optim | | | |
| izes this call, the sum is | | | |
| // calculated imprecisely. We need to force the compiler t | | | |
| o always evaluate it correctly, | | | |
| // hence the weirdness. | | | |
| // | | | |
| // On some 32-bit linux machines, removing the volatile key | | | |
| word or calculating the sum inline | | | |
| // will make certain geo tests fail. Of course this check | | | |
| will force volatile for all 32-bit systems, | | | |
| // not just affected systems. | | | |
| if( sizeof(void*) <= 4 ){ | | | |
| volatile double sum = _y > p._y ? p._y + radius : _y + | | | |
| radius; | | | |
| return _y > p._y ? sum >= _y : sum >= p._y; | | | |
| } | | | |
| else { | | | |
| // Original math, correct for most systems | | | |
| return _y > p._y ? p._y + radius >= _y : _y + radius >= | | | |
| p._y; | | | |
| } | | | |
| } | | | |
| if( b == 0 ) { | | | |
| if( sizeof(void*) <= 4 ){ | | | |
| volatile double sum = _x > p._x ? p._x + radius : _x + | | | |
| radius; | | | |
| return _x > p._x ? sum >= _x : sum >= p._x; | | | |
| } | | | |
| else { | | | |
| return _x > p._x ? p._x + radius >= _x : _x + radius >= | | | |
| p._x; | | | |
| } | | | |
| } | | | |
| | | | |
| return sqrt( ( a * a ) + ( b * b ) ) <= radius; | | | |
| } | | | |
| | | | |
| string toString() const { | | | |
| StringBuilder buf; | | | |
| buf << "(" << _x << "," << _y << ")"; | | | |
| return buf.str(); | | | |
| | | | |
| } | | | |
| | | | |
| double _x; | | | |
| double _y; | | | |
| }; | | | |
| | | | |
| extern const double EARTH_RADIUS_KM; | | extern const double EARTH_RADIUS_KM; | |
| extern const double EARTH_RADIUS_MILES; | | extern const double EARTH_RADIUS_MILES; | |
| | | | |
| // Technically lat/long bounds, not really tied to earth radius. | | // Technically lat/long bounds, not really tied to earth radius. | |
| inline void checkEarthBounds( Point p ) { | | inline void checkEarthBounds( Point p ) { | |
| uassert( 14808, str::stream() << "point " << p.toString() << " must
be in earth-like bounds of long : [-180, 180], lat : [-90, 90] ", | | uassert( 14808, str::stream() << "point " << p.toString() << " must
be in earth-like bounds of long : [-180, 180], lat : [-90, 90] ", | |
| p._x >= -180 && p._x <= 180 && p._y >= -90 && p._y <= 90 )
; | | p._x >= -180 && p._x <= 180 && p._y >= -90 && p._y <= 90 )
; | |
| } | | } | |
| | | | |
| inline double deg2rad(double deg) { return deg * (M_PI/180); } | | inline double deg2rad(double deg) { return deg * (M_PI/180); } | |
| | | | |
End of changes. 2 change blocks. |
| 111 lines changed or deleted | | 1 lines changed or added | |
|
| dbclientinterface.h | | dbclientinterface.h | |
| | | | |
| skipping to change at line 250 | | skipping to change at line 250 | |
| string toString() const { return _string; } | | string toString() const { return _string; } | |
| | | | |
| DBClientBase* connect( string& errmsg, double socketTimeout = 0 ) c
onst; | | DBClientBase* connect( string& errmsg, double socketTimeout = 0 ) c
onst; | |
| | | | |
| string getSetName() const { return _setName; } | | string getSetName() const { return _setName; } | |
| | | | |
| vector<HostAndPort> getServers() const { return _servers; } | | vector<HostAndPort> getServers() const { return _servers; } | |
| | | | |
| ConnectionType type() const { return _type; } | | ConnectionType type() const { return _type; } | |
| | | | |
|
| | | /** | |
| | | * This returns true if this and other point to the same logical en | |
| | | tity. | |
| | | * For single nodes, thats the same address. | |
| | | * For replica sets, thats just the same replica set name. | |
| | | * For pair (deprecated) or sync cluster connections, that's the sa | |
| | | me hosts in any ordering. | |
| | | */ | |
| | | bool sameLogicalEndpoint( const ConnectionString& other ) const; | |
| | | | |
| static ConnectionString parse( const string& url , string& errmsg )
; | | static ConnectionString parse( const string& url , string& errmsg )
; | |
| | | | |
| static string typeToString( ConnectionType type ); | | static string typeToString( ConnectionType type ); | |
| | | | |
| // | | // | |
| // Allow overriding the default connection behavior | | // Allow overriding the default connection behavior | |
| // This is needed for some tests, which otherwise would fail becaus
e they are unable to contact | | // This is needed for some tests, which otherwise would fail becaus
e they are unable to contact | |
| // the correct servers. | | // the correct servers. | |
| // | | // | |
| | | | |
| | | | |
End of changes. 1 change blocks. |
| 0 lines changed or deleted | | 10 lines changed or added | |
|
| hostandport.h | | hostandport.h | |
| | | | |
| skipping to change at line 20 | | skipping to change at line 20 | |
| * | | * | |
| * Unless required by applicable law or agreed to in writing, software | | * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | | * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli
ed. | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or impli
ed. | |
| * See the License for the specific language governing permissions and | | * See the License for the specific language governing permissions and | |
| * limitations under the License. | | * limitations under the License. | |
| */ | | */ | |
| | | | |
| #pragma once | | #pragma once | |
| | | | |
|
| #include "sock.h" | | #include "mongo/db/cmdline.h" | |
| #include "../../db/cmdline.h" | | #include "mongo/util/mongoutils/str.h" | |
| #include "../mongoutils/str.h" | | #include "mongo/util/net/sock.h" | |
| | | #include "mongo/bson/util/builder.h" | |
| | | | |
| namespace mongo { | | namespace mongo { | |
| | | | |
| using namespace mongoutils; | | using namespace mongoutils; | |
| | | | |
| /** helper for manipulating host:port connection endpoints. | | /** helper for manipulating host:port connection endpoints. | |
| */ | | */ | |
| struct HostAndPort { | | struct HostAndPort { | |
| HostAndPort() : _port(-1) { } | | HostAndPort() : _port(-1) { } | |
| | | | |
| | | | |
| skipping to change at line 75 | | skipping to change at line 76 | |
| | | | |
| bool isLocalHost() const; | | bool isLocalHost() const; | |
| | | | |
| /** | | /** | |
| * @param includePort host:port if true, host otherwise | | * @param includePort host:port if true, host otherwise | |
| */ | | */ | |
| string toString( bool includePort=true ) const; | | string toString( bool includePort=true ) const; | |
| | | | |
| operator string() const { return toString(); } | | operator string() const { return toString(); } | |
| | | | |
|
| | | void append( StringBuilder& ss ) const; | |
| | | | |
| bool empty() const { | | bool empty() const { | |
| return _host.empty() && _port < 0; | | return _host.empty() && _port < 0; | |
| } | | } | |
| string host() const { | | string host() const { | |
| return _host; | | return _host; | |
| } | | } | |
| int port() const { | | int port() const { | |
| if (hasPort()) | | if (hasPort()) | |
| return _port; | | return _port; | |
| return CmdLine::DefaultDBPort; | | return CmdLine::DefaultDBPort; | |
| | | | |
| skipping to change at line 125 | | skipping to change at line 128 | |
| } | | } | |
| } | | } | |
| | | | |
| string h = getHostName(); | | string h = getHostName(); | |
| verify( !h.empty() ); | | verify( !h.empty() ); | |
| verify( h != "localhost" ); | | verify( h != "localhost" ); | |
| return HostAndPort(h, cmdLine.port); | | return HostAndPort(h, cmdLine.port); | |
| } | | } | |
| | | | |
| inline string HostAndPort::toString( bool includePort ) const { | | inline string HostAndPort::toString( bool includePort ) const { | |
|
| string h = host(); | | | |
| int p = port(); | | | |
| | | | |
| if ( ! includePort ) | | if ( ! includePort ) | |
|
| return h; | | return host(); | |
| | | | |
| | | StringBuilder ss; | |
| | | append( ss ); | |
| | | return ss.str(); | |
| | | } | |
| | | | |
| | | inline void HostAndPort::append( StringBuilder& ss ) const { | |
| | | ss << host(); | |
| | | | |
| | | int p = port(); | |
| | | | |
|
| stringstream ss; | | | |
| ss << h; | | | |
| if ( p != -1 ) { | | if ( p != -1 ) { | |
| ss << ':'; | | ss << ':'; | |
| #if defined(_DEBUG) | | #if defined(_DEBUG) | |
| if( p >= 44000 && p < 44100 ) { | | if( p >= 44000 && p < 44100 ) { | |
| log() << "warning: special debug port 44xxx used" << endl; | | log() << "warning: special debug port 44xxx used" << endl; | |
| ss << p+1; | | ss << p+1; | |
| } | | } | |
| else | | else | |
| ss << p; | | ss << p; | |
| #else | | #else | |
| ss << p; | | ss << p; | |
| #endif | | #endif | |
| } | | } | |
|
| return ss.str(); | | | |
| } | | } | |
| | | | |
| inline bool HostAndPort::isLocalHost() const { | | inline bool HostAndPort::isLocalHost() const { | |
| string _host = host(); | | string _host = host(); | |
| return ( _host == "localhost" | | return ( _host == "localhost" | |
| || startsWith(_host.c_str(), "127.") | | || startsWith(_host.c_str(), "127.") | |
| || _host == "::1" | | || _host == "::1" | |
| || _host == "anonymous unix socket" | | || _host == "anonymous unix socket" | |
| || _host.c_str()[0] == '/' // unix socket | | || _host.c_str()[0] == '/' // unix socket | |
| ); | | ); | |
| | | | |
End of changes. 6 change blocks. |
| 10 lines changed or deleted | | 18 lines changed or added | |
|
| lasterror.h | | lasterror.h | |
| | | | |
| skipping to change at line 32 | | skipping to change at line 32 | |
| namespace mongo { | | namespace mongo { | |
| class BSONObjBuilder; | | class BSONObjBuilder; | |
| class Message; | | class Message; | |
| | | | |
| struct LastError { | | struct LastError { | |
| int code; | | int code; | |
| string msg; | | string msg; | |
| enum UpdatedExistingType { NotUpdate, True, False } updatedExisting
; | | enum UpdatedExistingType { NotUpdate, True, False } updatedExisting
; | |
| OID upsertedId; | | OID upsertedId; | |
| OID writebackId; // this shouldn't get reset so that old GLE are ha
ndled | | OID writebackId; // this shouldn't get reset so that old GLE are ha
ndled | |
|
| | | int writebackSince; | |
| long long nObjects; | | long long nObjects; | |
| int nPrev; | | int nPrev; | |
| bool valid; | | bool valid; | |
| bool disabled; | | bool disabled; | |
| void writeback( OID& oid ) { | | void writeback( OID& oid ) { | |
| reset( true ); | | reset( true ); | |
| writebackId = oid; | | writebackId = oid; | |
|
| | | writebackSince = 0; | |
| } | | } | |
| void raiseError(int _code , const char *_msg) { | | void raiseError(int _code , const char *_msg) { | |
| reset( true ); | | reset( true ); | |
| code = _code; | | code = _code; | |
| msg = _msg; | | msg = _msg; | |
| } | | } | |
| void recordUpdate( bool _updateObjects , long long _nObjects , OID
_upsertedId ) { | | void recordUpdate( bool _updateObjects , long long _nObjects , OID
_upsertedId ) { | |
| reset( true ); | | reset( true ); | |
| nObjects = _nObjects; | | nObjects = _nObjects; | |
| updatedExisting = _updateObjects ? True : False; | | updatedExisting = _updateObjects ? True : False; | |
| if ( _upsertedId.isSet() ) | | if ( _upsertedId.isSet() ) | |
| upsertedId = _upsertedId; | | upsertedId = _upsertedId; | |
| | | | |
| } | | } | |
| void recordDelete( long long nDeleted ) { | | void recordDelete( long long nDeleted ) { | |
| reset( true ); | | reset( true ); | |
| nObjects = nDeleted; | | nObjects = nDeleted; | |
| } | | } | |
| LastError() { | | LastError() { | |
| reset(); | | reset(); | |
|
| | | writebackSince = 0; | |
| } | | } | |
| void reset( bool _valid = false ) { | | void reset( bool _valid = false ) { | |
| code = 0; | | code = 0; | |
| msg.clear(); | | msg.clear(); | |
| updatedExisting = NotUpdate; | | updatedExisting = NotUpdate; | |
| nObjects = 0; | | nObjects = 0; | |
| nPrev = 1; | | nPrev = 1; | |
| valid = _valid; | | valid = _valid; | |
| disabled = false; | | disabled = false; | |
| upsertedId.clear(); | | upsertedId.clear(); | |
| | | | |
End of changes. 3 change blocks. |
| 0 lines changed or deleted | | 3 lines changed or added | |
|
| matcher.h | | matcher.h | |
| | | | |
| skipping to change at line 25 | | skipping to change at line 25 | |
| * GNU Affero General Public License for more details. | | * GNU Affero General Public License for more details. | |
| * | | * | |
| * You should have received a copy of the GNU Affero General Public Licen
se | | * You should have received a copy of the GNU Affero General Public Licen
se | |
| * along with this program. If not, see <http://www.gnu.org/licenses/>. | | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| */ | | */ | |
| | | | |
| #pragma once | | #pragma once | |
| | | | |
| #include "jsobj.h" | | #include "jsobj.h" | |
| #include "pcrecpp.h" | | #include "pcrecpp.h" | |
|
| | | #include "geo/shapes.h" | |
| | | | |
| namespace mongo { | | namespace mongo { | |
| | | | |
| class Cursor; | | class Cursor; | |
| class CoveredIndexMatcher; | | class CoveredIndexMatcher; | |
| class ElementMatcher; | | class ElementMatcher; | |
| class Matcher; | | class Matcher; | |
| class FieldRangeVector; | | class FieldRangeVector; | |
| | | | |
| class RegexMatcher { | | class RegexMatcher { | |
| public: | | public: | |
| const char *_fieldName; | | const char *_fieldName; | |
| const char *_regex; | | const char *_regex; | |
| const char *_flags; | | const char *_flags; | |
| string _prefix; | | string _prefix; | |
| shared_ptr< pcrecpp::RE > _re; | | shared_ptr< pcrecpp::RE > _re; | |
| bool _isNot; | | bool _isNot; | |
| RegexMatcher() : _isNot() {} | | RegexMatcher() : _isNot() {} | |
| }; | | }; | |
| | | | |
|
| | | class GeoMatcher { | |
| | | private: | |
| | | GeoMatcher(const string& field) : _isBox(false), _isCircle(false), | |
| | | _isPolygon(false), | |
| | | _fieldName(field) {} | |
| | | bool _isBox; | |
| | | Box _box; | |
| | | | |
| | | bool _isCircle; | |
| | | Point _center; | |
| | | double _radius; | |
| | | | |
| | | bool _isPolygon; | |
| | | Polygon _polygon; | |
| | | | |
| | | string _fieldName; | |
| | | public: | |
| | | const string& getFieldName() const { return _fieldName; } | |
| | | | |
| | | static GeoMatcher makeBox(const string& field, const BSONObj &min, | |
| | | const BSONObj &max) { | |
| | | GeoMatcher m(field); | |
| | | m._isBox = true; | |
| | | uassert(16470, "Malformed coord: " + min.toString(), pointFrom( | |
| | | min, &m._box._min)); | |
| | | uassert(16471, "Malformed coord: " + max.toString(), pointFrom( | |
| | | max, &m._box._max)); | |
| | | return m; | |
| | | } | |
| | | | |
| | | static GeoMatcher makeCircle(const string& field, const BSONObj &ce | |
| | | nter, double rad) { | |
| | | GeoMatcher m(field); | |
| | | m._isCircle = true; | |
| | | uassert(16472, "Malformed coord: " + center.toString(), pointFr | |
| | | om(center, &m._center)); | |
| | | m._radius = rad; | |
| | | return m; | |
| | | } | |
| | | | |
| | | static GeoMatcher makePolygon(const string& field, const BSONObj &p | |
| | | oly) { | |
| | | GeoMatcher m(field); | |
| | | vector<Point> points; | |
| | | | |
| | | m._isPolygon = true; | |
| | | BSONObjIterator coordIt(poly); | |
| | | while (coordIt.more()) { | |
| | | BSONElement coord = coordIt.next(); | |
| | | const BSONObj& obj = coord.Obj(); | |
| | | Point p; | |
| | | uassert(16480, "Malformed coord: " + obj.toString(), pointF | |
| | | rom(obj, &p)); | |
| | | points.push_back(p); | |
| | | } | |
| | | m._polygon = Polygon(points); | |
| | | return m; | |
| | | } | |
| | | | |
| | | bool containsPoint(Point p) const { | |
| | | if (_isBox) { | |
| | | return _box.inside(p, 0); | |
| | | } else if (_isCircle) { | |
| | | return _center.distance(p) <= _radius; | |
| | | } else if (_isPolygon) { | |
| | | return _polygon.contains(p); | |
| | | } else { | |
| | | return false; | |
| | | } | |
| | | } | |
| | | | |
| | | string toString() const { | |
| | | stringstream ss; | |
| | | if (_isBox) { | |
| | | ss << "GeoMatcher Box: " << _box.toString(); | |
| | | } else if (_isCircle) { | |
| | | ss << "GeoMatcher Circle @ " << _center.toString() << " r = | |
| | | " << _radius; | |
| | | } else { | |
| | | ss << "GeoMatcher UNKNOWN"; | |
| | | } | |
| | | return ss.str(); | |
| | | } | |
| | | | |
| | | static bool pointFrom(const BSONObj o, Point *p) { | |
| | | BSONObjIterator i(o); | |
| | | if (!i.more()) { return false; } | |
| | | BSONElement xe = i.next(); | |
| | | if (!i.more()) { return false; } | |
| | | BSONElement ye = i.next(); | |
| | | if (!xe.isNumber() || !ye.isNumber()) { return false; } | |
| | | p->_x = xe.number(); | |
| | | p->_y = ye.number(); | |
| | | return true; | |
| | | } | |
| | | }; | |
| | | | |
| struct element_lt { | | struct element_lt { | |
| bool operator()(const BSONElement& l, const BSONElement& r) const { | | bool operator()(const BSONElement& l, const BSONElement& r) const { | |
| int x = (int) l.canonicalType() - (int) r.canonicalType(); | | int x = (int) l.canonicalType() - (int) r.canonicalType(); | |
| if ( x < 0 ) return true; | | if ( x < 0 ) return true; | |
| else if ( x > 0 ) return false; | | else if ( x > 0 ) return false; | |
| return compareElementValues(l,r) < 0; | | return compareElementValues(l,r) < 0; | |
| } | | } | |
| }; | | }; | |
| | | | |
| /** | | /** | |
| | | | |
| skipping to change at line 269 | | skipping to change at line 358 | |
| bool _haveNeg; | | bool _haveNeg; | |
| | | | |
| /* $atomic - if true, a multi document operation (some removes, upd
ates) | | /* $atomic - if true, a multi document operation (some removes, upd
ates) | |
| should be done atomically. in that case, we do not yi
eld - | | should be done atomically. in that case, we do not yi
eld - | |
| i.e. we stay locked the whole time. | | i.e. we stay locked the whole time. | |
| http://dochub.mongodb.org/core/remove | | http://dochub.mongodb.org/core/remove | |
| */ | | */ | |
| bool _atomic; | | bool _atomic; | |
| | | | |
| vector<RegexMatcher> _regexs; | | vector<RegexMatcher> _regexs; | |
|
| | | vector<GeoMatcher> _geo; | |
| | | | |
| // so we delete the mem when we're done: | | // so we delete the mem when we're done: | |
| vector< shared_ptr< BSONObjBuilder > > _builders; | | vector< shared_ptr< BSONObjBuilder > > _builders; | |
| list< shared_ptr< Matcher > > _andMatchers; | | list< shared_ptr< Matcher > > _andMatchers; | |
| list< shared_ptr< Matcher > > _orMatchers; | | list< shared_ptr< Matcher > > _orMatchers; | |
| list< shared_ptr< Matcher > > _norMatchers; | | list< shared_ptr< Matcher > > _norMatchers; | |
| | | | |
| friend class CoveredIndexMatcher; | | friend class CoveredIndexMatcher; | |
| }; | | }; | |
| | | | |
| | | | |
End of changes. 3 change blocks. |
| 0 lines changed or deleted | | 99 lines changed or added | |
|
| queryutil.h | | queryutil.h | |
| | | | |
| skipping to change at line 361 | | skipping to change at line 361 | |
| string getSpecial() const { return _special; } | | string getSpecial() const { return _special; } | |
| /** Make component intervals noninclusive. */ | | /** Make component intervals noninclusive. */ | |
| void setExclusiveBounds(); | | void setExclusiveBounds(); | |
| /** | | /** | |
| * Constructs a range where all FieldIntervals and FieldBounds are
in | | * Constructs a range where all FieldIntervals and FieldBounds are
in | |
| * the opposite order of the current range. | | * the opposite order of the current range. | |
| * NOTE the resulting intervals might not be strictValid(). | | * NOTE the resulting intervals might not be strictValid(). | |
| */ | | */ | |
| void reverse( FieldRange &ret ) const; | | void reverse( FieldRange &ret ) const; | |
| | | | |
|
| | | bool hasSpecialThatNeedsIndex() const { verify( _special.size() ); | |
| | | return _specialNeedsIndex; } | |
| | | | |
| string toString() const; | | string toString() const; | |
| private: | | private: | |
| BSONObj addObj( const BSONObj &o ); | | BSONObj addObj( const BSONObj &o ); | |
| void finishOperation( const vector<FieldInterval> &newIntervals, co
nst FieldRange &other, | | void finishOperation( const vector<FieldInterval> &newIntervals, co
nst FieldRange &other, | |
| bool exactMatchRepresentation ); | | bool exactMatchRepresentation ); | |
| vector<FieldInterval> _intervals; | | vector<FieldInterval> _intervals; | |
| // Owns memory for our BSONElements. | | // Owns memory for our BSONElements. | |
| vector<BSONObj> _objData; | | vector<BSONObj> _objData; | |
| string _special; | | string _special; | |
|
| | | bool _specialNeedsIndex; | |
| bool _exactMatchRepresentation; | | bool _exactMatchRepresentation; | |
| }; | | }; | |
| | | | |
| /** | | /** | |
| * A BoundList contains intervals specified by inclusive start | | * A BoundList contains intervals specified by inclusive start | |
| * and end bounds. The intervals should be nonoverlapping and occur in | | * and end bounds. The intervals should be nonoverlapping and occur in | |
| * the specified direction of traversal. For example, given a simple i
ndex {i:1} | | * the specified direction of traversal. For example, given a simple i
ndex {i:1} | |
| * and direction +1, one valid BoundList is: (1, 2); (4, 6). The same
BoundList | | * and direction +1, one valid BoundList is: (1, 2); (4, 6). The same
BoundList | |
| * would be valid for index {i:-1} with direction -1. | | * would be valid for index {i:-1} with direction -1. | |
| */ | | */ | |
| | | | |
| skipping to change at line 459 | | skipping to change at line 462 | |
| /** | | /** | |
| * @return a simplified query from the extreme values of the non un
iversal | | * @return a simplified query from the extreme values of the non un
iversal | |
| * fields. | | * fields. | |
| * @param fields If specified, the fields of the returned object ar
e | | * @param fields If specified, the fields of the returned object ar
e | |
| * ordered to match those of 'fields'. | | * ordered to match those of 'fields'. | |
| */ | | */ | |
| BSONObj simplifiedQuery( const BSONObj &fields = BSONObj() ) const; | | BSONObj simplifiedQuery( const BSONObj &fields = BSONObj() ) const; | |
| | | | |
| QueryPattern pattern( const BSONObj &sort = BSONObj() ) const; | | QueryPattern pattern( const BSONObj &sort = BSONObj() ) const; | |
| string getSpecial() const; | | string getSpecial() const; | |
|
| | | bool hasSpecialThatNeedsIndex() const; | |
| | | | |
| /** | | /** | |
| * @return a FieldRangeSet approximation of the documents in 'this'
but | | * @return a FieldRangeSet approximation of the documents in 'this'
but | |
| * not in 'other'. The approximation will be a superset of the doc
uments | | * not in 'other'. The approximation will be a superset of the doc
uments | |
| * in 'this' but not 'other'. | | * in 'this' but not 'other'. | |
| */ | | */ | |
| const FieldRangeSet &operator-=( const FieldRangeSet &other ); | | const FieldRangeSet &operator-=( const FieldRangeSet &other ); | |
| /** @return intersection of 'this' with 'other'. */ | | /** @return intersection of 'this' with 'other'. */ | |
| const FieldRangeSet &operator&=( const FieldRangeSet &other ); | | const FieldRangeSet &operator&=( const FieldRangeSet &other ); | |
| | | | |
| | | | |
| skipping to change at line 580 | | skipping to change at line 584 | |
| bool matchPossible() const { return _multiKey.matchPossible(); } | | bool matchPossible() const { return _multiKey.matchPossible(); } | |
| /** | | /** | |
| * @return false if a match is impossible on the specified index. | | * @return false if a match is impossible on the specified index. | |
| * @param idxNo -1 for non index scan. | | * @param idxNo -1 for non index scan. | |
| */ | | */ | |
| bool matchPossibleForIndex( NamespaceDetails *d, int idxNo, const B
SONObj &keyPattern ) const; | | bool matchPossibleForIndex( NamespaceDetails *d, int idxNo, const B
SONObj &keyPattern ) const; | |
| | | | |
| const char *ns() const { return _singleKey.ns(); } | | const char *ns() const { return _singleKey.ns(); } | |
| | | | |
| string getSpecial() const { return _singleKey.getSpecial(); } | | string getSpecial() const { return _singleKey.getSpecial(); } | |
|
| | | bool hasSpecialThatNeedsIndex() const { return _singleKey.hasSpecia
lThatNeedsIndex(); } | |
| | | | |
| /** Intersect with another FieldRangeSetPair. */ | | /** Intersect with another FieldRangeSetPair. */ | |
| FieldRangeSetPair &operator&=( const FieldRangeSetPair &other ); | | FieldRangeSetPair &operator&=( const FieldRangeSetPair &other ); | |
| /** | | /** | |
| * Subtract a FieldRangeSet, generally one expressing a range that
has | | * Subtract a FieldRangeSet, generally one expressing a range that
has | |
| * already been scanned. | | * already been scanned. | |
| */ | | */ | |
| FieldRangeSetPair &operator-=( const FieldRangeSet &scanned ); | | FieldRangeSetPair &operator-=( const FieldRangeSet &scanned ); | |
| | | | |
| BoundList shardKeyIndexBounds( const BSONObj &keyPattern ) const { | | BoundList shardKeyIndexBounds( const BSONObj &keyPattern ) const { | |
| | | | |
End of changes. 4 change blocks. |
| 0 lines changed or deleted | | 6 lines changed or added | |
|
| shard.h | | shard.h | |
| | | | |
| skipping to change at line 102 | | skipping to change at line 102 | |
| | | | |
| string toString() const { | | string toString() const { | |
| return _name + ":" + _addr; | | return _name + ":" + _addr; | |
| } | | } | |
| | | | |
| friend ostream& operator << (ostream& out, const Shard& s) { | | friend ostream& operator << (ostream& out, const Shard& s) { | |
| return (out << s.toString()); | | return (out << s.toString()); | |
| } | | } | |
| | | | |
| bool operator==( const Shard& s ) const { | | bool operator==( const Shard& s ) const { | |
|
| bool n = _name == s._name; | | if ( _name != s._name ) | |
| bool a = _addr == s._addr; | | return false; | |
| | | return _cs.sameLogicalEndpoint( s._cs ); | |
| verify( n == a ); // names and address are 1 to 1 | | | |
| return n; | | | |
| } | | } | |
| | | | |
| bool operator!=( const Shard& s ) const { | | bool operator!=( const Shard& s ) const { | |
|
| bool n = _name == s._name; | | return ! ( *this == s ); | |
| bool a = _addr == s._addr; | | | |
| return ! ( n && a ); | | | |
| } | | } | |
| | | | |
| bool operator==( const string& s ) const { | | bool operator==( const string& s ) const { | |
| return _name == s || _addr == s; | | return _name == s || _addr == s; | |
| } | | } | |
| | | | |
| bool operator!=( const string& s ) const { | | bool operator!=( const string& s ) const { | |
| return _name != s && _addr != s; | | return _name != s && _addr != s; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 274 | | skipping to change at line 270 | |
| | | | |
| ChunkManagerPtr getManager() const { | | ChunkManagerPtr getManager() const { | |
| return _manager; | | return _manager; | |
| } | | } | |
| | | | |
| bool setVersion() { | | bool setVersion() { | |
| _finishInit(); | | _finishInit(); | |
| return _setVersion; | | return _setVersion; | |
| } | | } | |
| | | | |
|
| static void sync(); | | static void sync( const string& db ); | |
| | | | |
| void donotCheckVersion() { | | void donotCheckVersion() { | |
| _setVersion = false; | | _setVersion = false; | |
| _finishedInit = true; | | _finishedInit = true; | |
| } | | } | |
| | | | |
| bool ok() const { return _conn > 0; } | | bool ok() const { return _conn > 0; } | |
| | | | |
| /** | | /** | |
| this just passes through excpet it checks for stale configs | | this just passes through excpet it checks for stale configs | |
| | | | |
| skipping to change at line 315 | | skipping to change at line 311 | |
| extern DBConnectionPool shardConnectionPool; | | extern DBConnectionPool shardConnectionPool; | |
| | | | |
| class ShardingConnectionHook : public DBConnectionHook { | | class ShardingConnectionHook : public DBConnectionHook { | |
| public: | | public: | |
| | | | |
| ShardingConnectionHook( bool shardedConnections ) | | ShardingConnectionHook( bool shardedConnections ) | |
| : _shardedConnections( shardedConnections ) { | | : _shardedConnections( shardedConnections ) { | |
| } | | } | |
| | | | |
| virtual void onCreate( DBClientBase * conn ); | | virtual void onCreate( DBClientBase * conn ); | |
|
| virtual void onHandedOut( DBClientBase * conn ); | | | |
| virtual void onDestroy( DBClientBase * conn ); | | virtual void onDestroy( DBClientBase * conn ); | |
| | | | |
| bool _shardedConnections; | | bool _shardedConnections; | |
| }; | | }; | |
| } | | } | |
| | | | |
End of changes. 4 change blocks. |
| 10 lines changed or deleted | | 5 lines changed or added | |
|
| sock.h | | sock.h | |
| | | | |
| skipping to change at line 207 | | skipping to change at line 207 | |
| Socket(int sock, const SockAddr& farEnd); | | Socket(int sock, const SockAddr& farEnd); | |
| | | | |
| /** In some cases the timeout will actually be 2x this value - eg w
e do a partial send, | | /** In some cases the timeout will actually be 2x this value - eg w
e do a partial send, | |
| then the timeout fires, then we try to send again, then the tim
eout fires again with | | then the timeout fires, then we try to send again, then the tim
eout fires again with | |
| no data sent, then we detect that the other side is down. | | no data sent, then we detect that the other side is down. | |
| | | | |
| Generally you don't want a timeout, you should be very prepared
for errors if you set one. | | Generally you don't want a timeout, you should be very prepared
for errors if you set one. | |
| */ | | */ | |
| Socket(double so_timeout = 0, int logLevel = 0 ); | | Socket(double so_timeout = 0, int logLevel = 0 ); | |
| | | | |
|
| ~Socket() { | | ~Socket(); | |
| close(); | | | |
| } | | | |
| | | | |
| bool connect(SockAddr& farEnd); | | bool connect(SockAddr& farEnd); | |
| void close(); | | void close(); | |
| | | | |
| void send( const char * data , int len, const char *context ); | | void send( const char * data , int len, const char *context ); | |
| void send( const vector< pair< char *, int > > &data, const char *c
ontext ); | | void send( const vector< pair< char *, int > > &data, const char *c
ontext ); | |
| | | | |
| // recv len or throw SocketException | | // recv len or throw SocketException | |
| void recv( char * data , int len ); | | void recv( char * data , int len ); | |
| int unsafe_recv( char *buf, int max ); | | int unsafe_recv( char *buf, int max ); | |
| | | | |
End of changes. 1 change blocks. |
| 3 lines changed or deleted | | 1 lines changed or added | |
|
| update_internal.h | | update_internal.h | |
| | | | |
| skipping to change at line 33 | | skipping to change at line 33 | |
| #include "mongo/db/jsobjmanipulator.h" | | #include "mongo/db/jsobjmanipulator.h" | |
| #include "mongo/db/matcher.h" | | #include "mongo/db/matcher.h" | |
| #include "mongo/util/embedded_builder.h" | | #include "mongo/util/embedded_builder.h" | |
| #include "mongo/util/stringutils.h" | | #include "mongo/util/stringutils.h" | |
| | | | |
| namespace mongo { | | namespace mongo { | |
| | | | |
| class ModState; | | class ModState; | |
| class ModSetState; | | class ModSetState; | |
| | | | |
|
| | | /** | |
| | | * a.$ -> a | |
| | | * @return true if out is set and we made a change | |
| | | */ | |
| | | bool getCanonicalIndexField( const string& fullName, string* out ); | |
| | | | |
| /* Used for modifiers such as $inc, $set, $push, ... | | /* Used for modifiers such as $inc, $set, $push, ... | |
| * stores the info about a single operation | | * stores the info about a single operation | |
| * once created should never be modified | | * once created should never be modified | |
| */ | | */ | |
| struct Mod { | | struct Mod { | |
| // See opFromStr below | | // See opFromStr below | |
| // 0 1 2 3 4 5 6 7 8
9 10 11 12 13 | | // 0 1 2 3 4 5 6 7 8
9 10 11 12 13 | |
| enum Op { INC, SET, PUSH, PUSH_ALL, PULL, PULL_ALL , POP, UNSET, BI
TAND, BITOR , BIT , ADDTOSET, RENAME_FROM, RENAME_TO } op; | | enum Op { INC, SET, PUSH, PUSH_ALL, PULL, PULL_ALL , POP, UNSET, BI
TAND, BITOR , BIT , ADDTOSET, RENAME_FROM, RENAME_TO } op; | |
| | | | |
| static const char* modNames[]; | | static const char* modNames[]; | |
| | | | |
| skipping to change at line 146 | | skipping to change at line 152 | |
| static bool isIndexed( const string& fullName , const set<string>&
idxKeys ) { | | static bool isIndexed( const string& fullName , const set<string>&
idxKeys ) { | |
| const char * fieldName = fullName.c_str(); | | const char * fieldName = fullName.c_str(); | |
| // check if there is an index key that is a parent of mod | | // check if there is an index key that is a parent of mod | |
| for( const char* dot = strchr( fieldName, '.' ); dot; dot = str
chr( dot + 1, '.' ) ) | | for( const char* dot = strchr( fieldName, '.' ); dot; dot = str
chr( dot + 1, '.' ) ) | |
| if ( idxKeys.count( string( fieldName, dot - fieldName ) )
) | | if ( idxKeys.count( string( fieldName, dot - fieldName ) )
) | |
| return true; | | return true; | |
| | | | |
| // check if there is an index key equal to mod | | // check if there is an index key equal to mod | |
| if ( idxKeys.count(fullName) ) | | if ( idxKeys.count(fullName) ) | |
| return true; | | return true; | |
|
| | | | |
| // check if there is an index key that is a child of mod | | // check if there is an index key that is a child of mod | |
| set< string >::const_iterator j = idxKeys.upper_bound( fullName
); | | set< string >::const_iterator j = idxKeys.upper_bound( fullName
); | |
| if ( j != idxKeys.end() && j->find( fullName ) == 0 && (*j)[ful
lName.size()] == '.' ) | | if ( j != idxKeys.end() && j->find( fullName ) == 0 && (*j)[ful
lName.size()] == '.' ) | |
| return true; | | return true; | |
| | | | |
| return false; | | return false; | |
| } | | } | |
| | | | |
|
| | | /** | |
| | | * checks if mod is in the index by inspecting fieldName, and remov | |
| | | ing | |
| | | * .$ or .### substrings (#=digit) with any number of digits. | |
| | | * | |
| | | * @return true iff the mod is indexed | |
| | | */ | |
| bool isIndexed( const set<string>& idxKeys ) const { | | bool isIndexed( const set<string>& idxKeys ) const { | |
|
| string fullName = fieldName; | | string myFieldName = fieldName; | |
| | | | |
|
| if ( isIndexed( fullName , idxKeys ) ) | | // first, check if full name is in idxKeys | |
| | | if ( isIndexed( myFieldName , idxKeys ) ) | |
| return true; | | return true; | |
| | | | |
|
| if ( strstr( fieldName , "." ) ) { | | string x; | |
| // check for a.0.1 | | if ( getCanonicalIndexField( myFieldName, &x ) ) { | |
| StringBuilder buf; | | if ( isIndexed( x, idxKeys ) ) | |
| for ( size_t i=0; i<fullName.size(); i++ ) { | | | |
| char c = fullName[i]; | | | |
| | | | |
| if ( c == '$' && | | | |
| i > 0 && fullName[i-1] == '.' && | | | |
| i+1<fullName.size() && | | | |
| fullName[i+1] == '.' ) { | | | |
| i++; | | | |
| continue; | | | |
| } | | | |
| | | | |
| buf << c; | | | |
| | | | |
| if ( c != '.' ) | | | |
| continue; | | | |
| | | | |
| if ( ! isdigit( fullName[i+1] ) ) | | | |
| continue; | | | |
| | | | |
| bool possible = true; | | | |
| size_t j=i+2; | | | |
| for ( ; j<fullName.size(); j++ ) { | | | |
| char d = fullName[j]; | | | |
| if ( d == '.' ) | | | |
| break; | | | |
| if ( isdigit( d ) ) | | | |
| continue; | | | |
| possible = false; | | | |
| break; | | | |
| } | | | |
| | | | |
| if ( possible ) | | | |
| i = j; | | | |
| } | | | |
| string x = buf.str(); | | | |
| if ( isIndexed( x , idxKeys ) ) | | | |
| return true; | | return true; | |
| } | | } | |
| | | | |
| return false; | | return false; | |
| } | | } | |
| | | | |
| void apply( BSONBuilderBase& b , BSONElement in , ModState& ms ) co
nst; | | void apply( BSONBuilderBase& b , BSONElement in , ModState& ms ) co
nst; | |
| | | | |
| /** | | /** | |
| * @return true iff toMatch should be removed from the array | | * @return true iff toMatch should be removed from the array | |
| | | | |
End of changes. 6 change blocks. |
| 41 lines changed or deleted | | 20 lines changed or added | |
|