diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2015-06-20 00:22:50 -0400 |
---|---|---|
committer | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2015-06-20 10:56:02 -0400 |
commit | 9c2ed42daa8fbbef4a919c21ec564e2db55e8d60 (patch) | |
tree | 3814f79c10d7b490948d8cb7b112ac1dd41ceff1 /src/mongo/db/clientcursor.h | |
parent | 01965cf52bce6976637ecb8f4a622aeb05ab256a (diff) | |
download | mongo-9c2ed42daa8fbbef4a919c21ec564e2db55e8d60.tar.gz |
SERVER-18579: Clang-Format - reformat code, no comment reflow
Diffstat (limited to 'src/mongo/db/clientcursor.h')
-rw-r--r-- | src/mongo/db/clientcursor.h | 624 |
1 files changed, 331 insertions, 293 deletions
diff --git a/src/mongo/db/clientcursor.h b/src/mongo/db/clientcursor.h index d2482ffbfa9..a145802e985 100644 --- a/src/mongo/db/clientcursor.h +++ b/src/mongo/db/clientcursor.h @@ -36,306 +36,344 @@ namespace mongo { - class ClientCursor; - class Collection; - class CursorManager; - class RecoveryUnit; +class ClientCursor; +class Collection; +class CursorManager; +class RecoveryUnit; - typedef long long CursorId; /* passed to the client so it can send back on getMore */ - static const CursorId INVALID_CURSOR_ID = -1; // But see SERVER-5726. +typedef long long CursorId; /* passed to the client so it can send back on getMore */ +static const CursorId INVALID_CURSOR_ID = -1; // But see SERVER-5726. +/** + * ClientCursor is a wrapper that represents a cursorid from our database application's + * perspective. + */ +class ClientCursor { + MONGO_DISALLOW_COPYING(ClientCursor); + +public: /** - * ClientCursor is a wrapper that represents a cursorid from our database application's - * perspective. + * This ClientCursor constructor creates a cursorid that can be used with getMore and + * killCursors. "cursorManager" is the object that will manage the lifetime of this + * cursor, and "ns" is the namespace string that should be associated with this cursor (e.g. + * "test.foo", "test.$cmd.listCollections", etc). */ - class ClientCursor { - MONGO_DISALLOW_COPYING(ClientCursor); - public: - /** - * This ClientCursor constructor creates a cursorid that can be used with getMore and - * killCursors. "cursorManager" is the object that will manage the lifetime of this - * cursor, and "ns" is the namespace string that should be associated with this cursor (e.g. - * "test.foo", "test.$cmd.listCollections", etc). - */ - ClientCursor(CursorManager* cursorManager, - PlanExecutor* exec, - const std::string& ns, - int qopts = 0, - const BSONObj query = BSONObj(), - bool isAggCursor = false); - - /** - * This ClientCursor is used to track sharding state for the given collection. - */ - explicit ClientCursor(const Collection* collection); - - // - // Basic accessors - // - - CursorId cursorid() const { return _cursorid; } - std::string ns() const { return _ns; } - CursorManager* cursorManager() const { return _cursorManager; } - bool isAggCursor() const { return _isAggCursor; } - - // - // Pinning functionality. - // - - /** - * Marks this ClientCursor as in use. unsetPinned() must be called before the destructor of - * this ClientCursor is invoked. - */ - void setPinned() { _isPinned = true; } - - /** - * Marks this ClientCursor as no longer in use. - */ - void unsetPinned() { _isPinned = false; } - - bool isPinned() const { return _isPinned; } - - /** - * This is called when someone is dropping a collection or something else that - * goes through killing cursors. - * It removes the responsiilibty of de-registering from ClientCursor. - * Responsibility for deleting the ClientCursor doesn't change from this call - * see PlanExecutor::kill. - */ - void kill(); - - // - // Timing and timeouts - // - - /** - * @param millis amount of idle passed time since last call - * note called outside of locks (other than ccmutex) so care must be exercised - */ - bool shouldTimeout( int millis ); - void setIdleTime( int millis ); - int idleTime() const { return _idleAgeMillis; } - - uint64_t getLeftoverMaxTimeMicros() const { return _leftoverMaxTimeMicros; } - void setLeftoverMaxTimeMicros( uint64_t leftoverMaxTimeMicros ) { - _leftoverMaxTimeMicros = leftoverMaxTimeMicros; - } - - // - // Replication-related stuff. TODO: Document and clean. - // - - // Used to report replication position only in master-slave, - // so we keep them as TimeStamp rather than OpTime. - void updateSlaveLocation(OperationContext* txn); - void slaveReadTill( const Timestamp& t ) { _slaveReadTill = t; } - /** Just for testing. */ - Timestamp getSlaveReadTill() const { return _slaveReadTill; } - - // - // Query-specific functionality that may be adapted for the PlanExecutor. - // - - PlanExecutor* getExecutor() const { return _exec.get(); } - int queryOptions() const { return _queryOptions; } - const BSONObj& getQuery() const { return _query; } - - // Used by ops/query.cpp to stash how many results have been returned by a query. - int pos() const { return _pos; } - void incPos(int n) { _pos += n; } - void setPos(int n) { _pos = n; } - - static long long totalOpen(); - - // - // Storage engine state for getMore. - // - - bool hasRecoveryUnit() const { return _ownedRU.get() || _unownedRU; } - - /** - * - * If a ClientCursor is created via DBDirectClient, it uses the same storage engine - * context as the DBDirectClient caller. We store this context in _unownedRU. We use - * this to verify that all further callers use the same RecoveryUnit. - * - * Once a ClientCursor has an unowned RecoveryUnit, it will always have one. - * - * Sets the unowned RecoveryUnit to 'ru'. Does NOT take ownership of the pointer. - */ - void setUnownedRecoveryUnit(RecoveryUnit* ru); - - /** - * Return the unowned RecoveryUnit. 'this' does not own pointer and therefore cannot - * transfer ownership. - */ - RecoveryUnit* getUnownedRecoveryUnit() const; - - /** - * If a ClientCursor is created via a client request, we bind its lifetime to the - * ClientCursor's by storing it un _ownedRU. In order to execute the query over repeated - * network requests, we have to keep the execution state around. - */ - - /** - * Set the owned recovery unit to 'ru'. Takes ownership of it. If there is a previous - * owned recovery unit, it is deleted. - */ - void setOwnedRecoveryUnit(RecoveryUnit* ru); - - /** - * Returns the owned recovery unit. Ownership is transferred to the caller. - */ - RecoveryUnit* releaseOwnedRecoveryUnit(); - - private: - friend class CursorManager; - friend class ClientCursorPin; - - /** - * Only friends are allowed to destroy ClientCursor objects. - */ - ~ClientCursor(); - - /** - * Initialization common between both constructors for the ClientCursor. The database must - * be stable when this is called, because cursors hang off the collection. - */ - void init(); - - // - // ClientCursor-specific data, independent of the underlying execution type. - // - - // The ID of the ClientCursor. - CursorId _cursorid; - - // The namespace we're operating on. - std::string _ns; - - CursorManager* _cursorManager; - - // if we've added it to the total open counter yet - bool _countedYet; - - // How many objects have been returned by the find() so far? - int _pos; - - // If this cursor was created by a find operation, '_query' holds the query predicate for - // the find. If this cursor was created by a command (e.g. the aggregate command), then - // '_query' holds the command specification received from the client. - BSONObj _query; - - // See the QueryOptions enum in dbclient.h - int _queryOptions; - - // Is this ClientCursor backed by an aggregation pipeline? Defaults to false. - // - // Agg executors differ from others in that they manage their own locking internally and - // should not be killed or destroyed when the underlying collection is deleted. - // - // Note: This should *not* be set for the internal cursor used as input to an aggregation. - bool _isAggCursor; - - // Is this cursor in use? Defaults to false. - bool _isPinned; - - // Is the "no timeout" flag set on this cursor? If false, this cursor may be targeted for - // deletion after an interval of inactivity. Defaults to false. - bool _isNoTimeout; - - // The replication position only used in master-slave. - Timestamp _slaveReadTill; - - // How long has the cursor been idle? - int _idleAgeMillis; - - // TODO: Document. - uint64_t _leftoverMaxTimeMicros; - - // For chunks that are being migrated, there is a period of time when that chunks data is in - // two shards, the donor and the receiver one. That data is picked up by a cursor on the - // receiver side, even before the migration was decided. The CollectionMetadata allow one - // to inquiry if any given document of the collection belongs indeed to this shard or if it - // is coming from (or a vestige of) an ongoing migration. - CollectionMetadataPtr _collMetadata; - - // Only one of these is not-NULL. - RecoveryUnit* _unownedRU; - std::unique_ptr<RecoveryUnit> _ownedRU; - // NOTE: _ownedRU must come before _exec, because _ownedRU must outlive _exec. - // The storage engine can have resources in the PlanExecutor that rely on - // the RecoveryUnit being alive. - - // - // The underlying execution machinery. - // - std::unique_ptr<PlanExecutor> _exec; - }; + ClientCursor(CursorManager* cursorManager, + PlanExecutor* exec, + const std::string& ns, + int qopts = 0, + const BSONObj query = BSONObj(), + bool isAggCursor = false); + + /** + * This ClientCursor is used to track sharding state for the given collection. + */ + explicit ClientCursor(const Collection* collection); + + // + // Basic accessors + // + + CursorId cursorid() const { + return _cursorid; + } + std::string ns() const { + return _ns; + } + CursorManager* cursorManager() const { + return _cursorManager; + } + bool isAggCursor() const { + return _isAggCursor; + } + + // + // Pinning functionality. + // + + /** + * Marks this ClientCursor as in use. unsetPinned() must be called before the destructor of + * this ClientCursor is invoked. + */ + void setPinned() { + _isPinned = true; + } + + /** + * Marks this ClientCursor as no longer in use. + */ + void unsetPinned() { + _isPinned = false; + } + + bool isPinned() const { + return _isPinned; + } + + /** + * This is called when someone is dropping a collection or something else that + * goes through killing cursors. + * It removes the responsiilibty of de-registering from ClientCursor. + * Responsibility for deleting the ClientCursor doesn't change from this call + * see PlanExecutor::kill. + */ + void kill(); + + // + // Timing and timeouts + // + + /** + * @param millis amount of idle passed time since last call + * note called outside of locks (other than ccmutex) so care must be exercised + */ + bool shouldTimeout(int millis); + void setIdleTime(int millis); + int idleTime() const { + return _idleAgeMillis; + } + + uint64_t getLeftoverMaxTimeMicros() const { + return _leftoverMaxTimeMicros; + } + void setLeftoverMaxTimeMicros(uint64_t leftoverMaxTimeMicros) { + _leftoverMaxTimeMicros = leftoverMaxTimeMicros; + } + + // + // Replication-related stuff. TODO: Document and clean. + // + + // Used to report replication position only in master-slave, + // so we keep them as TimeStamp rather than OpTime. + void updateSlaveLocation(OperationContext* txn); + void slaveReadTill(const Timestamp& t) { + _slaveReadTill = t; + } + /** Just for testing. */ + Timestamp getSlaveReadTill() const { + return _slaveReadTill; + } + + // + // Query-specific functionality that may be adapted for the PlanExecutor. + // + + PlanExecutor* getExecutor() const { + return _exec.get(); + } + int queryOptions() const { + return _queryOptions; + } + const BSONObj& getQuery() const { + return _query; + } + + // Used by ops/query.cpp to stash how many results have been returned by a query. + int pos() const { + return _pos; + } + void incPos(int n) { + _pos += n; + } + void setPos(int n) { + _pos = n; + } + + static long long totalOpen(); + + // + // Storage engine state for getMore. + // + + bool hasRecoveryUnit() const { + return _ownedRU.get() || _unownedRU; + } /** - * ClientCursorPin is an RAII class that manages the pinned state of a ClientCursor. - * ClientCursorPin objects pin the given cursor upon construction, and release the pin upon - * destruction. - * - * A pin extends the lifetime of a ClientCursor object until the pin's release. Pinned - * ClientCursor objects cannot not be killed due to inactivity, and cannot be killed by user - * kill requests. When a CursorManager is destroyed (e.g. by a collection drop), ownership of - * any still-pinned ClientCursor objects is transferred to their managing ClientCursorPin - * objects. * - * Example usage: - * { - * ClientCursorPin pin(cursorManager, cursorid); - * ClientCursor* cursor = pin.c(); - * if (cursor) { - * // Use cursor. - * } - * // Pin automatically released on block exit. - * } + * If a ClientCursor is created via DBDirectClient, it uses the same storage engine + * context as the DBDirectClient caller. We store this context in _unownedRU. We use + * this to verify that all further callers use the same RecoveryUnit. * - * Clients that wish to access ClientCursor objects owned by collection cursor managers must - * hold the collection lock during pin acquisition and pin release. This guards from a - * collection drop (which requires an exclusive lock on the collection) occurring concurrently - * with the pin request or unpin request. + * Once a ClientCursor has an unowned RecoveryUnit, it will always have one. * - * Clients that wish to access ClientCursor objects owned by the global cursor manager need not - * hold any locks; the global cursor manager can only be destroyed by a process exit. + * Sets the unowned RecoveryUnit to 'ru'. Does NOT take ownership of the pointer. + */ + void setUnownedRecoveryUnit(RecoveryUnit* ru); + + /** + * Return the unowned RecoveryUnit. 'this' does not own pointer and therefore cannot + * transfer ownership. + */ + RecoveryUnit* getUnownedRecoveryUnit() const; + + /** + * If a ClientCursor is created via a client request, we bind its lifetime to the + * ClientCursor's by storing it un _ownedRU. In order to execute the query over repeated + * network requests, we have to keep the execution state around. + */ + + /** + * Set the owned recovery unit to 'ru'. Takes ownership of it. If there is a previous + * owned recovery unit, it is deleted. + */ + void setOwnedRecoveryUnit(RecoveryUnit* ru); + + /** + * Returns the owned recovery unit. Ownership is transferred to the caller. + */ + RecoveryUnit* releaseOwnedRecoveryUnit(); + +private: + friend class CursorManager; + friend class ClientCursorPin; + + /** + * Only friends are allowed to destroy ClientCursor objects. + */ + ~ClientCursor(); + + /** + * Initialization common between both constructors for the ClientCursor. The database must + * be stable when this is called, because cursors hang off the collection. */ - class ClientCursorPin { - MONGO_DISALLOW_COPYING(ClientCursorPin); - public: - /** - * Asks "cursorManager" to set a pin on the ClientCursor associated with "cursorid". If no - * such cursor exists, does nothing. If the cursor is already pinned, throws a - * UserException. - */ - ClientCursorPin( CursorManager* cursorManager, long long cursorid ); - - /** - * Calls release(). - */ - ~ClientCursorPin(); - - /** - * Releases the pin. It does not delete the underlying cursor unless ownership has passed - * to us after kill. Turns into a no-op if release() or deleteUnderlying() have already - * been called on this pin. - */ - void release(); - - /** - * Deletes the underlying cursor. Cannot be called if release() or deleteUnderlying() have - * already been called on this pin. - */ - void deleteUnderlying(); - - ClientCursor *c() const; - - private: - ClientCursor* _cursor; - }; - - void startClientCursorMonitor(); - -} // namespace mongo + void init(); + + // + // ClientCursor-specific data, independent of the underlying execution type. + // + + // The ID of the ClientCursor. + CursorId _cursorid; + + // The namespace we're operating on. + std::string _ns; + + CursorManager* _cursorManager; + + // if we've added it to the total open counter yet + bool _countedYet; + + // How many objects have been returned by the find() so far? + int _pos; + + // If this cursor was created by a find operation, '_query' holds the query predicate for + // the find. If this cursor was created by a command (e.g. the aggregate command), then + // '_query' holds the command specification received from the client. + BSONObj _query; + + // See the QueryOptions enum in dbclient.h + int _queryOptions; + + // Is this ClientCursor backed by an aggregation pipeline? Defaults to false. + // + // Agg executors differ from others in that they manage their own locking internally and + // should not be killed or destroyed when the underlying collection is deleted. + // + // Note: This should *not* be set for the internal cursor used as input to an aggregation. + bool _isAggCursor; + + // Is this cursor in use? Defaults to false. + bool _isPinned; + + // Is the "no timeout" flag set on this cursor? If false, this cursor may be targeted for + // deletion after an interval of inactivity. Defaults to false. + bool _isNoTimeout; + + // The replication position only used in master-slave. + Timestamp _slaveReadTill; + + // How long has the cursor been idle? + int _idleAgeMillis; + + // TODO: Document. + uint64_t _leftoverMaxTimeMicros; + + // For chunks that are being migrated, there is a period of time when that chunks data is in + // two shards, the donor and the receiver one. That data is picked up by a cursor on the + // receiver side, even before the migration was decided. The CollectionMetadata allow one + // to inquiry if any given document of the collection belongs indeed to this shard or if it + // is coming from (or a vestige of) an ongoing migration. + CollectionMetadataPtr _collMetadata; + + // Only one of these is not-NULL. + RecoveryUnit* _unownedRU; + std::unique_ptr<RecoveryUnit> _ownedRU; + // NOTE: _ownedRU must come before _exec, because _ownedRU must outlive _exec. + // The storage engine can have resources in the PlanExecutor that rely on + // the RecoveryUnit being alive. + + // + // The underlying execution machinery. + // + std::unique_ptr<PlanExecutor> _exec; +}; + +/** + * ClientCursorPin is an RAII class that manages the pinned state of a ClientCursor. + * ClientCursorPin objects pin the given cursor upon construction, and release the pin upon + * destruction. + * + * A pin extends the lifetime of a ClientCursor object until the pin's release. Pinned + * ClientCursor objects cannot not be killed due to inactivity, and cannot be killed by user + * kill requests. When a CursorManager is destroyed (e.g. by a collection drop), ownership of + * any still-pinned ClientCursor objects is transferred to their managing ClientCursorPin + * objects. + * + * Example usage: + * { + * ClientCursorPin pin(cursorManager, cursorid); + * ClientCursor* cursor = pin.c(); + * if (cursor) { + * // Use cursor. + * } + * // Pin automatically released on block exit. + * } + * + * Clients that wish to access ClientCursor objects owned by collection cursor managers must + * hold the collection lock during pin acquisition and pin release. This guards from a + * collection drop (which requires an exclusive lock on the collection) occurring concurrently + * with the pin request or unpin request. + * + * Clients that wish to access ClientCursor objects owned by the global cursor manager need not + * hold any locks; the global cursor manager can only be destroyed by a process exit. + */ +class ClientCursorPin { + MONGO_DISALLOW_COPYING(ClientCursorPin); + +public: + /** + * Asks "cursorManager" to set a pin on the ClientCursor associated with "cursorid". If no + * such cursor exists, does nothing. If the cursor is already pinned, throws a + * UserException. + */ + ClientCursorPin(CursorManager* cursorManager, long long cursorid); + + /** + * Calls release(). + */ + ~ClientCursorPin(); + + /** + * Releases the pin. It does not delete the underlying cursor unless ownership has passed + * to us after kill. Turns into a no-op if release() or deleteUnderlying() have already + * been called on this pin. + */ + void release(); + + /** + * Deletes the underlying cursor. Cannot be called if release() or deleteUnderlying() have + * already been called on this pin. + */ + void deleteUnderlying(); + + ClientCursor* c() const; + +private: + ClientCursor* _cursor; +}; + +void startClientCursorMonitor(); + +} // namespace mongo |