diff options
author | Eliot Horowitz <eliot@10gen.com> | 2009-08-19 15:42:44 -0400 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2009-08-19 15:42:44 -0400 |
commit | e88821d778f4b75bec78807844938fd55259d28e (patch) | |
tree | a89861acfc6cd03892f582f2ea9093c88751348c | |
parent | 1a09d3a722c858b087b391dfd08f4cc367202c5c (diff) | |
parent | 4da12ed5093cabf8b1f5013b1d02713efd51e0f0 (diff) | |
download | mongo-e88821d778f4b75bec78807844938fd55259d28e.tar.gz |
Merge branch 'master' of git@github.com:mongodb/mongo
-rw-r--r-- | db/namespace.cpp | 140 | ||||
-rw-r--r-- | db/namespace.h | 43 |
2 files changed, 97 insertions, 86 deletions
diff --git a/db/namespace.cpp b/db/namespace.cpp index a5c21439876..b34e379f7b7 100644 --- a/db/namespace.cpp +++ b/db/namespace.cpp @@ -1,4 +1,4 @@ -// namespacedetails.cpp +// namespace.cpp /** * Copyright (C) 2008 10gen Inc. @@ -32,7 +32,7 @@ namespace mongo { BSONObj idKeyPattern = fromjson("{\"_id\":1}"); - /* deleted lists -- linked lists of deleted records -- tehy are placed in 'buckets' of various sizes + /* deleted lists -- linked lists of deleted records -- are placed in 'buckets' of various sizes so you can look for a deleterecord about the right size. */ int bucketSizes[] = { @@ -41,8 +41,6 @@ namespace mongo { 0x400000, 0x800000 }; -//NamespaceIndexMgr namespaceIndexMgr; - bool NamespaceIndex::exists() const { return !boost::filesystem::exists(path()); } @@ -222,9 +220,7 @@ namespace mongo { } void NamespaceDetails::dumpDeleted(set<DiskLoc> *extents) { -// out() << "DUMP deleted chains" << endl; for ( int i = 0; i < Buckets; i++ ) { -// out() << " bucket " << i << endl; DiskLoc dl = deletedList[i]; while ( !dl.isNull() ) { DeletedRecord *r = dl.drec(); @@ -239,7 +235,6 @@ namespace mongo { dl = r->nextDeleted; } } -// out() << endl; } /* combine adjacent deleted records @@ -548,9 +543,9 @@ namespace mongo { allIndexKeys.clear(); NamespaceDetails *d = nsdetails(ns.c_str()); for ( int i = 0; i < d->nIndexes; i++ ) { -// set<string> fields; + // set<string> fields; d->indexes[i].keyPattern().getFieldNames(allIndexKeys); -// allIndexKeys.insert(fields.begin(),fields.end()); + // allIndexKeys.insert(fields.begin(),fields.end()); } } @@ -614,67 +609,68 @@ namespace mongo { } } - void renameNamespace( const char *from, const char *to ) { - NamespaceIndex *ni = nsindex( from ); - assert( ni && ni->details( from ) && !ni->details( to ) ); - - // Our namespace and index details will move to a different - // memory location. The only references to namespace and - // index details across commands are in cursors and nsd - // transient (including query cache) so clear these. - ClientCursor::invalidate( from ); - NamespaceDetailsTransient::drop( from ); - - NamespaceDetails *details = ni->details( from ); - ni->add( to, *details ); - ni->drop( from ); - details = ni->details( to ); - - BSONObj oldSpec; - char database[256]; - nsToClient(from, database); - string s = database; - s += ".system.namespaces"; - assert( Helpers::findOne( s.c_str(), BSON( "name" << from ), oldSpec ) ); - - BSONObjBuilder newSpecB; - BSONObjIterator i( oldSpec.getObjectField( "options" ) ); - while( i.more() ) { - BSONElement e = i.next(); - if ( strcmp( e.fieldName(), "create" ) != 0 ) - newSpecB.append( e ); - else - newSpecB << "create" << to; - } - BSONObj newSpec = newSpecB.done(); - addNewNamespaceToCatalog( to, newSpec.isEmpty() ? 0 : &newSpec ); - - deleteObjects( s.c_str(), BSON( "name" << from ), false, false, true ); - // oldSpec variable no longer valid memory - - BSONObj oldIndexSpec; - s = database; - s += ".system.indexes"; - while( Helpers::findOne( s.c_str(), BSON( "ns" << from ), oldIndexSpec ) ) { - BSONObjBuilder newIndexSpecB; - BSONObjIterator i( oldIndexSpec ); - while( i.more() ) { - BSONElement e = i.next(); - if ( strcmp( e.fieldName(), "ns" ) != 0 ) - newIndexSpecB.append( e ); - else - newIndexSpecB << "ns" << to; - } - BSONObj newIndexSpec = newIndexSpecB.done(); - DiskLoc newIndexSpecLoc = theDataFileMgr.insert( s.c_str(), newIndexSpec.objdata(), newIndexSpec.objsize(), true, BSONElement(), false ); - int indexI = details->findIndexByName( oldIndexSpec.getStringField( "name" ) ); - IndexDetails &indexDetails = details->indexes[ indexI ]; - string oldIndexNs = indexDetails.indexNamespace(); - indexDetails.info = newIndexSpecLoc; - string newIndexNs = indexDetails.indexNamespace(); - - BtreeBucket::renameIndexNamespace( oldIndexNs.c_str(), newIndexNs.c_str() ); - deleteObjects( s.c_str(), oldIndexSpec.getOwned(), true, false, true ); - } - } + void renameNamespace( const char *from, const char *to ) { + NamespaceIndex *ni = nsindex( from ); + assert( ni && ni->details( from ) && !ni->details( to ) ); + + // Our namespace and index details will move to a different + // memory location. The only references to namespace and + // index details across commands are in cursors and nsd + // transient (including query cache) so clear these. + ClientCursor::invalidate( from ); + NamespaceDetailsTransient::drop( from ); + + NamespaceDetails *details = ni->details( from ); + ni->add( to, *details ); + ni->drop( from ); + details = ni->details( to ); + + BSONObj oldSpec; + char database[MaxClientLen]; + nsToClient(from, database); + string s = database; + s += ".system.namespaces"; + assert( Helpers::findOne( s.c_str(), BSON( "name" << from ), oldSpec ) ); + + BSONObjBuilder newSpecB; + BSONObjIterator i( oldSpec.getObjectField( "options" ) ); + while( i.more() ) { + BSONElement e = i.next(); + if ( strcmp( e.fieldName(), "create" ) != 0 ) + newSpecB.append( e ); + else + newSpecB << "create" << to; + } + BSONObj newSpec = newSpecB.done(); + addNewNamespaceToCatalog( to, newSpec.isEmpty() ? 0 : &newSpec ); + + deleteObjects( s.c_str(), BSON( "name" << from ), false, false, true ); + // oldSpec variable no longer valid memory + + BSONObj oldIndexSpec; + s = database; + s += ".system.indexes"; + while( Helpers::findOne( s.c_str(), BSON( "ns" << from ), oldIndexSpec ) ) { + BSONObjBuilder newIndexSpecB; + BSONObjIterator i( oldIndexSpec ); + while( i.more() ) { + BSONElement e = i.next(); + if ( strcmp( e.fieldName(), "ns" ) != 0 ) + newIndexSpecB.append( e ); + else + newIndexSpecB << "ns" << to; + } + BSONObj newIndexSpec = newIndexSpecB.done(); + DiskLoc newIndexSpecLoc = theDataFileMgr.insert( s.c_str(), newIndexSpec.objdata(), newIndexSpec.objsize(), true, BSONElement(), false ); + int indexI = details->findIndexByName( oldIndexSpec.getStringField( "name" ) ); + IndexDetails &indexDetails = details->indexes[ indexI ]; + string oldIndexNs = indexDetails.indexNamespace(); + indexDetails.info = newIndexSpecLoc; + string newIndexNs = indexDetails.indexNamespace(); + + BtreeBucket::renameIndexNamespace( oldIndexNs.c_str(), newIndexNs.c_str() ); + deleteObjects( s.c_str(), oldIndexSpec.getOwned(), true, false, true ); + } + } + } // namespace mongo diff --git a/db/namespace.h b/db/namespace.h index 4a207f4a557..4470aa63f09 100644 --- a/db/namespace.h +++ b/db/namespace.h @@ -19,11 +19,9 @@ #pragma once #include "../stdafx.h" - #include "jsobj.h" #include "queryutil.h" #include "storage.h" - #include "../util/hashtab.h" #include "../util/mmap.h" @@ -33,8 +31,11 @@ namespace mongo { #pragma pack(1) -// "database.a.b.c" -> "database" - const int MaxClientLen = 256; + /* in the mongo source code, "client" means "database". */ + + const int MaxClientLen = 256; // max str len for the db name + + // "database.a.b.c" -> "database" inline void nsToClient(const char *ns, char *database) { const char *p = ns; char *q = database; @@ -55,10 +56,14 @@ namespace mongo { return buf; } + /* e.g. + NamespaceString ns("acme.orders"); + cout << ns.coll; // "orders" + */ class NamespaceString { public: string db; - string coll; + string coll; // note collection names can have periods in them for organizing purposes (e.g. "system.indexes") private: void init(const char *ns) { const char *p = strchr(ns, '.'); @@ -71,6 +76,7 @@ namespace mongo { NamespaceString( const string& ns ) { init(ns.c_str()); } }; + /* This helper class is used to make the HashMap below in NamespaceDetails */ class Namespace { public: enum MaxNsLenValue { MaxNsLen = 128 }; @@ -106,6 +112,7 @@ namespace mongo { /** ( foo.bar ).getSisterNS( "blah" ) == foo.blah + perhaps this should move to the NamespaceString helper? */ string getSisterNS( const char * local ) { assert( local && local[0] != '.' ); @@ -118,23 +125,31 @@ namespace mongo { char buf[MaxNsLen]; }; + /* deleted lists -- linked lists of deleted records -- are placed in 'buckets' of various sizes + so you can look for a deleterecord about the right size. + */ const int Buckets = 19; const int MaxBucket = 18; - const int MaxIndexes = 10; - //extern BSONObj idKeyPattern; // { _id : 1 } + /* Maximum # of indexes per collection. We need to raise this limit at some point. + (Backward datafile compatibility is main issue with changing.) + */ + const int MaxIndexes = 10; + /* Details about a particular index. There is one of these effectively for each object in + system.namespaces (although this also includes the head pointer, which is not in that + collection). + */ class IndexDetails { public: - DiskLoc head; /* btree head */ + DiskLoc head; /* btree head disk location */ /* Location of index info object. Format: { name:"nameofindex", ns:"parentnsname", key: {keypattobject}[, unique: <bool>] } This object is in the system.indexes collection. Note that since we - have a pointer to the object here, the object in system.indexes must - never move. + have a pointer to the object here, the object in system.indexes MUST NEVER MOVE. */ DiskLoc info; @@ -491,14 +506,14 @@ namespace mongo { void add(const char *ns, DiskLoc& loc, bool capped) { NamespaceDetails details( loc, capped ); - add( ns, details ); + add( ns, details ); } - void add( const char *ns, const NamespaceDetails &details ) { + void add( const char *ns, const NamespaceDetails &details ) { init(); Namespace n(ns); uassert("too many namespaces/collections", ht->put(n, details)); - } + } /* just for diagnostics */ size_t detailsOffset(NamespaceDetails *d) { @@ -553,7 +568,7 @@ namespace mongo { string database_; }; - extern string dbpath; + extern string dbpath; // --dbpath parm // Rename a namespace within current 'client' db. // (Arguments should include db name) |