summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2009-08-19 15:42:44 -0400
committerEliot Horowitz <eliot@10gen.com>2009-08-19 15:42:44 -0400
commite88821d778f4b75bec78807844938fd55259d28e (patch)
treea89861acfc6cd03892f582f2ea9093c88751348c
parent1a09d3a722c858b087b391dfd08f4cc367202c5c (diff)
parent4da12ed5093cabf8b1f5013b1d02713efd51e0f0 (diff)
downloadmongo-e88821d778f4b75bec78807844938fd55259d28e.tar.gz
Merge branch 'master' of git@github.com:mongodb/mongo
-rw-r--r--db/namespace.cpp140
-rw-r--r--db/namespace.h43
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)