counters.h   counters.h 
// Copyright 2012 the V8 project authors. All rights reserved. // counters.h
// Redistribution and use in source and binary forms, with or without /*
// modification, are permitted provided that the following conditions are * Copyright (C) 2010 10gen Inc.
// met: *
// * This program is free software: you can redistribute it and/or modify
// * Redistributions of source code must retain the above copyright * it under the terms of the GNU Affero General Public License, version
// notice, this list of conditions and the following disclaimer. 3,
// * Redistributions in binary form must reproduce the above * as published by the Free Software Foundation.
// copyright notice, this list of conditions and the following *
// disclaimer in the documentation and/or other materials provided * This program is distributed in the hope that it will be useful,
// with the distribution. * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * Neither the name of Google Inc. nor the names of its * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// contributors may be used to endorse or promote products derived * GNU Affero General Public License for more details.
// from this software without specific prior written permission. *
// * You should have received a copy of the GNU Affero General Public Lice
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS nse
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * along with this program. If not, see <http://www.gnu.org/licenses/>.
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR *
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * As a special exception, the copyright holders give permission to link
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, the
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * code of portions of this program with the OpenSSL library under certa
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, in
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * conditions as described in each individual source file and distribute
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * linked combinations including the program with the OpenSSL library. Y
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ou
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * must comply with the GNU Affero General Public License in all respect
s for
#ifndef V8_COUNTERS_H_ * all of the code used other than as permitted herein. If you modify fi
#define V8_COUNTERS_H_ le(s)
* with this exception, you may extend this exception to your version of
#include "../include/v8.h" the
#include "allocation.h" * file(s), but you are not obligated to do so. If you do not wish to do
so,
namespace v8 { * delete this exception statement from your version. If you delete this
namespace internal { * exception statement from all source files in the program, then also d
elete
// StatsCounters is an interface for plugging into external * it in the license file.
// counters for monitoring. Counters can be looked up and */
// manipulated by name.
#pragma once
class StatsTable {
public: #include "mongo/pch.h"
// Register an application-defined function where #include "mongo/db/jsobj.h"
// counters can be looked up. #include "mongo/util/net/message.h"
void SetCounterFunction(CounterLookupCallback f) { #include "mongo/util/processinfo.h"
lookup_function_ = f; #include "mongo/util/concurrency/spin_lock.h"
} #include "mongo/db/pdfile.h"
// Register an application-defined function to create namespace mongo {
// a histogram for passing to the AddHistogramSample function
void SetCreateHistogramFunction(CreateHistogramCallback f) { /**
create_histogram_function_ = f; * for storing operation counters
} * note: not thread safe. ok with that for speed
*/
// Register an application-defined function to add a sample class OpCounters {
// to a histogram created with CreateHistogram function public:
void SetAddHistogramSampleFunction(AddHistogramSampleCallback f) {
add_histogram_sample_function_ = f; OpCounters();
} void incInsertInWriteLock(int n);
void gotInsert();
bool HasCounterFunction() const { void gotQuery();
return lookup_function_ != NULL; void gotUpdate();
} void gotDelete();
void gotGetMore();
// Lookup the location of a counter by name. If the lookup void gotCommand();
// is successful, returns a non-NULL pointer for writing the
// value of the counter. Each thread calling this function void gotOp( int op , bool isCommand );
// may receive a different location to store it's counter.
// The return value must not be cached and re-used across BSONObj getObj() const;
// threads, although a single thread is free to cache it.
int* FindLocation(const char* name) { // thse are used by snmp, and other things, do not remove
if (!lookup_function_) return NULL; const AtomicUInt * getInsert() const { return &_insert; }
return lookup_function_(name); const AtomicUInt * getQuery() const { return &_query; }
} const AtomicUInt * getUpdate() const { return &_update; }
const AtomicUInt * getDelete() const { return &_delete; }
// Create a histogram by name. If the create is successful, const AtomicUInt * getGetMore() const { return &_getmore; }
// returns a non-NULL pointer for use with AddHistogramSample const AtomicUInt * getCommand() const { return &_command; }
// function. min and max define the expected minimum and maximum
// sample values. buckets is the maximum number of buckets private:
// that the samples will be grouped into. void _checkWrap();
void* CreateHistogram(const char* name,
int min, // todo: there will be a lot of cache line contention on these. ne
int max, ed to do something
size_t buckets) { // else eventually.
if (!create_histogram_function_) return NULL; AtomicUInt _insert;
return create_histogram_function_(name, min, max, buckets); AtomicUInt _query;
} AtomicUInt _update;
AtomicUInt _delete;
// Add a sample to a histogram created with the CreateHistogram AtomicUInt _getmore;
// function. AtomicUInt _command;
void AddHistogramSample(void* histogram, int sample) { };
if (!add_histogram_sample_function_) return;
return add_histogram_sample_function_(histogram, sample); extern OpCounters globalOpCounters;
} extern OpCounters replOpCounters;
private: class NetworkCounter {
StatsTable(); public:
NetworkCounter() : _bytesIn(0), _bytesOut(0), _requests(0), _overfl
CounterLookupCallback lookup_function_; ows(0) {}
CreateHistogramCallback create_histogram_function_; void hit( long long bytesIn , long long bytesOut );
AddHistogramSampleCallback add_histogram_sample_function_; void append( BSONObjBuilder& b );
private:
friend class Isolate; long long _bytesIn;
long long _bytesOut;
DISALLOW_COPY_AND_ASSIGN(StatsTable); long long _requests;
};
// StatsCounters are dynamically created values which can be tracked in
// the StatsTable. They are designed to be lightweight to create and
// easy to use.
//
// Internally, a counter represents a value in a row of a StatsTable.
// The row has a 32bit value for each process/thread in the table and also
// a name (stored in the table metadata). Since the storage location can b
e
// thread-specific, this class cannot be shared across threads.
//
// This class is designed to be POD initialized. It will be registered wit
h
// the counter system on first use. For example:
// StatsCounter c = { "c:myctr", NULL, false };
struct StatsCounter {
const char* name_;
int* ptr_;
bool lookup_done_;
// Sets the counter to a specific value.
void Set(int value) {
int* loc = GetPtr();
if (loc) *loc = value;
}
// Increments the counter.
void Increment() {
int* loc = GetPtr();
if (loc) (*loc)++;
}
void Increment(int value) {
int* loc = GetPtr();
if (loc)
(*loc) += value;
}
// Decrements the counter.
void Decrement() {
int* loc = GetPtr();
if (loc) (*loc)--;
}
void Decrement(int value) {
int* loc = GetPtr();
if (loc) (*loc) -= value;
}
// Is this counter enabled?
// Returns false if table is full.
bool Enabled() {
return GetPtr() != NULL;
}
// Get the internal pointer to the counter. This is used
// by the code generator to emit code that manipulates a
// given counter without calling the runtime system.
int* GetInternalPointer() {
int* loc = GetPtr();
ASSERT(loc != NULL);
return loc;
}
protected:
// Returns the cached address of this counter location.
int* GetPtr() {
if (lookup_done_) return ptr_;
lookup_done_ = true;
ptr_ = FindLocationInStatsTable();
return ptr_;
}
private:
int* FindLocationInStatsTable() const;
};
// StatsCounterTimer t = { { L"t:foo", NULL, false }, 0, 0 };
struct StatsCounterTimer {
StatsCounter counter_;
int64_t start_time_;
int64_t stop_time_;
// Start the timer.
void Start();
// Stop the timer and record the results.
void Stop();
// Returns true if the timer is running.
bool Running() {
return counter_.Enabled() && start_time_ != 0 && stop_time_ == 0;
}
};
// A Histogram represents a dynamically created histogram in the StatsTable
.
//
// This class is designed to be POD initialized. It will be registered wit
h
// the histogram system on first use. For example:
// Histogram h = { "myhist", 0, 10000, 50, NULL, false };
struct Histogram {
const char* name_;
int min_;
int max_;
int num_buckets_;
void* histogram_;
bool lookup_done_;
// Add a single sample to this histogram.
void AddSample(int sample);
// Returns true if this histogram is enabled.
bool Enabled() {
return GetHistogram() != NULL;
}
protected:
// Returns the handle to the histogram.
void* GetHistogram() {
if (!lookup_done_) {
lookup_done_ = true;
histogram_ = CreateHistogram();
}
return histogram_;
}
private:
void* CreateHistogram() const;
};
// A HistogramTimer allows distributions of results to be created
// HistogramTimer t = { {L"foo", 0, 10000, 50, NULL, false}, 0, 0 };
struct HistogramTimer {
Histogram histogram_;
int64_t start_time_;
int64_t stop_time_;
// Start the timer.
void Start();
// Stop the timer and record the results.
void Stop();
// Returns true if the timer is running.
bool Running() {
return histogram_.Enabled() && (start_time_ != 0) && (stop_time_ == 0);
}
};
// Helper class for scoping a HistogramTimer.
class HistogramTimerScope BASE_EMBEDDED {
public:
explicit HistogramTimerScope(HistogramTimer* timer) :
timer_(timer) {
timer_->Start();
}
~HistogramTimerScope() {
timer_->Stop();
}
private:
HistogramTimer* timer_;
};
} } // namespace v8::internal long long _overflows;
#endif // V8_COUNTERS_H_ SpinLock _lock;
};
extern NetworkCounter networkCounter;
}
 End of changes. 3 change blocks. 
273 lines changed or deleted 106 lines changed or added


 dbclientinterface.h   dbclientinterface.h 
skipping to change at line 937 skipping to change at line 937
uses the { listDatabases : 1 } command. uses the { listDatabases : 1 } command.
throws on error throws on error
*/ */
list<string> getDatabaseNames(); list<string> getDatabaseNames();
/** /**
get a list of all the current collections in db get a list of all the current collections in db
*/ */
list<string> getCollectionNames( const string& db ); list<string> getCollectionNames( const string& db );
/**
* { name : "<short collection name>",
* options : { }
* }
*/
std::list<BSONObj> getCollectionInfos( const std::string& db,
const BSONObj& filter = BSON
Obj() );
bool exists( const string& ns ); bool exists( const string& ns );
/** Create an index if it does not already exist. /** Create an index if it does not already exist.
ensureIndex calls are remembered so it is safe/fast to call thi s function many ensureIndex calls are remembered so it is safe/fast to call thi s function many
times in your code. times in your code.
@param ns collection to be indexed @param ns collection to be indexed
@param keys the "key pattern" for the index. e.g., { name : 1 } @param keys the "key pattern" for the index. e.g., { name : 1 }
@param unique if true, indicates that key uniqueness should be e nforced for this index @param unique if true, indicates that key uniqueness should be e nforced for this index
@param name if not specified, it will be created from the keys a utomatically (which is recommended) @param name if not specified, it will be created from the keys a utomatically (which is recommended)
@param cache if set to false, the index cache for the connection won't remember this call @param cache if set to false, the index cache for the connection won't remember this call
 End of changes. 1 change blocks. 
0 lines changed or deleted 9 lines changed or added


 index_builder.h   index_builder.h 
skipping to change at line 75 skipping to change at line 75
killMatchingIndexBuilds(Collection* collection, killMatchingIndexBuilds(Collection* collection,
const IndexCatalog::IndexKillCriteria& criteria); const IndexCatalog::IndexKillCriteria& criteria);
/** /**
* Retry all index builds in the list. Builds each index in a separ ate thread. If ns does * Retry all index builds in the list. Builds each index in a separ ate thread. If ns does
* not match the ns field in the indexes list, the BSONObj's ns fie ld is changed before the * not match the ns field in the indexes list, the BSONObj's ns fie ld is changed before the
* index is built (to handle rename). * index is built (to handle rename).
*/ */
static void restoreIndexes(const std::vector<BSONObj>& indexes); static void restoreIndexes(const std::vector<BSONObj>& indexes);
/**
* Waits for a background index build to register itself. This fun
ction must be called
* after starting a background index build via a BackgroundJob and
before starting a
* subsequent one.
*/
static void waitForBgIndexStarting();
private: private:
const BSONObj _index; const BSONObj _index;
std::string _name; // name of this builder, not related to the inde x std::string _name; // name of this builder, not related to the inde x
static AtomicUInt _indexBuildCount; static AtomicUInt _indexBuildCount;
}; };
} }
 End of changes. 1 change blocks. 
0 lines changed or deleted 9 lines changed or added


 index_entry.h   index_entry.h 
skipping to change at line 49 skipping to change at line 49
* This name sucks, but every name involving 'index' is used somewhere. * This name sucks, but every name involving 'index' is used somewhere.
*/ */
struct IndexEntry { struct IndexEntry {
/** /**
* Use this constructor if you're making an IndexEntry from the cat alog. * Use this constructor if you're making an IndexEntry from the cat alog.
*/ */
IndexEntry(const BSONObj& kp, IndexEntry(const BSONObj& kp,
const string& accessMethod, const string& accessMethod,
bool mk, bool mk,
bool sp, bool sp,
bool unq,
const string& n, const string& n,
const BSONObj& io) const BSONObj& io)
: keyPattern(kp), : keyPattern(kp),
multikey(mk), multikey(mk),
sparse(sp), sparse(sp),
unique(unq),
name(n), name(n),
infoObj(io) { infoObj(io) {
type = IndexNames::nameToType(accessMethod); type = IndexNames::nameToType(accessMethod);
} }
/** /**
* For testing purposes only. * For testing purposes only.
*/ */
IndexEntry(const BSONObj& kp, IndexEntry(const BSONObj& kp,
bool mk, bool mk,
bool sp, bool sp,
bool unq,
const string& n, const string& n,
const BSONObj& io) const BSONObj& io)
: keyPattern(kp), : keyPattern(kp),
multikey(mk), multikey(mk),
sparse(sp), sparse(sp),
unique(unq),
name(n), name(n),
infoObj(io) { infoObj(io) {
type = IndexNames::nameToType(IndexNames::findPluginName(keyPat tern)); type = IndexNames::nameToType(IndexNames::findPluginName(keyPat tern));
} }
/** /**
* For testing purposes only. * For testing purposes only.
*/ */
IndexEntry(const BSONObj& kp) IndexEntry(const BSONObj& kp)
: keyPattern(kp), : keyPattern(kp),
multikey(false), multikey(false),
sparse(false), sparse(false),
unique(false),
name("test_foo"), name("test_foo"),
infoObj(BSONObj()) { infoObj(BSONObj()) {
type = IndexNames::nameToType(IndexNames::findPluginName(keyPat tern)); type = IndexNames::nameToType(IndexNames::findPluginName(keyPat tern));
} }
BSONObj keyPattern; BSONObj keyPattern;
bool multikey; bool multikey;
bool sparse; bool sparse;
bool unique;
string name; string name;
// Geo indices have extra parameters. We need those available to p lan correctly. // Geo indices have extra parameters. We need those available to p lan correctly.
BSONObj infoObj; BSONObj infoObj;
// What type of index is this? (What access method can we use on t he index described // What type of index is this? (What access method can we use on t he index described
// by the keyPattern?) // by the keyPattern?)
IndexType type; IndexType type;
std::string toString() const { std::string toString() const {
 End of changes. 6 change blocks. 
0 lines changed or deleted 7 lines changed or added


 index_scan.h   index_scan.h 
skipping to change at line 115 skipping to change at line 115
virtual ~IndexScan() { } virtual ~IndexScan() { }
virtual StageState work(WorkingSetID* out); virtual StageState work(WorkingSetID* out);
virtual bool isEOF(); virtual bool isEOF();
virtual void prepareToYield(); virtual void prepareToYield();
virtual void recoverFromYield(); virtual void recoverFromYield();
virtual void invalidate(const DiskLoc& dl, InvalidationType type); virtual void invalidate(const DiskLoc& dl, InvalidationType type);
virtual PlanStageStats* getStats(); virtual PlanStageStats* getStats();
/**
* Get an unowned pointer to this stage's common stats.
*/
CommonStats* getCommonStats();
/**
* Get an unowned pointer to this stage's specific stats.
*/
IndexScanStats* getSpecificStats();
private: private:
/** /**
* Initialize the underlying IndexCursor, grab information from the catalog for stats. * Initialize the underlying IndexCursor, grab information from the catalog for stats.
*/ */
void initIndexScan(); void initIndexScan();
/** See if the cursor is pointing at or past _endKey, if _endKey is non-empty. */ /** See if the cursor is pointing at or past _endKey, if _endKey is non-empty. */
void checkEnd(); void checkEnd();
// The WorkingSet we annotate with results. Not owned by us. // The WorkingSet we annotate with results. Not owned by us.
 End of changes. 1 change blocks. 
0 lines changed or deleted 10 lines changed or added


 plan_stats.h   plan_stats.h 
skipping to change at line 352 skipping to change at line 352
return specific; return specific;
} }
size_t dupsTested; size_t dupsTested;
size_t dupsDropped; size_t dupsDropped;
// How many records were we forced to fetch as the result of an inv alidation? // How many records were we forced to fetch as the result of an inv alidation?
size_t forcedFetches; size_t forcedFetches;
}; };
struct S2NearStats : public SpecificStats {
S2NearStats() : nscanned(0), nscannedObjects(0), isMultiKey(false)
{ }
virtual SpecificStats* clone() const {
S2NearStats* specific = new S2NearStats(*this);
return specific;
}
size_t nscanned;
size_t nscannedObjects;
bool isMultiKey;
};
struct ShardingFilterStats : public SpecificStats { struct ShardingFilterStats : public SpecificStats {
ShardingFilterStats() : chunkSkips(0) { } ShardingFilterStats() : chunkSkips(0) { }
virtual SpecificStats* clone() const { virtual SpecificStats* clone() const {
ShardingFilterStats* specific = new ShardingFilterStats(*this); ShardingFilterStats* specific = new ShardingFilterStats(*this);
return specific; return specific;
} }
size_t chunkSkips; size_t chunkSkips;
}; };
 End of changes. 1 change blocks. 
0 lines changed or deleted 14 lines changed or added


 planner_ixselect.h   planner_ixselect.h 
skipping to change at line 99 skipping to change at line 99
/** /**
* Amend the RelevantTag lists for all predicates in the subtree ro oted at 'node' to remove * Amend the RelevantTag lists for all predicates in the subtree ro oted at 'node' to remove
* invalid assignments to text and geo indices. * invalid assignments to text and geo indices.
* *
* See the body of this function and the specific stripInvalidAssig nments functions for details. * See the body of this function and the specific stripInvalidAssig nments functions for details.
*/ */
static void stripInvalidAssignments(MatchExpression* node, static void stripInvalidAssignments(MatchExpression* node,
const vector<IndexEntry>& indic es); const vector<IndexEntry>& indic es);
/**
* In some special cases, we can strip most of the index assignment
s from the tree early
* on. Specifically, if we find an AND which has a child tagged for
equality over a
* single-field unique index, then all other predicate-to-index ass
ignments can be
* stripped off the subtree rooted at 'node'.
*
* This is used to ensure that we always favor key-value lookup pla
ns over any
* more complex plan.
*
* Example:
* Suppose you have match expression OR (AND (a==1, b==2), AND (c
==3, d==4)).
* There are indices on fields, 'a', 'b', 'c', and 'd'. The index
on 'd' is
* the only unique index.
*
* This code will find that the subtree AND (c==3, d==4) can be a
nswered by
* looking up the value of 'd' in the unique index. Since no bett
er plan than
* a single key lookup is ever available, all assignments in this
subtree
* are stripped, except for the assignment of d==4 to the unique
'd' index.
*
* Stripping the assignment for 'c' causes the planner to generat
e just two
* possible plans:
* 1) an OR of an index scan over 'a' and an index scan over 'd
'
* 2) an OR of an index scan over 'b' and an index scan over 'd
'
*/
static void stripUnneededAssignments(MatchExpression* node,
const std::vector<IndexEntry>&
indices);
private: private:
/** /**
* Amend the RelevantTag lists for all predicates in the subtree ro oted at 'node' to remove * Amend the RelevantTag lists for all predicates in the subtree ro oted at 'node' to remove
* invalid assignments to text indexes. * invalid assignments to text indexes.
* *
* A predicate on a field from a compound text index with a non-emp ty index prefix * A predicate on a field from a compound text index with a non-emp ty index prefix
* (e.g. pred {a: 1, b: 1} on index {a: 1, b: 1, c: "text"}) is onl y considered valid to * (e.g. pred {a: 1, b: 1} on index {a: 1, b: 1, c: "text"}) is onl y considered valid to
* assign to the text index if it is a direct child of an AND with the following properties: * assign to the text index if it is a direct child of an AND with the following properties:
* - it has a TEXT child * - it has a TEXT child
* - for every index prefix component, it has an EQ child on that c omponent's path * - for every index prefix component, it has an EQ child on that c omponent's path
 End of changes. 1 change blocks. 
0 lines changed or deleted 41 lines changed or added


 s2near.h   s2near.h 
skipping to change at line 33 skipping to change at line 33
* file(s), but you are not obligated to do so. If you do not wish to do so, * file(s), but you are not obligated to do so. If you do not wish to do so,
* delete this exception statement from your version. If you delete this * delete this exception statement from your version. If you delete this
* exception statement from all source files in the program, then also d elete * exception statement from all source files in the program, then also d elete
* it in the license file. * it in the license file.
*/ */
#pragma once #pragma once
#include <queue> #include <queue>
#include "mongo/db/exec/fetch.h"
#include "mongo/db/exec/index_scan.h"
#include "mongo/db/exec/plan_stage.h" #include "mongo/db/exec/plan_stage.h"
#include "mongo/db/geo/geoquery.h" #include "mongo/db/geo/geoquery.h"
#include "mongo/db/geo/s2common.h" #include "mongo/db/geo/s2common.h"
#include "mongo/db/index/index_descriptor.h" #include "mongo/db/index/index_descriptor.h"
#include "mongo/db/jsobj.h" #include "mongo/db/jsobj.h"
#include "mongo/db/matcher/expression.h" #include "mongo/db/matcher/expression.h"
#include "mongo/db/query/index_bounds.h" #include "mongo/db/query/index_bounds.h"
#include "mongo/platform/unordered_set.h" #include "mongo/platform/unordered_set.h"
#include "third_party/s2/s2cap.h" #include "third_party/s2/s2cap.h"
#include "third_party/s2/s2regionintersection.h" #include "third_party/s2/s2regionintersection.h"
skipping to change at line 97 skipping to change at line 99
WorkingSet* _ws; WorkingSet* _ws;
// This is the "array index" of the key field that is the near fiel d. We use this to do // This is the "array index" of the key field that is the near fiel d. We use this to do
// cheap is-this-doc-in-the-annulus testing. We also need to know where to stuff the index // cheap is-this-doc-in-the-annulus testing. We also need to know where to stuff the index
// bounds for the various annuluses/annuli. // bounds for the various annuluses/annuli.
int _nearFieldIndex; int _nearFieldIndex;
// Geo filter in index scan (which is owned by fetch stage in _chil d). // Geo filter in index scan (which is owned by fetch stage in _chil d).
scoped_ptr<MatchExpression> _keyGeoFilter; scoped_ptr<MatchExpression> _keyGeoFilter;
scoped_ptr<PlanStage> _child; // The child fetch stage for the current annulus.
scoped_ptr<FetchStage> _child;
// The child of '_child'. Not owned here.
IndexScan* _indexScan;
// The S2 machinery that represents the search annulus. We keep th is around after bounds // The S2 machinery that represents the search annulus. We keep th is around after bounds
// generation to check for intersection. // generation to check for intersection.
S2Cap _innerCap; S2Cap _innerCap;
S2Cap _outerCap; S2Cap _outerCap;
S2RegionIntersection _annulus; S2RegionIntersection _annulus;
// We use this to hold on to the results in an annulus. Results ar e sorted to have // We use this to hold on to the results in an annulus. Results ar e sorted to have
// decreasing distance. // decreasing distance.
struct Result { struct Result {
skipping to change at line 156 skipping to change at line 162
// Did we encounter an unrecoverable error? // Did we encounter an unrecoverable error?
bool _failed; bool _failed;
// Have we init()'d yet? // Have we init()'d yet?
bool _initted; bool _initted;
// What index are we searching over? // What index are we searching over?
IndexDescriptor* _descriptor; IndexDescriptor* _descriptor;
CommonStats _commonStats; CommonStats _commonStats;
S2NearStats _specificStats;
}; };
} // namespace mongo } // namespace mongo
 End of changes. 3 change blocks. 
1 lines changed or deleted 8 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/