mu::MuStream *setup() { PString *p = new PString(); p->pluck(frs("31.wav"), beat_to_tick(0.00), 1.0); p->pluck(frs("36.wav"), beat_to_tick(1.50), 1.0); p->pluck(frs("29.wav"), beat_to_tick(4.00), 1.0); p->pluck(frs("38.wav"), beat_to_tick(5.50), 1.0); p->dampen(beat_to_tick(8.00)); mu::LoopStream *loop_stream = new mu::LoopStream(); loop_stream->set_source(p->stream()); loop_stream->set_interval(beat_to_tick(8.00)); loop_stream->set_source_end(beat_to_tick(8.00)); return loop_stream; }
void check( const BSONObj &spec ) { { BSONObj keypat = idx(); //cout << keypat.toString() << endl; _c.ensureIndex( ns(), idx() ); } Client::Context ctx( ns() ); FieldRangeSet frs( ns(), spec, true ); // orphan spec for this test. IndexSpec *idxSpec = new IndexSpec( idx() ); boost::shared_ptr< FieldRangeVector > frv( new FieldRangeVector( frs, *idxSpec, direction() ) ); scoped_ptr<BtreeCursor> c( BtreeCursor::make( nsdetails( ns() ), 1, nsdetails( ns() )->idx( 1 ), frv, direction() ) ); Matcher m( spec ); int count = 0; while( c->ok() ) { ASSERT( m.matches( c->current() ) ); c->advance(); ++count; } int expectedCount = 0; for( vector< BSONObj >::const_iterator i = _objs.begin(); i != _objs.end(); ++i ) { if ( m.matches( *i ) ) { ++expectedCount; } } ASSERT_EQUALS( expectedCount, count ); }
Bool GFXFont::read( const char *in_name ) { Bool success; HANDLE fileHandle; // handle of opened file fileHandle = CreateFile(in_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if ( fileHandle == INVALID_HANDLE_VALUE ) { AssertWarn(0, avar("GFXFont::load: Unable to load font %s, CreateFile for reading failed.", in_name)); return FALSE; } FileRStream frs(fileHandle); success = read( &frs ); frs.close(); CloseHandle( fileHandle ); if ( success ) return TRUE; else { AssertWarn(0, avar("GFXFont::load: Unable to load font %s, StreamIO for reading failed.", in_name)); return FALSE; } }
//================================================================ // NAME // GFXBitmapArray::read // // DESCRIPTION // // // ARGUMENTS // // // RETURNS // // // NOTES // //================================================================ Bool GFXBitmapArray::read(const char *in_filename, DWORD in_flags) { Bool result; HANDLE fileHandle; fileHandle = CreateFile(in_filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (fileHandle == INVALID_HANDLE_VALUE) { AssertWarn(0, avar("GFXBitmapArray::load: Unable to open file %s, CreateFile for reading failed.", in_filename)); return (FALSE); } FileRStream frs(fileHandle); result = read(&frs, in_flags); frs.close(); CloseHandle(fileHandle); return(result); }
void S2SimpleCursor::seek(const BSONObj& query, const vector<GeoQuery>& regions) { _nscanned = 0; _matchTested = 0; _geoTested = 0; _fields = regions; _seen = unordered_set<DiskLoc, DiskLoc::Hasher>(); BSONObjBuilder geoFieldsToNuke; for (size_t i = 0; i < _fields.size(); ++i) { geoFieldsToNuke.append(_fields[i].getField(), ""); } // false means we want to filter OUT geoFieldsToNuke, not filter to include only that. _filteredQuery = query.filterFieldsUndotted(geoFieldsToNuke.obj(), false); BSONObjBuilder specBuilder; BSONObjIterator i(_descriptor->keyPattern()); while (i.more()) { BSONElement e = i.next(); // Checked in AccessMethod already, so we know this spec has only numbers and 2dsphere if ( e.type() == String ) { specBuilder.append( e.fieldName(), 1 ); } else { specBuilder.append( e.fieldName(), e.numberInt() ); } } BSONObj spec = specBuilder.obj(); BSONObj frsObj; BSONObjBuilder frsObjBuilder; frsObjBuilder.appendElements(_filteredQuery); S2RegionCoverer coverer; for (size_t i = 0; i < _fields.size(); ++i) { vector<S2CellId> cover; double area = _fields[i].getRegion().GetRectBound().Area(); S2SearchUtil::setCoverLimitsBasedOnArea(area, &coverer, _params.coarsestIndexedLevel); coverer.GetCovering(_fields[i].getRegion(), &cover); uassert(16759, "No cover ARGH?!", cover.size() > 0); _cellsInCover = cover.size(); BSONObj fieldRange = S2SearchUtil::coverAsBSON(cover, _fields[i].getField(), _params.coarsestIndexedLevel); frsObjBuilder.appendElements(fieldRange); } frsObj = frsObjBuilder.obj(); FieldRangeSet frs(_descriptor->parentNS().c_str(), frsObj, false, false); shared_ptr<FieldRangeVector> frv(new FieldRangeVector(frs, spec, 1)); _btreeCursor.reset(BtreeCursor::make(nsdetails(_descriptor->parentNS()), _descriptor->getOnDisk(), frv, 0, 1)); next(); }
Status HashIndexCursor::seek(const BSONObj& position) { //Use FieldRangeSet to parse the query into a vector of intervals //These should be point-intervals if this cursor is ever used //So the FieldInterval vector will be, e.g. <[1,1], [3,3], [6,6]> FieldRangeSet frs( "" , position, true, true ); const vector<FieldInterval>& intervals = frs.range( _hashedField.c_str() ).intervals(); //Construct a new query based on the hashes of the previous point-intervals //e.g. {a : {$in : [ hash(1) , hash(3) , hash(6) ]}} BSONObjBuilder newQueryBuilder; BSONObjBuilder inObj( newQueryBuilder.subobjStart( _hashedField ) ); BSONArrayBuilder inArray( inObj.subarrayStart("$in") ); vector<FieldInterval>::const_iterator i; for( i = intervals.begin(); i != intervals.end(); ++i ){ if ( ! i->equality() ){ _oldCursor.reset( BtreeCursor::make( nsdetails( _descriptor->parentNS()), _descriptor->getOnDisk(), BSON( "" << MINKEY ) , BSON( "" << MAXKEY ) , true , 1 ) ); return Status::OK(); } inArray.append(HashAccessMethod::makeSingleKey(i->_lower._bound, _seed, _hashVersion)); } inArray.done(); inObj.done(); BSONObj newQuery = newQueryBuilder.obj(); // FieldRangeVector needs an IndexSpec so we make it one. BSONObjBuilder specBuilder; BSONObjIterator it(_descriptor->keyPattern()); while (it.more()) { BSONElement e = it.next(); specBuilder.append(e.fieldName(), 1); } BSONObj spec = specBuilder.obj(); IndexSpec specForFRV(spec); //Use the point-intervals of the new query to create a Btree cursor FieldRangeSet newfrs( "" , newQuery , true, true ); shared_ptr<FieldRangeVector> newVector( new FieldRangeVector( newfrs , specForFRV, 1 ) ); _oldCursor.reset( BtreeCursor::make(nsdetails(_descriptor->parentNS()), _descriptor->getOnDisk(), newVector, 0, 1)); return Status::OK(); }
shared_ptr<Cursor> HashedIndexType::newCursor( const BSONObj& query , const BSONObj& order , int numWanted ) const { //Use FieldRangeSet to parse the query into a vector of intervals //These should be point-intervals if this cursor is ever used //So the FieldInterval vector will be, e.g. <[1,1], [3,3], [6,6]> FieldRangeSet frs( "" , query , true, true ); const vector<FieldInterval>& intervals = frs.range( _hashedField.c_str() ).intervals(); //Force a match of the query against the actual document by giving //the cursor a matcher with an empty indexKeyPattern. This insures the //index is not used as a covered index. //NOTE: this forcing is necessary due to potential hash collisions const shared_ptr< CoveredIndexMatcher > forceDocMatcher( new CoveredIndexMatcher( query , BSONObj() ) ); //Construct a new query based on the hashes of the previous point-intervals //e.g. {a : {$in : [ hash(1) , hash(3) , hash(6) ]}} BSONObjBuilder newQueryBuilder; BSONObjBuilder inObj( newQueryBuilder.subobjStart( _hashedField ) ); BSONArrayBuilder inArray( inObj.subarrayStart("$in") ); vector<FieldInterval>::const_iterator i; for( i = intervals.begin(); i != intervals.end(); ++i ){ if ( ! i->equality() ){ const shared_ptr< BtreeCursor > exhaustiveCursor( BtreeCursor::make( nsdetails( _spec->getDetails()->parentNS().c_str()), *( _spec->getDetails() ), BSON( "" << MINKEY ) , BSON( "" << MAXKEY ) , true , 1 ) ); exhaustiveCursor->setMatcher( forceDocMatcher ); return exhaustiveCursor; } inArray.append( makeSingleKey( i->_lower._bound , _seed , _hashVersion ) ); } inArray.done(); inObj.done(); BSONObj newQuery = newQueryBuilder.obj(); //Use the point-intervals of the new query to create a Btree cursor FieldRangeSet newfrs( "" , newQuery , true, true ); shared_ptr<FieldRangeVector> newVector( new FieldRangeVector( newfrs , *_spec , 1 ) ); const shared_ptr< BtreeCursor > cursor( BtreeCursor::make( nsdetails( _spec->getDetails()->parentNS().c_str()), *( _spec->getDetails() ), newVector , 1 ) ); cursor->setMatcher( forceDocMatcher ); return cursor; }
void run() { dblock lk; IndexSpec idx( BSON( "a" << 1 << "b" << 1 ) ); _c.ensureIndex( ns(), idx.keyPattern ); for( int i = 0; i < 300; ++i ) { _c.insert( ns(), BSON( "a" << i << "b" << 5 ) ); } FieldRangeSet frs( ns(), BSON( "b" << 3 ), true ); boost::shared_ptr<FieldRangeVector> frv( new FieldRangeVector( frs, idx, 1 ) ); Client::Context ctx( ns() ); scoped_ptr<BtreeCursor> c( BtreeCursor::make( nsdetails( ns() ), 1, nsdetails( ns() )->idx(1), frv, 1 ) ); long long initialNscanned = c->nscanned(); ASSERT( initialNscanned < 200 ); ASSERT( c->ok() ); c->advance(); ASSERT( c->nscanned() > initialNscanned ); ASSERT( c->nscanned() < 200 ); ASSERT( c->ok() ); }
GFXFont* GFXFont::load(const char *in_name) { HANDLE fileHandle = CreateFile(in_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if ( fileHandle == INVALID_HANDLE_VALUE ) { AssertWarn(0, avar("GFXFont::load: Unable to load font %s, CreateFile for reading failed.", in_name)); return(FALSE); } FileRStream frs(fileHandle); GFXFont *font = load(&frs); frs.close(); CloseHandle(fileHandle); return(font); }
void check( const BSONObj &spec ) { _c.ensureIndex( ns(), idx() ); Client::Context ctx( ns() ); FieldRangeSet frs( ns(), spec ); boost::shared_ptr< FieldRangeVector > frv( new FieldRangeVector( frs, idx(), direction() ) ); BtreeCursor c( nsdetails( ns() ), 1, nsdetails( ns() )->idx( 1 ), frv, direction() ); Matcher m( spec ); int count = 0; while( c.ok() ) { ASSERT( m.matches( c.current() ) ); c.advance(); ++count; } int expectedCount = 0; for( vector< BSONObj >::const_iterator i = _objs.begin(); i != _objs.end(); ++i ) { if ( m.matches( *i ) ) { ++expectedCount; } } ASSERT_EQUALS( expectedCount, count ); }
bool S2Cursor::ok() { if (NULL == _btreeCursor.get()) { // FieldRangeVector needs an IndexSpec so we make it one. BSONObjBuilder specBuilder; BSONObjIterator i(_keyPattern); while (i.more()) { BSONElement e = i.next(); specBuilder.append(e.fieldName(), 1); } BSONObj spec = specBuilder.obj(); IndexSpec specForFRV(spec); // All the magic is in makeUnifiedFRS. See below. // A lot of these arguments are opaque. BSONObj frsObj; if (!makeFRSObject(&frsObj)) { return false; } FieldRangeSet frs(_details->parentNS().c_str(), frsObj, false, false); shared_ptr<FieldRangeVector> frv(new FieldRangeVector(frs, specForFRV, 1)); _btreeCursor.reset(BtreeCursor::make(nsdetails(_details->parentNS()), *_details, frv, 0, 1)); return advance(); } return _btreeCursor->ok(); }
// Fill _results with the next shell of results. We may have to search several times to do // this. If _results.empty() after calling fillResults, there are no more possible results. void S2NearCursor::fillResults() { verify(_results.empty()); if (_innerRadius >= _outerRadius) { return; } if (_innerRadius > _maxDistance) { return; } // We iterate until 1. our search radius is too big or 2. we find results. do { // Some of these arguments are opaque, look at the definitions of the involved classes. FieldRangeSet frs(_details->parentNS().c_str(), makeFRSObject(), false, false); shared_ptr<FieldRangeVector> frv(new FieldRangeVector(frs, _specForFRV, 1)); scoped_ptr<BtreeCursor> cursor(BtreeCursor::make(nsdetails(_details->parentNS().c_str()), *_details, frv, 0, 1)); // Do the actual search through this annulus. size_t considered = 0; for (; cursor->ok(); cursor->advance()) { ++_nscanned; ++considered; MatchDetails details; bool matched = _matcher->matchesCurrent(cursor.get(), &details); if (!matched) { continue; } const BSONObj& indexedObj = cursor->currLoc().obj(); size_t geoFieldsInRange = 0; double minMatchingDistance = 1e20; // Calculate the distance from our query point(s) to the geo field(s). for (size_t i = 0; i < _fields.size(); ++i) { const GeoQueryField& field = _fields[i]; BSONElementSet geoFieldElements; indexedObj.getFieldsDotted(field.field, geoFieldElements); if (geoFieldElements.empty()) { continue; } S2Point us = field.getCentroid(); for (BSONElementSet::iterator oi = geoFieldElements.begin(); oi != geoFieldElements.end(); ++oi) { const BSONObj &geoObj = oi->Obj(); double dist = -1; S2Point them; if (GeoJSONParser::isPolygon(geoObj)) { S2Polygon shape; GeoJSONParser::parsePolygon(geoObj, &shape); them = shape.Project(us); } else if (GeoJSONParser::isLineString(geoObj)) { S2Polyline shape; GeoJSONParser::parseLineString(geoObj, &shape); int tmp; them = shape.Project(us, &tmp); } else if (GeoJSONParser::isPoint(geoObj)) { S2Cell point; GeoJSONParser::parsePoint(geoObj, &point); them = point.GetCenter(); } S1Angle angle(us, them); dist = angle.radians() * _params.radius; if (dist >= _innerRadius && dist <= _outerRadius) { ++geoFieldsInRange; minMatchingDistance = min(dist, minMatchingDistance); } } } if (_fields.size() == geoFieldsInRange) { if (_returned.end() == _returned.find(cursor->currLoc())) { _results.push(Result(cursor->currLoc(), cursor->currKey(), minMatchingDistance)); } } } if (_results.empty()) { _radiusIncrement *= 2; nextAnnulus(); } } while (_results.empty() && _innerRadius < M_PI * _params.radius); // TODO: consider shrinking _radiusIncrement if _results.size() meets some criteria. }
// Fill _results with all of the results in the annulus defined by _innerRadius and // _outerRadius. If no results are found, grow the annulus and repeat until success (or // until the edge of the world). void S2NearIndexCursor::fillResults() { verify(_results.empty()); if (_innerRadius >= _outerRadius) { return; } if (_innerRadius > _maxDistance) { return; } // We iterate until 1. our search radius is too big or 2. we find results. do { // Some of these arguments are opaque, look at the definitions of the involved classes. FieldRangeSet frs(_descriptor->parentNS().c_str(), makeFRSObject(), false, false); shared_ptr<FieldRangeVector> frv(new FieldRangeVector(frs, _specForFRV, 1)); scoped_ptr<BtreeCursor> cursor(BtreeCursor::make(nsdetails(_descriptor->parentNS()), _descriptor->getOnDisk(), frv, 0, 1)); // The cursor may return the same obj more than once for a given // FRS, so we make sure to only consider it once in any given annulus. // // We don't want this outside of the 'do' loop because the covering // for an annulus may return an object whose distance to the query // point is actually contained in a subsequent annulus. If we // didn't consider every object in a given annulus we might miss // the point. // // We don't use a global 'seen' because we get that by requiring // the distance from the query point to the indexed geo to be // within our 'current' annulus, and I want to dodge all yield // issues if possible. unordered_set<DiskLoc, DiskLoc::Hasher> seen; LOG(1) << "looking at annulus from " << _innerRadius << " to " << _outerRadius << endl; LOG(1) << "Total # returned: " << _stats._numReturned << endl; // Do the actual search through this annulus. for (; cursor->ok(); cursor->advance()) { // Don't bother to look at anything we've returned. if (_returned.end() != _returned.find(cursor->currLoc())) { ++_stats._returnSkip; continue; } ++_stats._nscanned; if (seen.end() != seen.find(cursor->currLoc())) { ++_stats._btreeDups; continue; } // Get distance interval from our query point to the cell. // If it doesn't overlap with our current shell, toss. BSONObj currKey(cursor->currKey()); BSONObjIterator it(currKey); BSONElement geoKey; for (int i = 0; i <= _nearFieldIndex; ++i) { geoKey = it.next(); } S2Cell keyCell = S2Cell(S2CellId::FromString(geoKey.String())); if (!_annulus.MayIntersect(keyCell)) { ++_stats._keyGeoSkip; continue; } // We have to add this document to seen *AFTER* the key intersection test. // A geometry may have several keys, one of which may be in our search shell and one // of which may be outside of it. We don't want to ignore a document just because // one of its covers isn't inside this annulus. seen.insert(cursor->currLoc()); // At this point forward, we will not examine the document again in this annulus. const BSONObj& indexedObj = cursor->currLoc().obj(); // Match against indexed geo fields. ++_stats._geoMatchTested; size_t geoFieldsMatched = 0; // See if the object actually overlaps w/the geo query fields. for (size_t i = 0; i < _indexedGeoFields.size(); ++i) { BSONElementSet geoFieldElements; indexedObj.getFieldsDotted(_indexedGeoFields[i].getField(), geoFieldElements, false); if (geoFieldElements.empty()) { continue; } bool match = false; for (BSONElementSet::iterator oi = geoFieldElements.begin(); !match && (oi != geoFieldElements.end()); ++oi) { if (!oi->isABSONObj()) { continue; } const BSONObj &geoObj = oi->Obj(); GeometryContainer geoContainer; uassert(16762, "ill-formed geometry: " + geoObj.toString(), geoContainer.parseFrom(geoObj)); match = _indexedGeoFields[i].satisfiesPredicate(geoContainer); } if (match) { ++geoFieldsMatched; } } if (geoFieldsMatched != _indexedGeoFields.size()) { continue; } // Get all the fields with that name from the document. BSONElementSet geoFieldElements; indexedObj.getFieldsDotted(_nearQuery.field, geoFieldElements, false); if (geoFieldElements.empty()) { continue; } ++_stats._inAnnulusTested; double minDistance = 1e20; // Look at each field in the document and take the min. distance. for (BSONElementSet::iterator oi = geoFieldElements.begin(); oi != geoFieldElements.end(); ++oi) { if (!oi->isABSONObj()) { continue; } double dist = distanceTo(oi->Obj()); minDistance = min(dist, minDistance); } // We could be in an annulus, yield, add new points closer to // query point than the last point we returned, then unyield. // This would return points out of order. if (minDistance < _returnedDistance) { continue; } // If the min. distance satisfies our distance criteria if (minDistance >= _innerRadius && minDistance < _outerRadius) { // The result is valid. We have to de-dup ourselves here. if (_returned.end() == _returned.find(cursor->currLoc())) { _results.push(Result(cursor->currLoc(), cursor->currKey(), minDistance)); } } } if (_results.empty()) { LOG(1) << "results empty!\n"; _radiusIncrement *= 2; nextAnnulus(); } else if (_results.size() < 300) { _radiusIncrement *= 2; } else if (_results.size() > 600) { _radiusIncrement /= 2; } } while (_results.empty() && _innerRadius < _maxDistance && _innerRadius < _outerRadius); LOG(1) << "Filled shell with " << _results.size() << " results" << endl; }
// Fill _results with the next shell of results. We may have to search several times to do // this. If _results.empty() after calling fillResults, there are no more possible results. void S2NearCursor::fillResults() { verify(_results.empty()); if (_innerRadius >= _outerRadius) { return; } if (_innerRadius > _maxDistance) { return; } // We iterate until 1. our search radius is too big or 2. we find results. do { // Some of these arguments are opaque, look at the definitions of the involved classes. FieldRangeSet frs(_details->parentNS().c_str(), makeFRSObject(), false, false); shared_ptr<FieldRangeVector> frv(new FieldRangeVector(frs, _specForFRV, 1)); scoped_ptr<BtreeCursor> cursor(BtreeCursor::make(nsdetails(_details->parentNS().c_str()), *_details, frv, 0, 1)); // Do the actual search through this annulus. size_t considered = 0; for (; cursor->ok(); cursor->advance()) { ++considered; MatchDetails details; bool matched = _matcher->matchesCurrent(cursor.get(), &details); if (!matched) { continue; } const BSONObj& indexedObj = cursor->currLoc().obj(); size_t geoFieldsInRange = 0; double minMatchingDistance = 1e20; // Calculate the distance from our query point(s) to the geo field(s). // For each geo field in the query... for (size_t i = 0; i < _fields.size(); ++i) { const QueryGeometry& field = _fields[i]; // Get all the fields with that name from the document. BSONElementSet geoFieldElements; indexedObj.getFieldsDotted(field.field, geoFieldElements, false); if (geoFieldElements.empty()) { continue; } // For each field with that name in the document... for (BSONElementSet::iterator oi = geoFieldElements.begin(); oi != geoFieldElements.end(); ++oi) { if (!oi->isABSONObj()) { continue; } double dist = distanceBetween(field, oi->Obj()); // If it satisfies our distance criteria... if (dist >= _innerRadius && dist <= _outerRadius) { // Success! For this field. ++geoFieldsInRange; minMatchingDistance = min(dist, minMatchingDistance); } } } // If all the geo query fields had something in range if (_fields.size() == geoFieldsInRange) { // The result is valid. We have to de-dup ourselves here. if (_returned.end() == _returned.find(cursor->currLoc())) { _results.push(Result(cursor->currLoc(), cursor->currKey(), minMatchingDistance)); } } } if (_results.empty()) { _radiusIncrement *= 2; nextAnnulus(); } } while (_results.empty() && _innerRadius < _maxDistance && _innerRadius < _outerRadius && _innerRadius < M_PI * _params.radius); // TODO: consider shrinking _radiusIncrement if _results.size() meets some criteria. }
IndexSuitability HashedIndexType::suitability( const BSONObj& query , const BSONObj& order ) const { FieldRangeSet frs( "" , query , true, true ); if ( frs.isPointIntervalSet( _hashedField ) ) return HELPFUL; return USELESS; }
// Fill _results with the next shell of results. We may have to search several times to do // this. If _results.empty() after calling fillResults, there are no more possible results. void S2NearCursor::fillResults() { verify(_results.empty()); if (_innerRadius >= _outerRadius) { return; } if (_innerRadius > _maxDistance) { return; } if (0 == _numToReturn) { return; } // We iterate until 1. our search radius is too big or 2. we find results. do { // Some of these arguments are opaque, look at the definitions of the involved classes. FieldRangeSet frs(_details->parentNS().c_str(), makeFRSObject(), false, false); shared_ptr<FieldRangeVector> frv(new FieldRangeVector(frs, _specForFRV, 1)); scoped_ptr<BtreeCursor> cursor(BtreeCursor::make(nsdetails(_details->parentNS()), *_details, frv, 0, 1)); // The cursor may return the same obj more than once for a given // FRS, so we make sure to only consider it once in any given annulus. // // We don't want this outside of the 'do' loop because the covering // for an annulus may return an object whose distance to the query // point is actually contained in a subsequent annulus. If we // didn't consider every object in a given annulus we might miss // the point. // // We don't use a global 'seen' because we get that by requiring // the distance from the query point to the indexed geo to be // within our 'current' annulus, and I want to dodge all yield // issues if possible. set<DiskLoc> seen; LOG(1) << "looking at annulus from " << _innerRadius << " to " << _outerRadius << endl; // Do the actual search through this annulus. for (; cursor->ok(); cursor->advance()) { ++_nscanned; if (seen.end() != seen.find(cursor->currLoc())) { continue; } seen.insert(cursor->currLoc()); // Match against non-indexed fields. ++_matchTested; MatchDetails details; bool matched = _matcher->matchesCurrent(cursor.get(), &details); if (!matched) { continue; } const BSONObj& indexedObj = cursor->currLoc().obj(); ++_geoTested; // Match against indexed geo fields. size_t geoFieldsMatched = 0; // OK, cool, non-geo match satisfied. See if the object actually overlaps w/the geo // query fields. for (size_t i = 0; i < _indexedGeoFields.size(); ++i) { BSONElementSet geoFieldElements; indexedObj.getFieldsDotted(_indexedGeoFields[i].getField(), geoFieldElements, false); if (geoFieldElements.empty()) { continue; } bool match = false; for (BSONElementSet::iterator oi = geoFieldElements.begin(); !match && (oi != geoFieldElements.end()); ++oi) { if (!oi->isABSONObj()) { continue; } const BSONObj &geoObj = oi->Obj(); GeometryContainer geoContainer; uassert(16699, "ill-formed geometry: " + geoObj.toString(), geoContainer.parseFrom(geoObj)); match = _indexedGeoFields[i].satisfiesPredicate(geoContainer); } if (match) { ++geoFieldsMatched; } } if (geoFieldsMatched != _indexedGeoFields.size()) { continue; } // Finally, see if the item is in our search annulus. size_t geoFieldsInRange = 0; double minMatchingDistance = 1e20; // Get all the fields with that name from the document. BSONElementSet geoFieldElements; indexedObj.getFieldsDotted(_nearQuery.field, geoFieldElements, false); if (geoFieldElements.empty()) { continue; } // For each field with that name in the document... for (BSONElementSet::iterator oi = geoFieldElements.begin(); oi != geoFieldElements.end(); ++oi) { if (!oi->isABSONObj()) { continue; } double dist = distanceTo(oi->Obj()); // If it satisfies our distance criteria... if (dist >= _innerRadius && dist <= _outerRadius) { // Success! For this field. ++geoFieldsInRange; minMatchingDistance = min(dist, minMatchingDistance); } } // If all the geo query fields had something in range if (geoFieldsInRange > 0) { // The result is valid. We have to de-dup ourselves here. if (_returned.end() == _returned.find(cursor->currLoc())) { _results.push(Result(cursor->currLoc(), cursor->currKey(), minMatchingDistance)); } } } if (_results.empty()) { _radiusIncrement *= 2; nextAnnulus(); } } while (_results.empty() && _innerRadius < _maxDistance && _innerRadius < _outerRadius); }
mu::MuStream *setup() { PString *p = new PString(); p->pluck(frs("67.wav"), beat_to_tick(0.00), 1.0); p->pluck(frs("67.wav"), beat_to_tick(0.75), 1.0); p->pluck(frs("72.wav"), beat_to_tick(1.50), 1.0); p->hammer(frs("74.wav"), beat_to_tick(1.65), 1.0); p->pluck(frs("72.wav"), beat_to_tick(2.50), 1.0); p->pluck(frs("72.wav"), beat_to_tick(3.00), 1.0); p->pluck(frs("72.wav"), beat_to_tick(4.00), 1.0); p->hammer(frs("74.wav"), beat_to_tick(4.15), 1.0); p->pluck(frs("72.wav"), beat_to_tick(4.75), 1.0); p->pluck(frs("74.wav"), beat_to_tick(5.50), 1.0); p->pluck(frs("74.wav"), beat_to_tick(6.50), 1.0); p->pluck(frs("74.wav"), beat_to_tick(7.00), 1.0); p->dampen(beat_to_tick(8.00)); PString *q = new PString(); q->pluck(frs("60.wav"), beat_to_tick(3.50), 1.0); q->dampen(beat_to_tick(5.50)); mu::SumStream *sstream = new mu::SumStream(); sstream->add_source(p->stream()); sstream->add_source(q->stream()); mu::LoopStream *loop_stream = new mu::LoopStream(); loop_stream->set_source(sstream); loop_stream->set_interval(beat_to_tick(8.00)); loop_stream->set_source_end(beat_to_tick(8.00)); return loop_stream; }