0
0
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:
Dwight 2011-04-19 10:31:26 -04:00
commit 6c9fe3bbfd
20 changed files with 257 additions and 245 deletions

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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();
}

View File

@ -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() {

View File

@ -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++ ) ) );

View File

@ -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;
}

View File

@ -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...
}

View File

@ -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;
}

View File

@ -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 ) {}
}

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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 );
}

View File

@ -108,7 +108,7 @@ void cleanup( int sig ) {
void myterminate() {
rawOut( "bridge terminate() called, printing stack:" );
printStackTrace();
abort();
::abort();
}
void setupSignals() {

View File

@ -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 {

View File

@ -27,7 +27,7 @@ namespace mongo {
void fail() {
log() << "synchronization (race condition) failure" << endl;
printStackTrace();
abort();
::abort();
}
void enter() {
if( ++n != 1 ) fail();

View File

@ -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;
}

View File

@ -431,7 +431,6 @@ namespace mongo {
string errnoWithPrefix( const char * prefix );
void Logstream::logLockless( const StringData& s ) {
if ( s.size() == 0 )
return;

View File

@ -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 ***

View File

@ -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;