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
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, #pragma once
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, #include "mongo/pch.h"
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY #include "../jsobj.h"
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT #include "../../util/net/message.h"
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #include "../../util/processinfo.h"
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "../../util/concurrency/spin_lock.h"
#include "mongo/db/pdfile.h"
#ifndef V8_COUNTERS_H_
#define V8_COUNTERS_H_ namespace mongo {
#include "../include/v8.h" /**
#include "allocation.h" * for storing operation counters
* note: not thread safe. ok with that for speed
namespace v8 { */
namespace internal { class OpCounters {
public:
// StatsCounters is an interface for plugging into external
// counters for monitoring. Counters can be looked up and OpCounters();
// manipulated by name. void incInsertInWriteLock(int n) { _insert.x += n; }
void gotInsert() { _insert++; }
class StatsTable { void gotQuery() { _query++; }
public: void gotUpdate() { _update++; }
// Register an application-defined function where void gotDelete() { _delete++; }
// counters can be looked up. void gotGetMore() { _getmore++; }
void SetCounterFunction(CounterLookupCallback f) { void gotCommand() { _command++; }
lookup_function_ = f;
} void gotOp( int op , bool isCommand );
// Register an application-defined function to create BSONObj getObj() const;
// a histogram for passing to the AddHistogramSample function
void SetCreateHistogramFunction(CreateHistogramCallback f) { // thse are used by snmp, and other things, do not remove
create_histogram_function_ = f; const AtomicUInt * getInsert() const { return &_insert; }
} const AtomicUInt * getQuery() const { return &_query; }
const AtomicUInt * getUpdate() const { return &_update; }
// Register an application-defined function to add a sample const AtomicUInt * getDelete() const { return &_delete; }
// to a histogram created with CreateHistogram function const AtomicUInt * getGetMore() const { return &_getmore; }
void SetAddHistogramSampleFunction(AddHistogramSampleCallback f) { const AtomicUInt * getCommand() const { return &_command; }
add_histogram_sample_function_ = f;
} private:
void _checkWrap();
bool HasCounterFunction() const {
return lookup_function_ != NULL; // todo: there will be a lot of cache line contention on these. ne
} ed to do something
// else eventually.
// Lookup the location of a counter by name. If the lookup AtomicUInt _insert;
// is successful, returns a non-NULL pointer for writing the AtomicUInt _query;
// value of the counter. Each thread calling this function AtomicUInt _update;
// may receive a different location to store it's counter. AtomicUInt _delete;
// The return value must not be cached and re-used across AtomicUInt _getmore;
// threads, although a single thread is free to cache it. AtomicUInt _command;
int* FindLocation(const char* name) { };
if (!lookup_function_) return NULL;
return lookup_function_(name); extern OpCounters globalOpCounters;
} extern OpCounters replOpCounters;
// Create a histogram by name. If the create is successful, class NetworkCounter {
// returns a non-NULL pointer for use with AddHistogramSample public:
// function. min and max define the expected minimum and maximum NetworkCounter() : _bytesIn(0), _bytesOut(0), _requests(0), _overfl
// sample values. buckets is the maximum number of buckets ows(0) {}
// that the samples will be grouped into. void hit( long long bytesIn , long long bytesOut );
void* CreateHistogram(const char* name, void append( BSONObjBuilder& b );
int min, private:
int max, long long _bytesIn;
size_t buckets) { long long _bytesOut;
if (!create_histogram_function_) return NULL; long long _requests;
return create_histogram_function_(name, min, max, buckets);
}
// Add a sample to a histogram created with the CreateHistogram
// function.
void AddHistogramSample(void* histogram, int sample) {
if (!add_histogram_sample_function_) return;
return add_histogram_sample_function_(histogram, sample);
}
private:
StatsTable();
CounterLookupCallback lookup_function_;
CreateHistogramCallback create_histogram_function_;
AddHistogramSampleCallback add_histogram_sample_function_;
friend class Isolate;
DISALLOW_COPY_AND_ASSIGN(StatsTable);
};
// 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 86 lines changed or added


 dbmessage.h   dbmessage.h 
skipping to change at line 112 skipping to change at line 112
}; };
#pragma pack() #pragma pack()
/* For the database/server protocol, these objects and functions encaps ulate /* For the database/server protocol, these objects and functions encaps ulate
the various messages transmitted over the connection. the various messages transmitted over the connection.
See http://dochub.mongodb.org/core/mongowireprotocol See http://dochub.mongodb.org/core/mongowireprotocol
*/ */
class DbMessage { class DbMessage {
// Assume sizeof(int) == 4 bytes
BOOST_STATIC_ASSERT(sizeof(int) == 4);
public: public:
DbMessage(const Message& _m) : m(_m) , mark(0) { // Note: DbMessage constructor reads the first 4 bytes and stores i
// for received messages, Message has only one buffer t in reserved
theEnd = _m.singleData()->_data + _m.header()->dataLen(); DbMessage(const Message& msg);
char *r = _m.singleData()->_data;
reserved = (int *) r; // Indicates whether this message is expected to have a ns
data = r + 4; // or in the case of dbMsg, a string in the same place as ns
nextjsobj = data; bool messageShouldHaveNs() const {
return (_msg.operation() >= dbMsg) && (_msg.operation() <= dbDe
lete);
} }
/** the 32 bit field before the ns /** the 32 bit field before the ns
* track all bit usage here as its cross op * track all bit usage here as its cross op
* 0: InsertOption_ContinueOnError * 0: InsertOption_ContinueOnError
* 1: fromWriteback * 1: fromWriteback
*/ */
int& reservedField() { return *reserved; } int reservedField() const { return _reserved; }
void setReservedField(int value) { _reserved = value; }
const char * getns() const {
return data;
}
void getns(Namespace& ns) const {
ns = data;
}
const char * afterNS() const {
return data + strlen( data ) + 1;
}
int getInt( int num ) const { const char * getns() const;
const int * foo = (const int*)afterNS(); int getQueryNToReturn() const;
return foo[num];
}
int getQueryNToReturn() const { int getFlags() const;
return getInt( 1 ); void setFlags(int value);
}
/** long long getInt64(int offsetBytes) const;
* get an int64 at specified offsetBytes after ns
*/
long long getInt64( int offsetBytes ) const {
const char * x = afterNS();
x += offsetBytes;
const long long * ll = (const long long*)x;
return ll[0];
}
void resetPull() { nextjsobj = data; } int pullInt();
int pullInt() const { return pullInt(); } long long pullInt64();
int& pullInt() { const long long* getArray(size_t count) const;
if ( nextjsobj == data )
nextjsobj += strlen(data) + 1; // skip namespace
int& i = *((int *)nextjsobj);
nextjsobj += 4;
return i;
}
long long pullInt64() const {
return pullInt64();
}
long long &pullInt64() {
if ( nextjsobj == data )
nextjsobj += strlen(data) + 1; // skip namespace
long long &i = *((long long *)nextjsobj);
nextjsobj += 8;
return i;
}
OID* getOID() const {
return (OID *) (data + strlen(data) + 1); // skip namespace
}
void getQueryStuff(const char *&query, int& ntoreturn) {
int *i = (int *) (data + strlen(data) + 1);
ntoreturn = *i;
i++;
query = (const char *) i;
}
/* for insert and update msgs */ /* for insert and update msgs */
bool moreJSObjs() const { bool moreJSObjs() const {
return nextjsobj != 0; return _nextjsobj != 0;
}
BSONObj nextJsObj() {
if ( nextjsobj == data ) {
nextjsobj += strlen(data) + 1; // skip namespace
massert( 13066 , "Message contains no documents", theEnd >
nextjsobj );
}
massert( 10304,
"Client Error: Remaining data too small for BSON objec
t",
theEnd - nextjsobj >= 5 );
if ( cmdLine.objcheck ) {
Status status = validateBSON( nextjsobj, theEnd - nextjsobj
);
massert( 10307,
str::stream() << "Client Error: bad object in mess
age: " << status.reason(),
status.isOK() );
}
BSONObj js(nextjsobj);
verify( js.objsize() >= 5 );
verify( js.objsize() < ( theEnd - data ) );
nextjsobj += js.objsize();
if ( nextjsobj >= theEnd )
nextjsobj = 0;
return js;
} }
const Message& msg() const { return m; } BSONObj nextJsObj();
const Message& msg() const { return _msg; }
const char * markGet() { const char * markGet() const {
return nextjsobj; return _nextjsobj;
} }
void markSet() { void markSet() {
mark = nextjsobj; _mark = _nextjsobj;
} }
void markReset( const char * toMark = 0) { void markReset(const char * toMark = NULL);
if( toMark == 0 ) toMark = mark;
verify( toMark );
nextjsobj = toMark;
}
private: private:
const Message& m; // Check if we have enough data to read
int* reserved; template<typename T>
const char *data; void checkRead(const char* start, size_t count = 0) const;
const char *nextjsobj;
const char *theEnd; template<typename T>
void checkReadOffset(const char* start, size_t offset) const;
// Read some type without advancing our position
template<typename T>
T read() const;
// Read some type, and advance our position
template<typename T> T readAndAdvance();
const Message& _msg;
int _reserved; // flags or zero depending on packet, starts the pac
ket
const char* _nsStart; // start of namespace string, +4 from message
start
const char* _nextjsobj; // current position reading packet
const char* _theEnd; // end of packet
const char* _mark;
const char * mark; unsigned int _nsLen;
}; };
/* a request to run a query, received from the database */ /* a request to run a query, received from the database */
class QueryMessage { class QueryMessage {
public: public:
const char *ns; const char *ns;
int ntoskip; int ntoskip;
int ntoreturn; int ntoreturn;
int queryOptions; int queryOptions;
BSONObj query; BSONObj query;
 End of changes. 14 change blocks. 
110 lines changed or deleted 55 lines changed or added


 index_set.h   index_set.h 
skipping to change at line 35 skipping to change at line 35
namespace mongo { namespace mongo {
/** /**
* a.$ -> a * a.$ -> a
* @return true if out is set and we made a change * @return true if out is set and we made a change
*/ */
bool getCanonicalIndexField( const StringData& fullName, std::string* o ut ); bool getCanonicalIndexField( const StringData& fullName, std::string* o ut );
class IndexPathSet { class IndexPathSet {
public: public:
IndexPathSet();
void addPath( const StringData& path ); void addPath( const StringData& path );
void allPathsIndexed();
void clear(); void clear();
bool mightBeIndexed( const StringData& path ) const; bool mightBeIndexed( const StringData& path ) const;
private: private:
bool _startsWith( const StringData& a, const StringData& b ) const; bool _startsWith( const StringData& a, const StringData& b ) const;
std::set<std::string> _canonical; std::set<std::string> _canonical;
bool _allPathsIndexed;
}; };
} }
 End of changes. 3 change blocks. 
0 lines changed or deleted 6 lines changed or added


 message.h   message.h 
skipping to change at line 106 skipping to change at line 106
int messageLength; // total message size, including this int messageLength; // total message size, including this
int requestID; // identifier for this message int requestID; // identifier for this message
int responseTo; // requestID from the original request int responseTo; // requestID from the original request
// (used in responses from db) // (used in responses from db)
int opCode; int opCode;
}; };
#pragma pack() #pragma pack()
#pragma pack(1) #pragma pack(1)
/* todo merge this with MSGHEADER (or inherit from it). */ /* todo merge this with MSGHEADER (or inherit from it). */
struct MsgData { class MsgData {
friend class Message;
friend class DbMessage;
friend class MessagingPort;
public:
int len; /* len of the msg, including this field */ int len; /* len of the msg, including this field */
MSGID id; /* request/reply id's match... */ MSGID id; /* request/reply id's match... */
MSGID responseTo; /* id of the message we are responding to */ MSGID responseTo; /* id of the message we are responding to */
short _operation; short _operation;
char _flags; char _flags;
char _version; char _version;
int operation() const { int operation() const {
return _operation; return _operation;
} }
void setOperation(int o) { void setOperation(int o) {
_flags = 0; _flags = 0;
_version = 0; _version = 0;
_operation = o; _operation = o;
} }
char _data[4];
int& dataAsInt() { int& dataAsInt() {
return *((int *) _data); return *((int *) _data);
} }
bool valid() { bool valid() {
if ( len <= 0 || len > ( 4 * BSONObjMaxInternalSize ) ) if ( len <= 0 || len > ( 4 * BSONObjMaxInternalSize ) )
return false; return false;
if ( _operation < 0 || _operation > 30000 ) if ( _operation < 0 || _operation > 30000 )
return false; return false;
skipping to change at line 143 skipping to change at line 147
} }
long long getCursor() { long long getCursor() {
verify( responseTo > 0 ); verify( responseTo > 0 );
verify( _operation == opReply ); verify( _operation == opReply );
long long * l = (long long *)(_data + 4); long long * l = (long long *)(_data + 4);
return l[0]; return l[0];
} }
int dataLen(); // len without header int dataLen(); // len without header
private:
char _data[4]; //must be last member
}; };
const int MsgDataHeaderSize = sizeof(MsgData) - 4; const int MsgDataHeaderSize = sizeof(MsgData) - 4;
inline int MsgData::dataLen() { inline int MsgData::dataLen() {
return len - MsgDataHeaderSize; return len - MsgDataHeaderSize;
} }
#pragma pack() #pragma pack()
class Message { class Message {
public: public:
// we assume here that a vector with initial size 0 does no allocat ion (0 is the default, but wanted to make it explicit). // we assume here that a vector with initial size 0 does no allocat ion (0 is the default, but wanted to make it explicit).
 End of changes. 4 change blocks. 
2 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/