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