mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
Merge branch 'master' of github.com:mongodb/mongo
This commit is contained in:
commit
6c9fe3bbfd
65
db/db.cpp
65
db/db.cpp
@ -24,6 +24,7 @@
|
||||
#include "../util/unittest.h"
|
||||
#include "../util/file_allocator.h"
|
||||
#include "../util/background.h"
|
||||
#include "../util/text.h"
|
||||
#include "dbmessage.h"
|
||||
#include "instance.h"
|
||||
#include "clientcursor.h"
|
||||
@ -51,6 +52,10 @@
|
||||
|
||||
namespace mongo {
|
||||
|
||||
namespace dur {
|
||||
extern unsigned long long DataLimitPerJournalFile;
|
||||
}
|
||||
|
||||
/* only off if --nocursors which is for debugging. */
|
||||
extern bool useCursors;
|
||||
|
||||
@ -774,6 +779,8 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
if (params.count("smallfiles")) {
|
||||
cmdLine.smallfiles = true;
|
||||
assert( dur::DataLimitPerJournalFile >= 128 * 1024 * 1024 );
|
||||
dur::DataLimitPerJournalFile = 128 * 1024 * 1024;
|
||||
}
|
||||
if (params.count("diaglog")) {
|
||||
int x = params["diaglog"].as<int>();
|
||||
@ -1045,7 +1052,7 @@ namespace mongo {
|
||||
void myterminate() {
|
||||
rawOut( "terminate() called, printing stack:" );
|
||||
printStackTrace();
|
||||
abort();
|
||||
::abort();
|
||||
}
|
||||
|
||||
void setupSignals_ignoreHelper( int signal ) {}
|
||||
@ -1114,19 +1121,63 @@ namespace mongo {
|
||||
}
|
||||
}
|
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER filtLast = 0;
|
||||
::HANDLE standardOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
LONG WINAPI exceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo) {
|
||||
{
|
||||
// given the severity of the event we write to console in addition to the --logFile
|
||||
// (rawOut writes to the logfile, if a special one were specified)
|
||||
DWORD written;
|
||||
WriteFile(standardOut, "unhandled exception\n", 20, &written, 0);
|
||||
FlushFileBuffers(standardOut);
|
||||
}
|
||||
|
||||
DWORD ec = ExceptionInfo->ExceptionRecord->ExceptionCode;
|
||||
if( ec == EXCEPTION_ACCESS_VIOLATION ) {
|
||||
rawOut("access violation");
|
||||
}
|
||||
else {
|
||||
rawOut("unhandled exception");
|
||||
char buf[64];
|
||||
strcpy(buf, "ec=0x");
|
||||
_ui64toa(ec, buf+5, 16);
|
||||
rawOut(buf);
|
||||
}
|
||||
if( filtLast )
|
||||
return filtLast(ExceptionInfo);
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
// called by mongoAbort()
|
||||
extern void (*reportEventToSystem)(const char *msg);
|
||||
void reportEventToSystemImpl(const char *msg) {
|
||||
static ::HANDLE hEventLog = RegisterEventSource( NULL, TEXT("mongod") );
|
||||
if( hEventLog ) {
|
||||
std::wstring s = toNativeString(msg);
|
||||
LPCTSTR txt = s.c_str();
|
||||
BOOL ok = ReportEvent(
|
||||
hEventLog, EVENTLOG_ERROR_TYPE,
|
||||
0, 0, NULL,
|
||||
1,
|
||||
0,
|
||||
&txt,
|
||||
0);
|
||||
wassert(ok);
|
||||
}
|
||||
}
|
||||
|
||||
void myPurecallHandler() {
|
||||
rawOut( "pure virtual method called, printing stack:" );
|
||||
printStackTrace();
|
||||
abort();
|
||||
mongoAbort("pure virtual");
|
||||
}
|
||||
|
||||
void setupSignals( bool inFork ) {
|
||||
if( SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE ) )
|
||||
;
|
||||
else
|
||||
massert( 10297 , "Couldn't register Windows Ctrl-C handler", false);
|
||||
reportEventToSystem = reportEventToSystemImpl;
|
||||
filtLast = SetUnhandledExceptionFilter(exceptionFilter);
|
||||
massert(10297 , "Couldn't register Windows Ctrl-C handler", SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE));
|
||||
_set_purecall_handler( myPurecallHandler );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace mongo
|
||||
|
18
db/dur.cpp
18
db/dur.cpp
@ -516,19 +516,19 @@ namespace mongo {
|
||||
}
|
||||
catch(DBException& e ) {
|
||||
log() << "dbexception in groupCommitLL causing immediate shutdown: " << e.toString() << endl;
|
||||
abort();
|
||||
mongoAbort("dur1");
|
||||
}
|
||||
catch(std::ios_base::failure& e) {
|
||||
log() << "ios_base exception in groupCommitLL causing immediate shutdown: " << e.what() << endl;
|
||||
abort();
|
||||
mongoAbort("dur2");
|
||||
}
|
||||
catch(std::bad_alloc& e) {
|
||||
log() << "bad_alloc exception in groupCommitLL causing immediate shutdown: " << e.what() << endl;
|
||||
abort();
|
||||
mongoAbort("dur3");
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
log() << "exception in dur::groupCommitLL causing immediate shutdown: " << e.what() << endl;
|
||||
abort();
|
||||
mongoAbort("dur4");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -602,19 +602,19 @@ namespace mongo {
|
||||
}
|
||||
catch(DBException& e ) {
|
||||
log() << "dbexception in groupCommit causing immediate shutdown: " << e.toString() << endl;
|
||||
abort();
|
||||
mongoAbort("gc1");
|
||||
}
|
||||
catch(std::ios_base::failure& e) {
|
||||
log() << "ios_base exception in groupCommit causing immediate shutdown: " << e.what() << endl;
|
||||
abort();
|
||||
mongoAbort("gc2");
|
||||
}
|
||||
catch(std::bad_alloc& e) {
|
||||
log() << "bad_alloc exception in groupCommit causing immediate shutdown: " << e.what() << endl;
|
||||
abort();
|
||||
mongoAbort("gc3");
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
log() << "exception in dur::groupCommit causing immediate shutdown: " << e.what() << endl;
|
||||
abort(); // based on myTerminate()
|
||||
mongoAbort("gc4");
|
||||
}
|
||||
}
|
||||
|
||||
@ -695,7 +695,7 @@ namespace mongo {
|
||||
}
|
||||
catch(std::exception& e) {
|
||||
log() << "exception in durThread causing immediate shutdown: " << e.what() << endl;
|
||||
abort(); // based on myTerminate()
|
||||
mongoAbort("exception in durThread");
|
||||
}
|
||||
}
|
||||
cc().shutdown();
|
||||
|
3
db/dur.h
3
db/dur.h
@ -9,6 +9,9 @@ namespace mongo {
|
||||
|
||||
class NamespaceDetails;
|
||||
|
||||
void mongoAbort(const char *msg);
|
||||
void abort(); // not defined -- use mongoAbort() instead
|
||||
|
||||
namespace dur {
|
||||
|
||||
// a smaller limit is likely better on 32 bit
|
||||
|
@ -42,6 +42,17 @@ namespace mongo {
|
||||
class AlignedBuilder;
|
||||
|
||||
namespace dur {
|
||||
// Rotate after reaching this data size in a journal (j._<n>) file
|
||||
// We use a smaller size for 32 bit as the journal is mmapped during recovery (only)
|
||||
// Note if you take a set of datafiles, including journal files, from 32->64 or vice-versa, it must
|
||||
// work. (and should as-is)
|
||||
// --smallfiles makes the limit small.
|
||||
#if defined(_DEBUG)
|
||||
unsigned long long DataLimitPerJournalFile = 128 * 1024 * 1024;
|
||||
#else
|
||||
unsigned long long DataLimitPerJournalFile = (sizeof(void*)==4) ? 256 * 1024 * 1024 : 1 * 1024 * 1024 * 1024;
|
||||
#endif
|
||||
|
||||
BOOST_STATIC_ASSERT( sizeof(Checksum) == 16 );
|
||||
BOOST_STATIC_ASSERT( sizeof(JHeader) == 8192 );
|
||||
BOOST_STATIC_ASSERT( sizeof(JSectHeader) == 20 );
|
||||
@ -289,7 +300,7 @@ namespace mongo {
|
||||
string fn = str::stream() << "prealloc." << i;
|
||||
filesystem::path filepath = getJournalDir() / fn;
|
||||
|
||||
unsigned long long limit = Journal::DataLimit;
|
||||
unsigned long long limit = DataLimitPerJournalFile;
|
||||
if( debug && i == 1 ) {
|
||||
// moving 32->64, the prealloc files would be short. that is "ok", but we want to exercise that
|
||||
// case, so we force exercising here when _DEBUG is set by arbitrarily stopping prealloc at a low
|
||||
@ -582,13 +593,11 @@ namespace mongo {
|
||||
|
||||
j.updateLSNFile();
|
||||
|
||||
if( _curLogFile && _written < DataLimit )
|
||||
if( _curLogFile && _written < DataLimitPerJournalFile )
|
||||
return;
|
||||
|
||||
if( _curLogFile ) {
|
||||
|
||||
closeCurrentJournalFile();
|
||||
|
||||
removeUnneededJournalFiles();
|
||||
}
|
||||
|
||||
|
@ -49,16 +49,6 @@ namespace mongo {
|
||||
unsigned long long lastFlushTime() const { return _lastFlushTime; }
|
||||
void cleanup(bool log);
|
||||
|
||||
// Rotate after reaching this data size in a journal (j._<n>) file
|
||||
// We use a smaller size for 32 bit as the journal is mmapped during recovery (only)
|
||||
// Note if you take a set of datafiles, including journal files, from 32->64 or vice-versa, it must
|
||||
// work. (and should as-is)
|
||||
#if defined(_DEBUG)
|
||||
static const unsigned long long DataLimit = 128 * 1024 * 1024;
|
||||
#else
|
||||
static const unsigned long long DataLimit = (sizeof(void*)==4) ? 256 * 1024 * 1024 : 1 * 1024 * 1024 * 1024;
|
||||
#endif
|
||||
|
||||
unsigned long long curFileId() const { return _curFileId; }
|
||||
|
||||
void assureLogFileOpen() {
|
||||
|
209
db/geo/2d.cpp
209
db/geo/2d.cpp
@ -163,6 +163,7 @@ namespace mongo {
|
||||
}
|
||||
|
||||
/** Finds all locations in a geo-indexed object */
|
||||
// TODO: Can we just return references to the locs, if they won't change?
|
||||
void getKeys( const BSONObj& obj, vector< BSONObj >& locs ) const {
|
||||
getKeys( obj, NULL, &locs );
|
||||
}
|
||||
@ -966,54 +967,33 @@ namespace mongo {
|
||||
//// Distance not used ////
|
||||
|
||||
GeoPoint( const KeyNode& node )
|
||||
: _key( node.key ) , _loc( node.recordLoc ) , _o( node.recordLoc.obj() ) , _distance( -1 ), _exactDistance( -1 ), _hopper( NULL ) {
|
||||
}
|
||||
|
||||
//// Lazy initialization of exact distance ////
|
||||
|
||||
GeoPoint( const KeyNode& node , double distance, GeoHopper* hopper )
|
||||
: _key( node.key ) , _loc( node.recordLoc ) , _o( node.recordLoc.obj() ) , _distance( distance ), _exactDistance( -1 ), _hopper( hopper ) {
|
||||
}
|
||||
|
||||
GeoPoint( const BSONObj& key , DiskLoc loc , double distance, GeoHopper* hopper )
|
||||
: _key(key) , _loc(loc) , _o( loc.obj() ) , _distance( distance ), _exactDistance( -1 ), _hopper( hopper ) {
|
||||
: _key( node.key ) , _loc( node.recordLoc ) , _o( node.recordLoc.obj() ) , _exactDistance( -1 ), _exactWithin( false ) {
|
||||
}
|
||||
|
||||
//// Immediate initialization of exact distance ////
|
||||
|
||||
GeoPoint( const KeyNode& node , double distance, double exactDistance, bool exactWithin, GeoHopper* hopper )
|
||||
: _key( node.key ) , _loc( node.recordLoc ) , _o( node.recordLoc.obj() ) , _distance( distance ), _exactDistance( exactDistance ), _exactWithin( exactWithin ), _hopper( hopper ) {
|
||||
GeoPoint( const KeyNode& node , double exactDistance, bool exactWithin )
|
||||
: _key( node.key ) , _loc( node.recordLoc ) , _o( node.recordLoc.obj() ), _exactDistance( exactDistance ), _exactWithin( exactWithin ) {
|
||||
}
|
||||
|
||||
GeoPoint( const BSONObj& key , DiskLoc loc , double distance, double exactDistance, bool exactWithin, GeoHopper* hopper )
|
||||
: _key(key) , _loc(loc) , _o( loc.obj() ) , _distance( distance ), _exactDistance( exactDistance ), _exactWithin( exactWithin ), _hopper( hopper ) {
|
||||
bool operator<( const GeoPoint& other ) const {
|
||||
return _exactDistance < other._exactDistance;
|
||||
}
|
||||
|
||||
double exactDistance();
|
||||
|
||||
bool exactWithin();
|
||||
|
||||
bool operator<( const GeoPoint& other ) const;
|
||||
|
||||
bool isEmpty() const {
|
||||
return _o.isEmpty();
|
||||
}
|
||||
|
||||
string toString() const {
|
||||
|
||||
return str::stream() << "Point from " << _o.toString() << " approx : " << _distance << " exact : " << _exactDistance
|
||||
<< " within ? " << _exactWithin;
|
||||
|
||||
return str::stream() << "Point from " << _o.toString() << " dist : " << _exactDistance << " within ? " << _exactWithin;
|
||||
}
|
||||
|
||||
BSONObj _key;
|
||||
DiskLoc _loc;
|
||||
BSONObj _o;
|
||||
double _distance;
|
||||
|
||||
double _exactDistance;
|
||||
bool _exactWithin;
|
||||
GeoHopper* _hopper;
|
||||
|
||||
};
|
||||
|
||||
@ -1104,8 +1084,8 @@ namespace mongo {
|
||||
public:
|
||||
typedef multiset<GeoPoint> Holder;
|
||||
|
||||
GeoHopper( const Geo2dType * g , unsigned max , const Point& n , const BSONObj& filter = BSONObj() , double maxDistance = numeric_limits<double>::max() , GeoDistType type=GEO_PLAIN, bool lazyExact = true )
|
||||
: GeoAccumulator( g , filter ) , _max( max ) , _near( n ), _maxDistance( maxDistance ), _type( type ), _distError( type == GEO_PLAIN ? g->_error : g->_errorSphere ), _approxFarthest(0), _lazyExact( lazyExact )
|
||||
GeoHopper( const Geo2dType * g , unsigned max , const Point& n , const BSONObj& filter = BSONObj() , double maxDistance = numeric_limits<double>::max() , GeoDistType type=GEO_PLAIN )
|
||||
: GeoAccumulator( g , filter ) , _max( max ) , _near( n ), _maxDistance( maxDistance ), _type( type ), _distError( type == GEO_PLAIN ? g->_error : g->_errorSphere ), _farthest(0)
|
||||
{}
|
||||
|
||||
virtual bool checkDistance( const KeyNode& node, double& d ) {
|
||||
@ -1117,14 +1097,10 @@ namespace mongo {
|
||||
d = approxDistance( node );
|
||||
assert( d >= 0 );
|
||||
|
||||
// If we're in the error range, return true
|
||||
if( inErrorBounds( d ) ) {
|
||||
// Should check exact point later in addSpecific()
|
||||
return true;
|
||||
}
|
||||
|
||||
// Out of the error range, see how close we are to the furthest points
|
||||
bool good = d < _maxDistance && ( _points.size() < _max || d < farthest() + 2 * _distError );
|
||||
bool good = d <= _maxDistance + 2 * _distError /* In error range */
|
||||
&& ( _points.size() < _max /* need more points */
|
||||
|| d <= farthest() + 2 * _distError /* could be closer than previous points */ );
|
||||
|
||||
GEODEBUG( "\t\t\t\t\t\t\t checkDistance " << _near.toString()
|
||||
<< "\t" << GeoHash( node.key.firstElement() ) << "\t" << d
|
||||
@ -1153,34 +1129,30 @@ namespace mongo {
|
||||
return approxDistance;
|
||||
}
|
||||
|
||||
double exactDistances( const KeyNode& node ) {
|
||||
|
||||
/** Evaluates exact distance for keys and documents, storing which locations were used so far */
|
||||
double exactDistance( const KeyNode& node, bool& exactWithin ) {
|
||||
return exactDistance( node.key, node.recordLoc.obj(), exactWithin );
|
||||
}
|
||||
|
||||
double exactDistance( const BSONObj& key, const BSONObj& doc, bool& exactWithin ) {
|
||||
|
||||
GEODEBUG( "Finding exact distance for " << key.toString() << " and " << doc.toString() );
|
||||
GEODEBUG( "Finding exact distance for " << node.key.toString() << " and " << node.recordLoc.obj().toString() );
|
||||
|
||||
// Find all the location objects from the keys
|
||||
vector< BSONObj > locs;
|
||||
_g->getKeys( doc, locs );
|
||||
_g->getKeys( node.recordLoc.obj(), locs );
|
||||
|
||||
double exactDistance = -1;
|
||||
double maxDistance = -1;
|
||||
|
||||
// Find the particular location we want
|
||||
BSONObj loc;
|
||||
GeoHash keyHash( key.firstElement(), _g->_bits );
|
||||
GeoHash keyHash( node.key.firstElement(), _g->_bits );
|
||||
for( vector< BSONObj >::iterator i = locs.begin(); i != locs.end(); ++i ) {
|
||||
|
||||
loc = *i;
|
||||
|
||||
// Ignore all locations we've used
|
||||
if( _usedLocs.end() != _usedLocs.find( loc.objdata() ) ) continue;
|
||||
// Ignore all locations not hashed to the key's hash
|
||||
// Ignore all locations not hashed to the key's hash, since we may see
|
||||
// those later
|
||||
if( _g->_hash( loc ) != keyHash ) continue;
|
||||
|
||||
double exactDistance = -1;
|
||||
bool exactWithin = false;
|
||||
|
||||
// Get the appropriate distance for the type
|
||||
switch ( _type ) {
|
||||
case GEO_PLAIN:
|
||||
@ -1194,20 +1166,24 @@ namespace mongo {
|
||||
default: assert( false );
|
||||
}
|
||||
|
||||
break;
|
||||
assert( exactDistance >= 0 );
|
||||
if( !exactWithin ) continue;
|
||||
|
||||
GEODEBUG( "Inserting exact point: " << GeoPoint( node , exactDistance, exactWithin ) );
|
||||
|
||||
// Add a point for this location
|
||||
_points.insert( GeoPoint( node , exactDistance, exactWithin ) );
|
||||
|
||||
if( exactDistance > maxDistance ) maxDistance = exactDistance;
|
||||
}
|
||||
|
||||
assert( exactDistance >= 0 );
|
||||
return maxDistance;
|
||||
|
||||
// Remember we used this sub-doc for this query
|
||||
_usedLocs.insert( loc.objdata() );
|
||||
|
||||
return exactDistance;
|
||||
}
|
||||
|
||||
// Always in distance units, whether radians or normal
|
||||
double farthest() const {
|
||||
return _approxFarthest;
|
||||
return _farthest;
|
||||
}
|
||||
|
||||
bool inErrorBounds( double approxD ) const {
|
||||
@ -1218,38 +1194,17 @@ namespace mongo {
|
||||
|
||||
GEODEBUG( "\t\t" << GeoHash( node.key.firstElement() ) << "\t" << node.recordLoc.obj() << "\t" << d );
|
||||
|
||||
if( _lazyExact && ! inErrorBounds( d ) ) {
|
||||
double maxDistance = exactDistances( node );
|
||||
if( maxDistance >= 0 ){
|
||||
|
||||
// Haven't yet looked up exact points, will look it up later
|
||||
_points.insert( GeoPoint( node.key , node.recordLoc , d , this ) );
|
||||
// Recalculate the current furthest point.
|
||||
int numToErase = _points.size() - _max;
|
||||
while( numToErase-- > 0 ){
|
||||
_points.erase( --_points.end() );
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
_farthest = boost::next( _points.end(), -1 )->_exactDistance;
|
||||
|
||||
// Look up exact point now.
|
||||
bool exactWithin;
|
||||
double exactD = exactDistance( node, exactWithin );
|
||||
|
||||
// Don't add the point if it's not actually in the range
|
||||
if( ! exactWithin ) return;
|
||||
|
||||
_points.insert( GeoPoint( node.key , node.recordLoc , d , exactD , exactWithin, this ) );
|
||||
}
|
||||
|
||||
// Recalculate the current furthest point.
|
||||
if ( _points.size() > _max ) {
|
||||
_points.erase( --_points.end() );
|
||||
|
||||
Holder::iterator i = _points.end();
|
||||
i--;
|
||||
|
||||
// Need to compensate for error both in the center point and in the current
|
||||
// point, hence 2 * error
|
||||
_approxFarthest = i->_distance;
|
||||
}
|
||||
else {
|
||||
if (d > _approxFarthest)
|
||||
_approxFarthest = d;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1259,58 +1214,10 @@ namespace mongo {
|
||||
double _maxDistance;
|
||||
GeoDistType _type;
|
||||
double _distError;
|
||||
double _approxFarthest;
|
||||
|
||||
bool _lazyExact;
|
||||
set< const char* > _usedLocs;
|
||||
double _farthest;
|
||||
|
||||
};
|
||||
|
||||
/** Caches and returns the exact distance of a point from the target location */
|
||||
double GeoPoint::exactDistance() {
|
||||
if( _exactDistance >= 0 ) return _exactDistance;
|
||||
|
||||
assert( _hopper );
|
||||
_exactDistance = _hopper->exactDistance( _key, _o, _exactWithin );
|
||||
assert( _exactDistance >= 0 );
|
||||
|
||||
return _exactDistance;
|
||||
}
|
||||
|
||||
|
||||
/** Caches and returns whether a point was found to be exactly in the bounds */
|
||||
bool GeoPoint::exactWithin() {
|
||||
if( _exactDistance >= 0 ) return _exactWithin;
|
||||
|
||||
// Get exact distance & within
|
||||
exactDistance();
|
||||
|
||||
return _exactWithin;
|
||||
}
|
||||
|
||||
bool GeoPoint::operator<( const GeoPoint& other ) const {
|
||||
|
||||
// We can only compare points when a distance was added!
|
||||
assert( _distance >= 0 );
|
||||
|
||||
// log() << "Comparing " << *this << " and " << other << " result : " << endl;
|
||||
|
||||
// Check if we need to use exact distance. Our distances may be off by up to 2 * the single-box error
|
||||
if( abs( _distance - other._distance ) <= 2 * _hopper->_distError ) {
|
||||
|
||||
// log() << " exact : " << (((GeoPoint*) this)->exactDistance() < ((GeoPoint&) other).exactDistance()) << " diff : " << (((GeoPoint*) this)->exactDistance() - ((GeoPoint&) other).exactDistance()) << endl;
|
||||
// cout << fixed << setprecision(20) << " Comparing " << ((GeoPoint*) this)->exactDistance() << " and " << ((GeoPoint&) other).exactDistance() << " result " << (((GeoPoint*) this)->exactDistance() < ((GeoPoint&) other).exactDistance()) << endl;
|
||||
|
||||
return ((GeoPoint*) this)->exactDistance() < ((GeoPoint&) other).exactDistance();
|
||||
}
|
||||
|
||||
// cout << fixed << setprecision(20) << "Inexact comparing " << _distance << " (" << ((GeoPoint*) this)->exactDistance() << ") and " << other._distance << " (" << ((GeoPoint&) other).exactDistance() << ") result : " << ( _distance < other._distance ) << " error : " << _hopper->_g->_error << endl;
|
||||
// log() << " inexact : " << (_distance < other._distance) << " diff : " << (_distance - other._distance) << endl;
|
||||
|
||||
return _distance < other._distance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct BtreeLocation {
|
||||
int pos;
|
||||
@ -1392,10 +1299,10 @@ namespace mongo {
|
||||
|
||||
class GeoSearch {
|
||||
public:
|
||||
GeoSearch( const Geo2dType * g , const Point& startPt , int numWanted=100 , BSONObj filter=BSONObj() , double maxDistance = numeric_limits<double>::max() , GeoDistType type=GEO_PLAIN, bool lazyExact = true )
|
||||
GeoSearch( const Geo2dType * g , const Point& startPt , int numWanted=100 , BSONObj filter=BSONObj() , double maxDistance = numeric_limits<double>::max() , GeoDistType type=GEO_PLAIN )
|
||||
: _spec( g ) ,_startPt( startPt ), _start( g->hash( startPt._x, startPt._y ) ) ,
|
||||
_numWanted( numWanted ) , _filter( filter ) , _maxDistance( maxDistance ) ,
|
||||
_hopper( new GeoHopper( g , numWanted , _startPt , filter , maxDistance, type, lazyExact ) ), _type(type) {
|
||||
_hopper( new GeoHopper( g , numWanted , _startPt , filter , maxDistance, type ) ), _type(type) {
|
||||
assert( g->getDetails() );
|
||||
_nscanned = 0;
|
||||
_found = 0;
|
||||
@ -1631,29 +1538,7 @@ namespace mongo {
|
||||
virtual ~GeoSearchCursor() {}
|
||||
|
||||
virtual bool ok() {
|
||||
if( _cur == _end ) return false;
|
||||
|
||||
// If we're near the bounds of our range and did lazy distance loading,
|
||||
// test the exact locations.
|
||||
|
||||
if( _s->_hopper->_lazyExact ) {
|
||||
|
||||
GeoPoint& point = (GeoPoint&) *_cur;
|
||||
|
||||
if( abs( _s->_maxDistance - point._distance ) <= 2 * _s->_hopper->_distError ) {
|
||||
|
||||
GEODEBUG( point.toString() );
|
||||
|
||||
// Must check within, not distance, b/c of double precision errors
|
||||
if( ! point.exactWithin() ) {
|
||||
GEODEBUG( "Final point : " ); //<< _cur->_o.toString() << _cur->_distance << " exact : " << ((GeoPoint) _cur).exactDistance() );
|
||||
_cur = _end;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return _cur != _end;
|
||||
}
|
||||
|
||||
virtual Record* _current() { assert(ok()); return _cur->_loc.rec(); }
|
||||
@ -2470,7 +2355,7 @@ namespace mongo {
|
||||
type = GEO_SPHERE;
|
||||
|
||||
// We're returning exact distances, so don't evaluate lazily.
|
||||
GeoSearch gs( g , n , numWanted , filter , maxDistance , type, false );
|
||||
GeoSearch gs( g , n , numWanted , filter , maxDistance , type );
|
||||
|
||||
if ( cmdObj["start"].type() == String) {
|
||||
GeoHash start ((string) cmdObj["start"].valuestr());
|
||||
@ -2491,7 +2376,7 @@ namespace mongo {
|
||||
for ( GeoHopper::Holder::iterator i=gs._hopper->_points.begin(); i!=gs._hopper->_points.end(); i++ ) {
|
||||
|
||||
const GeoPoint& p = *i;
|
||||
double dis = distanceMultiplier * ((GeoPoint&) p).exactDistance();
|
||||
double dis = distanceMultiplier * p._exactDistance;
|
||||
totalDistance += dis;
|
||||
|
||||
BSONObjBuilder bb( arr.subobjStart( BSONObjBuilder::numStr( x++ ) ) );
|
||||
|
@ -220,6 +220,15 @@ namespace mongo {
|
||||
return ok;
|
||||
}
|
||||
|
||||
void (*reportEventToSystem)(const char *msg) = 0;
|
||||
|
||||
void mongoAbort(const char *msg) {
|
||||
if( reportEventToSystem )
|
||||
reportEventToSystem(msg);
|
||||
rawOut(msg);
|
||||
::abort();
|
||||
}
|
||||
|
||||
// Returns false when request includes 'end'
|
||||
void assembleResponse( Message &m, DbResponse &dbresponse, const HostAndPort& remote ) {
|
||||
|
||||
@ -755,7 +764,7 @@ namespace mongo {
|
||||
}
|
||||
if( --n <= 0 ) {
|
||||
log() << "shutdown: couldn't acquire write lock, aborting" << endl;
|
||||
abort();
|
||||
mongoAbort("couldn't acquire write lock");
|
||||
}
|
||||
log() << "shutdown: waiting for write lock..." << endl;
|
||||
}
|
||||
|
@ -82,7 +82,10 @@ namespace mongo {
|
||||
void *p = MapViewOfFile(maphandle, FILE_MAP_READ, 0, 0, 0);
|
||||
if ( p == 0 ) {
|
||||
DWORD e = GetLastError();
|
||||
log() << "createPrivateMap failed " << filename() << " " << errnoWithDescription(e) << endl;
|
||||
log() << "createPrivateMap failed " << filename() << " " <<
|
||||
errnoWithDescription(e) << " filelen:" << len <<
|
||||
((sizeof(void*) == 4 ) ? " (32 bit build)" : "") <<
|
||||
endl;
|
||||
}
|
||||
else {
|
||||
clearWritableBits(p);
|
||||
@ -280,7 +283,7 @@ namespace mongo {
|
||||
if( cmdLine.dur ) {
|
||||
_view_private = createPrivateMap();
|
||||
if( _view_private == 0 ) {
|
||||
massert( 13636 , "createPrivateMap failed (look in log for error)" , false );
|
||||
msgasserted(13636, str::stream() << "file " << filename() << " open/create failed in createPrivateMap (look in log for more information)");
|
||||
}
|
||||
privateViews.add(_view_private, this); // note that testIntent builds use this, even though it points to view_write then...
|
||||
}
|
||||
|
@ -341,17 +341,13 @@ namespace mongo {
|
||||
|
||||
int MongoDataFile::defaultSize( const char *filename ) const {
|
||||
int size;
|
||||
|
||||
if ( fileNo <= 4 )
|
||||
size = (64*1024*1024) << fileNo;
|
||||
else
|
||||
size = 0x7ff00000;
|
||||
|
||||
if ( cmdLine.smallfiles ) {
|
||||
size = size >> 2;
|
||||
}
|
||||
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
@ -170,7 +170,7 @@ namespace mongo {
|
||||
|
||||
if (minutesRunning > 30){
|
||||
log() << currentTestName << " has been running for more than 30 minutes. aborting." << endl;
|
||||
abort();
|
||||
::abort();
|
||||
}
|
||||
else if (minutesRunning > 1){
|
||||
warning() << currentTestName << " has been running for more than " << minutesRunning-1 << " minutes." << endl;
|
||||
@ -422,4 +422,5 @@ namespace mongo {
|
||||
}
|
||||
|
||||
void setupSignals( bool inFork ) {}
|
||||
|
||||
}
|
||||
|
@ -64,7 +64,9 @@ namespace ThreadedTests {
|
||||
enum { N = 40000 };
|
||||
#endif
|
||||
MongoMutex *mm;
|
||||
ProgressMeter pm;
|
||||
public:
|
||||
MongoMutexTest() : pm(N * nthreads) {}
|
||||
void run() {
|
||||
Timer t;
|
||||
cout << "MongoMutexTest N:" << N << endl;
|
||||
@ -121,6 +123,7 @@ namespace ThreadedTests {
|
||||
mm->lock_shared();
|
||||
mm->unlock_shared();
|
||||
}
|
||||
pm.hit();
|
||||
}
|
||||
cc().shutdown();
|
||||
}
|
||||
|
@ -1,28 +1,32 @@
|
||||
//
|
||||
// Tests the error handling of spherical queries
|
||||
// along with multi-location documents.
|
||||
// This is necessary since the error handling must manage
|
||||
// multiple documents, and so requires simultaneous testing.
|
||||
//
|
||||
|
||||
var numTests = 30
|
||||
|
||||
for ( var test = 0; test < numTests; test++ ) {
|
||||
|
||||
|
||||
//var fixedTest = 6017
|
||||
//if( fixedTest ) test = fixedTest
|
||||
|
||||
Random.srand( 1337 + test );
|
||||
|
||||
|
||||
var radius = 5000 * Random.rand() // km
|
||||
radius = radius / 6371 // radians
|
||||
var numPoints = Math.floor( 3000 * Random.rand() )
|
||||
var numDocs = Math.floor( 400 * Random.rand() )
|
||||
// TODO: Wrapping uses the error value to figure out what would overlap...
|
||||
var bits = Math.floor( 5 + Random.rand() * 28 )
|
||||
|
||||
var maxPointsPerDoc = 50
|
||||
|
||||
t = db.sphere
|
||||
|
||||
var randomPoint = function() {
|
||||
return [ Random.rand() * 360 - 180, Random.rand() * 180 - 90 ];
|
||||
}
|
||||
|
||||
var pointsIn = 0
|
||||
var pointsOut = 0
|
||||
|
||||
// Get a start point that doesn't require wrapping
|
||||
// TODO: Are we a bit too aggressive with wrapping issues?
|
||||
var startPoint
|
||||
@ -42,56 +46,113 @@ for ( var test = 0; test < numTests; test++ ) {
|
||||
}
|
||||
} while (ex)
|
||||
|
||||
for ( var i = 0; i < numPoints; i++ ) {
|
||||
var pointsIn = 0
|
||||
var pointsOut = 0
|
||||
var docsIn = 0
|
||||
var docsOut = 0
|
||||
var totalPoints = 0
|
||||
|
||||
//var point = randomPoint()
|
||||
|
||||
for ( var i = 0; i < numDocs; i++ ) {
|
||||
|
||||
var point = randomPoint()
|
||||
var numPoints = Math.floor( Random.rand() * maxPointsPerDoc + 1 )
|
||||
var docIn = false
|
||||
var multiPoint = []
|
||||
|
||||
totalPoints += numPoints
|
||||
|
||||
for ( var p = 0; p < numPoints; p++ ) {
|
||||
var point = randomPoint()
|
||||
multiPoint.push( point )
|
||||
|
||||
t.insert( { loc : point } )
|
||||
if ( Geo.sphereDistance( startPoint, point ) <= radius ) {
|
||||
pointsIn++
|
||||
docIn = true
|
||||
} else {
|
||||
pointsOut++
|
||||
}
|
||||
}
|
||||
|
||||
if ( Geo.sphereDistance( startPoint, point ) <= radius )
|
||||
pointsIn++;
|
||||
t.insert( { loc : multiPoint } )
|
||||
|
||||
if ( docIn )
|
||||
docsIn++
|
||||
else
|
||||
pointsOut++;
|
||||
docsOut++
|
||||
|
||||
}
|
||||
|
||||
assert.isnull( db.getLastError() )
|
||||
printjson( { test: test,
|
||||
radius : radius, bits : bits, numDocs : numDocs, pointsIn : pointsIn, docsIn : docsIn, pointsOut : pointsOut,
|
||||
docsOut : docsOut } )
|
||||
|
||||
assert.isnull( db.getLastError() )
|
||||
assert.eq( docsIn + docsOut, numDocs )
|
||||
assert.eq( pointsIn + pointsOut, totalPoints )
|
||||
|
||||
printjson( { radius : radius, numPoints : numPoints, pointsIn : pointsIn, pointsOut : pointsOut } )
|
||||
|
||||
// $centerSphere
|
||||
assert.eq( pointsIn , t.find( { loc : { $within : { $centerSphere : [ startPoint, radius ] } } } ).count() )
|
||||
assert.eq( docsIn, t.find( { loc : { $within : { $centerSphere : [ startPoint, radius ] } } } ).count() )
|
||||
|
||||
// $nearSphere
|
||||
var results = t.find( { loc : { $nearSphere : startPoint, $maxDistance : radius } } ).limit(2 * pointsIn).toArray()
|
||||
assert.eq( pointsIn , results.length )
|
||||
var results = t.find( { loc : { $nearSphere : startPoint, $maxDistance : radius } } ).limit( 2 * pointsIn )
|
||||
.toArray()
|
||||
|
||||
assert.eq( pointsIn, results.length )
|
||||
|
||||
var distance = 0;
|
||||
for( var i = 0; i < results.length; i++ ){
|
||||
var newDistance = Geo.sphereDistance( startPoint, results[i].loc )
|
||||
// print( "Dist from : " + results[i].loc + " to " + startPoint + " is " + newDistance + " vs " + radius )
|
||||
assert.lte( newDistance, radius )
|
||||
assert.gte( newDistance, distance )
|
||||
distance = newDistance
|
||||
for ( var i = 0; i < results.length; i++ ) {
|
||||
|
||||
var minNewDistance = radius + 1
|
||||
for( var j = 0; j < results[i].loc.length; j++ ){
|
||||
var newDistance = Geo.sphereDistance( startPoint, results[i].loc[j] )
|
||||
if( newDistance < minNewDistance && newDistance >= distance ) minNewDistance = newDistance
|
||||
}
|
||||
|
||||
//print( "Dist from : " + results[i].loc[j] + " to " + startPoint + " is "
|
||||
// + minNewDistance + " vs " + radius )
|
||||
|
||||
assert.lte( minNewDistance, radius )
|
||||
assert.gte( minNewDistance, distance )
|
||||
distance = minNewDistance
|
||||
|
||||
}
|
||||
|
||||
// geoNear
|
||||
var results = db.runCommand({ geoNear : "sphere", near : startPoint, maxDistance : radius, num : 2 * pointsIn, spherical : true }).results
|
||||
assert.eq( pointsIn , results.length )
|
||||
var results = db.runCommand( {
|
||||
geoNear : "sphere", near : startPoint, maxDistance : radius, num : 2 * pointsIn, spherical : true } ).results
|
||||
|
||||
/*
|
||||
printjson( results );
|
||||
|
||||
for ( var j = 0; j < results[0].obj.loc.length; j++ ) {
|
||||
var newDistance = Geo.sphereDistance( startPoint, results[0].obj.loc[j] )
|
||||
if( newDistance <= radius ) print( results[0].obj.loc[j] + " : " + newDistance )
|
||||
}
|
||||
*/
|
||||
|
||||
assert.eq( pointsIn, results.length )
|
||||
|
||||
var distance = 0;
|
||||
for( var i = 0; i < results.length; i++ ){
|
||||
for ( var i = 0; i < results.length; i++ ) {
|
||||
var retDistance = results[i].dis
|
||||
var newDistance = Geo.sphereDistance( startPoint, results[i].obj.loc )
|
||||
// print( "Dist from : " + results[i].loc + " to " + startPoint + " is " + newDistance + " vs " + radius )
|
||||
assert( newDistance >= retDistance - 0.0001 && newDistance <= retDistance + 0.0001 )
|
||||
|
||||
// print( "Dist from : " + results[i].loc + " to " + startPoint + " is "
|
||||
// + retDistance + " vs " + radius )
|
||||
|
||||
var distInObj = false
|
||||
for ( var j = 0; j < results[i].obj.loc.length && distInObj == false; j++ ) {
|
||||
var newDistance = Geo.sphereDistance( startPoint, results[i].obj.loc[j] )
|
||||
distInObj = ( newDistance >= retDistance - 0.0001 && newDistance <= retDistance + 0.0001 )
|
||||
}
|
||||
|
||||
assert( distInObj )
|
||||
assert.lte( retDistance, radius )
|
||||
assert.gte( retDistance, distance )
|
||||
assert.lte( newDistance, radius )
|
||||
assert.gte( newDistance, distance )
|
||||
distance = retDistance
|
||||
}
|
||||
|
||||
|
||||
|
||||
//break;
|
||||
}
|
||||
|
||||
|
||||
|
@ -707,7 +707,7 @@ namespace mongo {
|
||||
}
|
||||
|
||||
log() << "ChunkManager: couldn't find chunk for: " << key << " going to retry" << endl;
|
||||
_reload_inlock();
|
||||
_reload();
|
||||
return findChunk( obj , true );
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ void cleanup( int sig ) {
|
||||
void myterminate() {
|
||||
rawOut( "bridge terminate() called, printing stack:" );
|
||||
printStackTrace();
|
||||
abort();
|
||||
::abort();
|
||||
}
|
||||
|
||||
void setupSignals() {
|
||||
|
@ -257,7 +257,7 @@ public:
|
||||
cerr << "Error creating index " << o["ns"].String();
|
||||
cerr << ": " << err["code"].Int() << " " << err["err"].String() << endl;
|
||||
cerr << "To resume index restoration, run " << _name << " on file" << _fileName << " manually." << endl;
|
||||
abort();
|
||||
::abort();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -27,7 +27,7 @@ namespace mongo {
|
||||
void fail() {
|
||||
log() << "synchronization (race condition) failure" << endl;
|
||||
printStackTrace();
|
||||
abort();
|
||||
::abort();
|
||||
}
|
||||
void enter() {
|
||||
if( ++n != 1 ) fail();
|
||||
|
@ -19,8 +19,8 @@
|
||||
#include "pch.h"
|
||||
#include "assert_util.h"
|
||||
#include "assert.h"
|
||||
//#include "file.h"
|
||||
#include <cmath>
|
||||
#include "time_support.h"
|
||||
using namespace std;
|
||||
|
||||
#ifndef _WIN32
|
||||
@ -28,7 +28,7 @@ using namespace std;
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
|
||||
#include "../db/jsobj.h"
|
||||
//#include "../db/jsobj.h"
|
||||
|
||||
namespace mongo {
|
||||
|
||||
@ -84,7 +84,7 @@ namespace mongo {
|
||||
|
||||
if ( _file ) {
|
||||
#ifdef _WIN32
|
||||
cout << "log rotation doesn't work on windows" << endl;
|
||||
cout << "log rotation net yet supported on windows" << endl;
|
||||
return;
|
||||
#else
|
||||
struct tm t;
|
||||
@ -135,4 +135,3 @@ namespace mongo {
|
||||
FILE* Logstream::logfile = stdout;
|
||||
|
||||
}
|
||||
|
||||
|
@ -431,7 +431,6 @@ namespace mongo {
|
||||
string errnoWithPrefix( const char * prefix );
|
||||
|
||||
void Logstream::logLockless( const StringData& s ) {
|
||||
|
||||
if ( s.size() == 0 )
|
||||
return;
|
||||
|
||||
|
@ -11,3 +11,5 @@
|
||||
|
||||
So basically, easy to use, general purpose stuff, with no arduous dependencies to drop into
|
||||
any new project.
|
||||
|
||||
*** PLACE UNIT TESTS IN mongoutils/test.cpp ***
|
||||
|
@ -184,7 +184,8 @@ namespace mongo {
|
||||
|
||||
/* note: can't use malloc herein - may be in signal handler.
|
||||
logLockless() likely does not comply and should still be fixed todo
|
||||
*/
|
||||
likewise class string?
|
||||
*/
|
||||
void rawOut( const string &s ) {
|
||||
if( s.empty() ) return;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user