diff options
Diffstat (limited to 'db/namespace.h')
-rw-r--r-- | db/namespace.h | 77 |
1 files changed, 64 insertions, 13 deletions
diff --git a/db/namespace.h b/db/namespace.h index ef3d04e..3dfb3f3 100644 --- a/db/namespace.h +++ b/db/namespace.h @@ -20,7 +20,7 @@ #include "../pch.h" #include "jsobj.h" -#include "queryutil.h" +#include "querypattern.h" #include "diskloc.h" #include "../util/hashtab.h" #include "mongommf.h" @@ -44,6 +44,21 @@ namespace mongo { NamespaceString( const string& ns ) { init(ns.c_str()); } string ns() const { return db + '.' + coll; } bool isSystem() const { return strncmp(coll.c_str(), "system.", 7) == 0; } + + /** + * @return true if ns is 'normal'. $ used for collections holding index data, which do not contain BSON objects in their records. + * special case for the local.oplog.$main ns -- naming it as such was a mistake. + */ + static bool normal(const char* ns) { + const char *p = strchr(ns, '$'); + if( p == 0 ) + return true; + return strcmp( ns, "local.oplog.$main" ) == 0; + } + + static bool special(const char *ns) { + return !normal(ns) || strstr(ns, ".system."); + } private: void init(const char *ns) { const char *p = strchr(ns, '.'); @@ -67,6 +82,9 @@ namespace mongo { bool operator==(const char *r) const { return strcmp(buf, r) == 0; } bool operator==(const Namespace& r) const { return strcmp(buf, r.buf) == 0; } int hash() const; // value returned is always > 0 + + size_t size() const { return strlen( buf ); } + string toString() const { return (string) buf; } operator string() const { return (string) buf; } @@ -93,8 +111,8 @@ namespace mongo { namespace mongo { - /** @return true if a client can modify this namespace - things like *.system.users + /** @return true if a client can modify this namespace even though it is under ".system." + For example <dbname>.system.users is ok for regular clients to update. @param write used when .system.js */ bool legalClientSystemNS( const string& ns , bool write ); @@ -154,7 +172,7 @@ namespace mongo { unsigned long long reservedA; long long extraOffset; // where the $extra info is located (bytes relative to this) public: - int indexBuildInProgress; // 1 if in prog + int indexBuildInProgress; // 1 if in prog unsigned reservedB; // ofs 424 (8) struct Capped2 { @@ -302,13 +320,17 @@ namespace mongo { void paddingFits() { double x = paddingFactor - 0.01; - if ( x >= 1.0 ) - getDur().setNoJournal(&paddingFactor, &x, sizeof(x)); + if ( x >= 1.0 ) { + *getDur().writing(&paddingFactor) = x; + //getDur().setNoJournal(&paddingFactor, &x, sizeof(x)); + } } void paddingTooSmall() { double x = paddingFactor + 0.6; - if ( x <= 2.0 ) - getDur().setNoJournal(&paddingFactor, &x, sizeof(x)); + if ( x <= 2.0 ) { + *getDur().writing(&paddingFactor) = x; + //getDur().setNoJournal(&paddingFactor, &x, sizeof(x)); + } } // @return offset in indexes[] @@ -337,6 +359,10 @@ namespace mongo { return -1; } + bool haveIdIndex() { + return (flags & NamespaceDetails::Flag_HaveIdIndex) || findIdIndex() >= 0; + } + /* return which "deleted bucket" for this size object */ static int bucket(int n) { for ( int i = 0; i < Buckets; i++ ) @@ -412,9 +438,12 @@ namespace mongo { static std::map< string, shared_ptr< NamespaceDetailsTransient > > _map; public: NamespaceDetailsTransient(const char *ns) : _ns(ns), _keysComputed(false), _qcWriteCount() { } + private: /* _get() is not threadsafe -- see get_inlock() comments */ static NamespaceDetailsTransient& _get(const char *ns); - /* use get_w() when doing write operations */ + public: + /* use get_w() when doing write operations. this is safe as there is only 1 write op and it's exclusive to everything else. + for reads you must lock and then use get_inlock() instead. */ static NamespaceDetailsTransient& get_w(const char *ns) { DEV assertInWriteLock(); return _get(ns); @@ -427,6 +456,26 @@ namespace mongo { static void clearForPrefix(const char *prefix); static void eraseForPrefix(const char *prefix); + /** + * @return a cursor interface to the query optimizer. The implementation may + * utilize a single query plan or interleave results from multiple query + * plans before settling on a single query plan. Note that the schema of + * currKey() documents, the matcher(), and the isMultiKey() nature of the + * cursor may change over the course of iteration. + * + * @param order - If no index exists that satisfies this sort order, an + * empty shared_ptr will be returned. + * + * The returned cursor may @throw inside of advance() or recoverFromYield() in + * certain error cases, for example if a capped overrun occurred during a yield. + * This indicates that the cursor was unable to perform a complete scan. + * + * This is a work in progress. Partial list of features not yet implemented: + * - modification of scanned documents + * - covered indexes + */ + static shared_ptr<Cursor> getCursor( const char *ns, const BSONObj &query, const BSONObj &order = BSONObj() ); + /* indexKeys() cache ---------------------------------------------------- */ /* assumed to be in write lock for this */ private: @@ -447,12 +496,12 @@ namespace mongo { /* IndexSpec caching */ private: map<const IndexDetails*,IndexSpec> _indexSpecs; - static mongo::mutex _isMutex; + static SimpleMutex _isMutex; public: const IndexSpec& getIndexSpec( const IndexDetails * details ) { IndexSpec& spec = _indexSpecs[details]; if ( ! spec._finishedInit ) { - scoped_lock lk(_isMutex); + SimpleMutex::scoped_lock lk(_isMutex); if ( ! spec._finishedInit ) { spec.reset( details ); assert( spec._finishedInit ); @@ -466,7 +515,7 @@ namespace mongo { int _qcWriteCount; map< QueryPattern, pair< BSONObj, long long > > _qcCache; public: - static mongo::mutex _qcMutex; + static SimpleMutex _qcMutex; /* you must be in the qcMutex when calling this (and using the returned val): */ static NamespaceDetailsTransient& get_inlock(const char *ns) { return _get(ns); @@ -479,7 +528,7 @@ namespace mongo { void notifyOfWriteOp() { if ( _qcCache.empty() ) return; - if ( ++_qcWriteCount >= 100 ) + if ( ++_qcWriteCount >= 1000 ) clearQueryCache(); } BSONObj indexForPattern( const QueryPattern &pattern ) { @@ -564,6 +613,8 @@ namespace mongo { boost::filesystem::path path() const; + unsigned long long fileLength() const { return f.length(); } + private: void maybeMkdir() const; |