summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog/collection.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/catalog/collection.h')
-rw-r--r--src/mongo/db/catalog/collection.h681
1 files changed, 349 insertions, 332 deletions
diff --git a/src/mongo/db/catalog/collection.h b/src/mongo/db/catalog/collection.h
index 5f5609bd437..972979378cf 100644
--- a/src/mongo/db/catalog/collection.h
+++ b/src/mongo/db/catalog/collection.h
@@ -53,343 +53,360 @@
namespace mongo {
- class CollectionCatalogEntry;
- class DatabaseCatalogEntry;
- class ExtentManager;
- class IndexCatalog;
- class MatchExpression;
- class MultiIndexBlock;
- class OpDebug;
- class OperationContext;
- class RecordCursor;
- class RecordFetcher;
- class UpdateDriver;
- class UpdateRequest;
-
- struct CompactOptions {
-
- CompactOptions() {
- paddingMode = NONE;
- validateDocuments = true;
- paddingFactor = 1;
- paddingBytes = 0;
- }
-
- // padding
- enum PaddingMode {
- PRESERVE, NONE, MANUAL
- } paddingMode;
-
- // only used if _paddingMode == MANUAL
- double paddingFactor; // what to multiple document size by
- int paddingBytes; // what to add to ducment size after multiplication
- unsigned computeRecordSize( unsigned recordSize ) const {
- recordSize = static_cast<unsigned>( paddingFactor * recordSize );
- recordSize += paddingBytes;
- return recordSize;
- }
-
- // other
- bool validateDocuments;
-
- std::string toString() const;
- };
-
- struct CompactStats {
- CompactStats() {
- corruptDocuments = 0;
- }
-
- long long corruptDocuments;
- };
+class CollectionCatalogEntry;
+class DatabaseCatalogEntry;
+class ExtentManager;
+class IndexCatalog;
+class MatchExpression;
+class MultiIndexBlock;
+class OpDebug;
+class OperationContext;
+class RecordCursor;
+class RecordFetcher;
+class UpdateDriver;
+class UpdateRequest;
+
+struct CompactOptions {
+ CompactOptions() {
+ paddingMode = NONE;
+ validateDocuments = true;
+ paddingFactor = 1;
+ paddingBytes = 0;
+ }
+
+ // padding
+ enum PaddingMode { PRESERVE, NONE, MANUAL } paddingMode;
+
+ // only used if _paddingMode == MANUAL
+ double paddingFactor; // what to multiple document size by
+ int paddingBytes; // what to add to ducment size after multiplication
+ unsigned computeRecordSize(unsigned recordSize) const {
+ recordSize = static_cast<unsigned>(paddingFactor * recordSize);
+ recordSize += paddingBytes;
+ return recordSize;
+ }
+
+ // other
+ bool validateDocuments;
+
+ std::string toString() const;
+};
+
+struct CompactStats {
+ CompactStats() {
+ corruptDocuments = 0;
+ }
+
+ long long corruptDocuments;
+};
+
+/**
+ * Queries with the awaitData option use this notifier object to wait for more data to be
+ * inserted into the capped collection.
+ */
+class CappedInsertNotifier {
+public:
+ CappedInsertNotifier();
+
+ /**
+ * Wakes up threads waiting on this object for the arrival of new data.
+ */
+ void notifyOfInsert();
+
+ /**
+ * Get a counter value which is incremented on every insert into a capped collection.
+ * The return value should be used as a reference value to pass into waitForCappedInsert().
+ */
+ uint64_t getCount() const;
+
+ /**
+ * Waits for 'timeout' microseconds, or until notifyAll() is called to indicate that new
+ * data is available in the capped collection.
+ */
+ void waitForInsert(uint64_t referenceCount, Microseconds timeout) const;
+
+private:
+ // Signalled when a successful insert is made into a capped collection.
+ mutable stdx::condition_variable _cappedNewDataNotifier;
+
+ // Mutex used with '_cappedNewDataNotifier'. Protects access to '_cappedInsertCount'.
+ mutable stdx::mutex _cappedNewDataMutex;
+
+ // A counter, incremented on insertion of new data into the capped collection.
+ //
+ // The condition which '_cappedNewDataNotifier' is being notified of is an increment of this
+ // counter. Access to this counter is synchronized with '_cappedNewDataMutex'.
+ uint64_t _cappedInsertCount;
+};
+
+/**
+ * this is NOT safe through a yield right now
+ * not sure if it will be, or what yet
+ */
+class Collection : CappedDocumentDeleteCallback, UpdateNotifier {
+public:
+ Collection(OperationContext* txn,
+ StringData fullNS,
+ CollectionCatalogEntry* details, // does not own
+ RecordStore* recordStore, // does not own
+ DatabaseCatalogEntry* dbce); // does not own
+
+ ~Collection();
+
+ bool ok() const {
+ return _magic == 1357924;
+ }
+
+ CollectionCatalogEntry* getCatalogEntry() {
+ return _details;
+ }
+ const CollectionCatalogEntry* getCatalogEntry() const {
+ return _details;
+ }
+
+ CollectionInfoCache* infoCache() {
+ return &_infoCache;
+ }
+ const CollectionInfoCache* infoCache() const {
+ return &_infoCache;
+ }
+
+ const NamespaceString& ns() const {
+ return _ns;
+ }
+
+ const IndexCatalog* getIndexCatalog() const {
+ return &_indexCatalog;
+ }
+ IndexCatalog* getIndexCatalog() {
+ return &_indexCatalog;
+ }
+
+ const RecordStore* getRecordStore() const {
+ return _recordStore;
+ }
+ RecordStore* getRecordStore() {
+ return _recordStore;
+ }
+
+ CursorManager* getCursorManager() const {
+ return &_cursorManager;
+ }
+
+ bool requiresIdIndex() const;
+
+ Snapshotted<BSONObj> docFor(OperationContext* txn, const RecordId& loc) const;
+
+ /**
+ * @param out - contents set to the right docs if exists, or nothing.
+ * @return true iff loc exists
+ */
+ bool findDoc(OperationContext* txn, const RecordId& loc, Snapshotted<BSONObj>* out) const;
+
+ std::unique_ptr<RecordCursor> getCursor(OperationContext* txn, bool forward = true) const;
+
+ /**
+ * Returns many cursors that partition the Collection into many disjoint sets. Iterating
+ * all returned cursors is equivalent to iterating the full collection.
+ */
+ std::vector<std::unique_ptr<RecordCursor>> getManyCursors(OperationContext* txn) const;
+
+ void deleteDocument(OperationContext* txn,
+ const RecordId& loc,
+ bool cappedOK = false,
+ bool noWarn = false,
+ BSONObj* deletedId = 0);
+
+ /**
+ * this does NOT modify the doc before inserting
+ * i.e. will not add an _id field for documents that are missing it
+ *
+ * If enforceQuota is false, quotas will be ignored.
+ */
+ StatusWith<RecordId> insertDocument(OperationContext* txn,
+ const BSONObj& doc,
+ bool enforceQuota,
+ bool fromMigrate = false);
/**
- * Queries with the awaitData option use this notifier object to wait for more data to be
- * inserted into the capped collection.
+ * Callers must ensure no document validation is performed for this collection when calling
+ * this method.
*/
- class CappedInsertNotifier {
- public:
- CappedInsertNotifier();
-
- /**
- * Wakes up threads waiting on this object for the arrival of new data.
- */
- void notifyOfInsert();
-
- /**
- * Get a counter value which is incremented on every insert into a capped collection.
- * The return value should be used as a reference value to pass into waitForCappedInsert().
- */
- uint64_t getCount() const;
-
- /**
- * Waits for 'timeout' microseconds, or until notifyAll() is called to indicate that new
- * data is available in the capped collection.
- */
- void waitForInsert(uint64_t referenceCount, Microseconds timeout) const;
-
- private:
- // Signalled when a successful insert is made into a capped collection.
- mutable stdx::condition_variable _cappedNewDataNotifier;
-
- // Mutex used with '_cappedNewDataNotifier'. Protects access to '_cappedInsertCount'.
- mutable stdx::mutex _cappedNewDataMutex;
-
- // A counter, incremented on insertion of new data into the capped collection.
- //
- // The condition which '_cappedNewDataNotifier' is being notified of is an increment of this
- // counter. Access to this counter is synchronized with '_cappedNewDataMutex'.
- uint64_t _cappedInsertCount;
- };
+ StatusWith<RecordId> insertDocument(OperationContext* txn,
+ const DocWriter* doc,
+ bool enforceQuota);
+
+ StatusWith<RecordId> insertDocument(OperationContext* txn,
+ const BSONObj& doc,
+ MultiIndexBlock* indexBlock,
+ bool enforceQuota);
+
+ /**
+ * updates the document @ oldLocation with newDoc
+ * if the document fits in the old space, it is put there
+ * if not, it is moved
+ * @return the post update location of the doc (may or may not be the same as oldLocation)
+ */
+ StatusWith<RecordId> updateDocument(OperationContext* txn,
+ const RecordId& oldLocation,
+ const Snapshotted<BSONObj>& oldDoc,
+ const BSONObj& newDoc,
+ bool enforceQuota,
+ bool indexesAffected,
+ OpDebug* debug,
+ oplogUpdateEntryArgs& args);
+
+ bool updateWithDamagesSupported() const;
/**
- * this is NOT safe through a yield right now
- * not sure if it will be, or what yet
+ * Not allowed to modify indexes.
+ * Illegal to call if updateWithDamagesSupported() returns false.
*/
- class Collection : CappedDocumentDeleteCallback, UpdateNotifier {
- public:
- Collection( OperationContext* txn,
- StringData fullNS,
- CollectionCatalogEntry* details, // does not own
- RecordStore* recordStore, // does not own
- DatabaseCatalogEntry* dbce ); // does not own
-
- ~Collection();
-
- bool ok() const { return _magic == 1357924; }
-
- CollectionCatalogEntry* getCatalogEntry() { return _details; }
- const CollectionCatalogEntry* getCatalogEntry() const { return _details; }
-
- CollectionInfoCache* infoCache() { return &_infoCache; }
- const CollectionInfoCache* infoCache() const { return &_infoCache; }
-
- const NamespaceString& ns() const { return _ns; }
-
- const IndexCatalog* getIndexCatalog() const { return &_indexCatalog; }
- IndexCatalog* getIndexCatalog() { return &_indexCatalog; }
-
- const RecordStore* getRecordStore() const { return _recordStore; }
- RecordStore* getRecordStore() { return _recordStore; }
-
- CursorManager* getCursorManager() const { return &_cursorManager; }
-
- bool requiresIdIndex() const;
-
- Snapshotted<BSONObj> docFor(OperationContext* txn, const RecordId& loc) const;
-
- /**
- * @param out - contents set to the right docs if exists, or nothing.
- * @return true iff loc exists
- */
- bool findDoc(OperationContext* txn, const RecordId& loc, Snapshotted<BSONObj>* out) const;
-
- std::unique_ptr<RecordCursor> getCursor(OperationContext* txn, bool forward = true) const;
-
- /**
- * Returns many cursors that partition the Collection into many disjoint sets. Iterating
- * all returned cursors is equivalent to iterating the full collection.
- */
- std::vector<std::unique_ptr<RecordCursor>> getManyCursors(OperationContext* txn) const;
-
- void deleteDocument( OperationContext* txn,
- const RecordId& loc,
- bool cappedOK = false,
- bool noWarn = false,
- BSONObj* deletedId = 0 );
-
- /**
- * this does NOT modify the doc before inserting
- * i.e. will not add an _id field for documents that are missing it
- *
- * If enforceQuota is false, quotas will be ignored.
- */
- StatusWith<RecordId> insertDocument( OperationContext* txn,
- const BSONObj& doc,
- bool enforceQuota,
- bool fromMigrate = false);
-
- /**
- * Callers must ensure no document validation is performed for this collection when calling
- * this method.
- */
- StatusWith<RecordId> insertDocument( OperationContext* txn,
- const DocWriter* doc,
- bool enforceQuota );
-
- StatusWith<RecordId> insertDocument( OperationContext* txn,
- const BSONObj& doc,
- MultiIndexBlock* indexBlock,
- bool enforceQuota );
-
- /**
- * updates the document @ oldLocation with newDoc
- * if the document fits in the old space, it is put there
- * if not, it is moved
- * @return the post update location of the doc (may or may not be the same as oldLocation)
- */
- StatusWith<RecordId> updateDocument(OperationContext* txn,
- const RecordId& oldLocation,
- const Snapshotted<BSONObj>& oldDoc,
- const BSONObj& newDoc,
- bool enforceQuota,
- bool indexesAffected,
- OpDebug* debug,
- oplogUpdateEntryArgs& args);
-
- bool updateWithDamagesSupported() const;
-
- /**
- * Not allowed to modify indexes.
- * Illegal to call if updateWithDamagesSupported() returns false.
- */
- Status updateDocumentWithDamages(OperationContext* txn,
- const RecordId& loc,
- const Snapshotted<RecordData>& oldRec,
- const char* damageSource,
- const mutablebson::DamageVector& damages,
- oplogUpdateEntryArgs& args);
-
- // -----------
-
- StatusWith<CompactStats> compact(OperationContext* txn, const CompactOptions* options);
-
- /**
- * removes all documents as fast as possible
- * indexes before and after will be the same
- * as will other characteristics
- */
- Status truncate(OperationContext* txn);
-
- /**
- * @param full - does more checks
- * @param scanData - scans each document
- * @return OK if the validate run successfully
- * OK will be returned even if corruption is found
- * deatils will be in result
- */
- Status validate( OperationContext* txn,
- bool full, bool scanData,
- ValidateResults* results, BSONObjBuilder* output );
-
- /**
- * forces data into cache
- */
- Status touch( OperationContext* txn,
- bool touchData, bool touchIndexes,
- BSONObjBuilder* output ) const;
-
- /**
- * Truncate documents newer than the document at 'end' from the capped
- * collection. The collection cannot be completely emptied using this
- * function. An assertion will be thrown if that is attempted.
- * @param inclusive - Truncate 'end' as well iff true
- * XXX: this will go away soon, just needed to move for now
- */
- void temp_cappedTruncateAfter( OperationContext* txn, RecordId end, bool inclusive );
-
- /**
- * Sets the validator for this collection.
- *
- * An empty validator removes all validation.
- * Requires an exclusive lock on the collection.
- */
- Status setValidator(OperationContext* txn, BSONObj validator);
-
- // -----------
-
- //
- // Stats
- //
-
- bool isCapped() const;
-
- /**
- * Get a pointer to a capped insert notifier object. The caller can wait on this object
- * until it is notified of a new insert into the capped collection.
- *
- * It is invalid to call this method unless the collection is capped.
- */
- std::shared_ptr<CappedInsertNotifier> getCappedInsertNotifier() const;
-
- uint64_t numRecords( OperationContext* txn ) const;
-
- uint64_t dataSize( OperationContext* txn ) const;
-
- int averageObjectSize( OperationContext* txn ) const {
- uint64_t n = numRecords( txn );
- if ( n == 0 )
- return 5;
- return static_cast<int>( dataSize( txn ) / n );
- }
-
- uint64_t getIndexSize(OperationContext* opCtx,
- BSONObjBuilder* details = NULL,
- int scale = 1);
-
- // --- end suspect things
-
- private:
-
- /**
- * Returns a non-ok Status if document does not pass this collection's validator.
- */
- Status checkValidation(OperationContext* txn, const BSONObj& document) const;
-
- /**
- * Returns a non-ok Status if validator is not legal for this collection.
- */
- StatusWith<std::unique_ptr<MatchExpression>> parseValidator(const BSONObj& validator) const;
-
- Status recordStoreGoingToMove( OperationContext* txn,
- const RecordId& oldLocation,
- const char* oldBuffer,
- size_t oldSize );
-
- Status recordStoreGoingToUpdateInPlace( OperationContext* txn,
- const RecordId& loc );
-
- Status aboutToDeleteCapped( OperationContext* txn, const RecordId& loc, RecordData data );
-
- /**
- * same semantics as insertDocument, but doesn't do:
- * - some user error checks
- * - adjust padding
- */
- StatusWith<RecordId> _insertDocument( OperationContext* txn,
- const BSONObj& doc,
- bool enforceQuota );
-
- bool _enforceQuota( bool userEnforeQuota ) const;
-
- int _magic;
-
- NamespaceString _ns;
- CollectionCatalogEntry* _details;
- RecordStore* _recordStore;
- DatabaseCatalogEntry* _dbce;
- CollectionInfoCache _infoCache;
- IndexCatalog _indexCatalog;
-
- // Empty means no filter.
- BSONObj _validatorDoc;
- // Points into _validatorDoc. Null means no filter.
- std::unique_ptr<MatchExpression> _validator;
-
- // this is mutable because read only users of the Collection class
- // use it keep state. This seems valid as const correctness of Collection
- // should be about the data.
- mutable CursorManager _cursorManager;
-
- // Notifier object for awaitData. Threads polling a capped collection for new data can wait
- // on this object until notified of the arrival of new data.
- //
- // This is non-null if and only if the collection is a capped collection.
- std::shared_ptr<CappedInsertNotifier> _cappedNotifier;
-
- friend class Database;
- friend class IndexCatalog;
- friend class NamespaceDetails;
- };
+ Status updateDocumentWithDamages(OperationContext* txn,
+ const RecordId& loc,
+ const Snapshotted<RecordData>& oldRec,
+ const char* damageSource,
+ const mutablebson::DamageVector& damages,
+ oplogUpdateEntryArgs& args);
+ // -----------
+
+ StatusWith<CompactStats> compact(OperationContext* txn, const CompactOptions* options);
+
+ /**
+ * removes all documents as fast as possible
+ * indexes before and after will be the same
+ * as will other characteristics
+ */
+ Status truncate(OperationContext* txn);
+
+ /**
+ * @param full - does more checks
+ * @param scanData - scans each document
+ * @return OK if the validate run successfully
+ * OK will be returned even if corruption is found
+ * deatils will be in result
+ */
+ Status validate(OperationContext* txn,
+ bool full,
+ bool scanData,
+ ValidateResults* results,
+ BSONObjBuilder* output);
+
+ /**
+ * forces data into cache
+ */
+ Status touch(OperationContext* txn,
+ bool touchData,
+ bool touchIndexes,
+ BSONObjBuilder* output) const;
+
+ /**
+ * Truncate documents newer than the document at 'end' from the capped
+ * collection. The collection cannot be completely emptied using this
+ * function. An assertion will be thrown if that is attempted.
+ * @param inclusive - Truncate 'end' as well iff true
+ * XXX: this will go away soon, just needed to move for now
+ */
+ void temp_cappedTruncateAfter(OperationContext* txn, RecordId end, bool inclusive);
+
+ /**
+ * Sets the validator for this collection.
+ *
+ * An empty validator removes all validation.
+ * Requires an exclusive lock on the collection.
+ */
+ Status setValidator(OperationContext* txn, BSONObj validator);
+
+ // -----------
+
+ //
+ // Stats
+ //
+
+ bool isCapped() const;
+
+ /**
+ * Get a pointer to a capped insert notifier object. The caller can wait on this object
+ * until it is notified of a new insert into the capped collection.
+ *
+ * It is invalid to call this method unless the collection is capped.
+ */
+ std::shared_ptr<CappedInsertNotifier> getCappedInsertNotifier() const;
+
+ uint64_t numRecords(OperationContext* txn) const;
+
+ uint64_t dataSize(OperationContext* txn) const;
+
+ int averageObjectSize(OperationContext* txn) const {
+ uint64_t n = numRecords(txn);
+ if (n == 0)
+ return 5;
+ return static_cast<int>(dataSize(txn) / n);
+ }
+
+ uint64_t getIndexSize(OperationContext* opCtx, BSONObjBuilder* details = NULL, int scale = 1);
+
+ // --- end suspect things
+
+private:
+ /**
+ * Returns a non-ok Status if document does not pass this collection's validator.
+ */
+ Status checkValidation(OperationContext* txn, const BSONObj& document) const;
+
+ /**
+ * Returns a non-ok Status if validator is not legal for this collection.
+ */
+ StatusWith<std::unique_ptr<MatchExpression>> parseValidator(const BSONObj& validator) const;
+
+ Status recordStoreGoingToMove(OperationContext* txn,
+ const RecordId& oldLocation,
+ const char* oldBuffer,
+ size_t oldSize);
+
+ Status recordStoreGoingToUpdateInPlace(OperationContext* txn, const RecordId& loc);
+
+ Status aboutToDeleteCapped(OperationContext* txn, const RecordId& loc, RecordData data);
+
+ /**
+ * same semantics as insertDocument, but doesn't do:
+ * - some user error checks
+ * - adjust padding
+ */
+ StatusWith<RecordId> _insertDocument(OperationContext* txn,
+ const BSONObj& doc,
+ bool enforceQuota);
+
+ bool _enforceQuota(bool userEnforeQuota) const;
+
+ int _magic;
+
+ NamespaceString _ns;
+ CollectionCatalogEntry* _details;
+ RecordStore* _recordStore;
+ DatabaseCatalogEntry* _dbce;
+ CollectionInfoCache _infoCache;
+ IndexCatalog _indexCatalog;
+
+ // Empty means no filter.
+ BSONObj _validatorDoc;
+ // Points into _validatorDoc. Null means no filter.
+ std::unique_ptr<MatchExpression> _validator;
+
+ // this is mutable because read only users of the Collection class
+ // use it keep state. This seems valid as const correctness of Collection
+ // should be about the data.
+ mutable CursorManager _cursorManager;
+
+ // Notifier object for awaitData. Threads polling a capped collection for new data can wait
+ // on this object until notified of the arrival of new data.
+ //
+ // This is non-null if and only if the collection is a capped collection.
+ std::shared_ptr<CappedInsertNotifier> _cappedNotifier;
+
+ friend class Database;
+ friend class IndexCatalog;
+ friend class NamespaceDetails;
+};
}