From 1bf45a0843ae3f28977f3a26a637c478ac557371 Mon Sep 17 00:00:00 2001 From: Dwight Date: Mon, 7 Jul 2008 18:57:04 -0400 Subject: fix deleteindexes and drop issue minor hashtab fix ensureindex works now if collection DNE --- db/db.cpp | 2 +- db/namespace.h | 15 +++++++++++++-- db/pdfile.cpp | 48 +++++++++++++++++++++++++++++++++++++++++------- db/pdfile.h | 5 ----- db/query.cpp | 26 +++++++++++++++++++------- db/storage.h | 6 ++++-- grid/message.cpp | 4 ++-- util/hashtab.h | 5 ++++- 8 files changed, 84 insertions(+), 27 deletions(-) diff --git a/db/db.cpp b/db/db.cpp index 8debc342790..0a37b98c20a 100644 --- a/db/db.cpp +++ b/db/db.cpp @@ -494,7 +494,7 @@ void connThread() stringstream ss; if( !dbMsgPort.recv(m) ) { - cout << "MessagingPort::recv(): returned false " << dbMsgPort.farEnd.toString() << endl; + cout << "end connection " << dbMsgPort.farEnd.toString() << endl; dbMsgPort.shutdown(); break; } diff --git a/db/namespace.h b/db/namespace.h index f35b84acdd2..d70ae6db3af 100644 --- a/db/namespace.h +++ b/db/namespace.h @@ -46,8 +46,14 @@ const int MaxIndexes = 10; class IndexDetails { public: DiskLoc head; /* btree head */ - /* index info object. - { name:"nameofindex", ns:"parentnsname", key: {keypattobject} } + + /* Location of index info object. Format: + + { name:"nameofindex", ns:"parentnsname", key: {keypattobject} } + + 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. */ DiskLoc info; @@ -70,6 +76,11 @@ public: s += io.getStringField("name"); return s; } + + /* delete this index. does NOT celan up the system catalog + (system.indexes or system.namespaces) -- only NamespaceIndex. + */ + void kill(); }; extern int bucketSizes[]; diff --git a/db/pdfile.cpp b/db/pdfile.cpp index 816f91a4015..0f4f72e0b8d 100644 --- a/db/pdfile.cpp +++ b/db/pdfile.cpp @@ -344,9 +344,17 @@ auto_ptr makeNamespaceCursor() { return auto_ptr(new NamespaceCursor()); }*/ -void newNamespace(const char *ns) { +/* add a new namespace to the system catalog (.system.namespaces). +*/ +void addNewNamespaceToCatalog(const char *ns) { cout << "New namespace: " << ns << endl; - if( strstr(ns, "system.namespaces") == 0 ) { + if( strstr(ns, "system.namespaces") ) { + // system.namespaces holds all the others, so it is not explicitly listed in the catalog. + // TODO: fix above should not be strstr! + return; + } + + { JSObjBuilder b; b.append("name", ns); JSObj j = b.done(); @@ -370,15 +378,19 @@ int initialExtentSize(int len) { } // { ..., capped: true, size: ..., max: ... } +// returns true if successful bool userCreateNS(const char *ns, JSObj& j, string& err) { if( nsdetails(ns) ) { err = "collection already exists"; return false; } - cout << j.toString() << endl; + cout << "create collection " << ns << ' ' << j.toString() << endl; - newNamespace(ns); + /* todo: do this only when we have allocated space successfully? or we could insert with a { ok: 0 } field + and then go back and set to ok : 1 after we are done. + */ + addNewNamespaceToCatalog(ns); int ies = initialExtentSize(128); Element e = j.findElement("size"); @@ -608,6 +620,16 @@ auto_ptr findTableScan(const char *ns, JSObj& order) { void aboutToDelete(const DiskLoc& dl); +/* delete this index. does NOT celan up the system catalog + (system.indexes or system.namespaces) -- only NamespaceIndex. +*/ +void IndexDetails::kill() { + string ns = indexNamespace(); + client->namespaceIndex.kill(ns.c_str()); + head.setInvalid(); + info.setInvalid(); +} + /* Pull out the relevant key objects from obj, so we can index them. Note that the set is multiple elements only when it's a "multikey" array. @@ -895,6 +917,8 @@ void indexRecord(NamespaceDetails *d, const void *buf, int len, DiskLoc newReco } } +extern JSObj emptyObj; + DiskLoc DataFileMgr::insert(const char *ns, const void *buf, int len, bool god) { bool addIndex = false; const char *sys = strstr(ns, "system."); @@ -915,7 +939,10 @@ DiskLoc DataFileMgr::insert(const char *ns, const void *buf, int len, bool god) NamespaceDetails *d = nsdetails(ns); if( d == 0 ) { - newNamespace(ns); + addNewNamespaceToCatalog(ns); + /* todo: shouldn't be in the namespace catalog until after the allocations here work. + also if this is an addIndex, those checks should happen before this! + */ client->newestFile()->newExtent(ns, initialExtentSize(len)); d = nsdetails(ns); } @@ -936,8 +963,15 @@ DiskLoc DataFileMgr::insert(const char *ns, const void *buf, int len, bool god) } tableToIndex = nsdetails(tabletoidxns); if( tableToIndex == 0 ) { - cout << "user warning: ignoring add index, no such collection:" << tabletoidxns << endl; - return DiskLoc(); + // try to create it + string err; + if( !userCreateNS(tabletoidxns, emptyObj, err) ) { + cout << "ERROR: failed to create collection while adding its index. " << tabletoidxns << endl; + return DiskLoc(); + } + tableToIndex = nsdetails(tabletoidxns); + cout << "info: creating collection " << tabletoidxns << " on add index\n"; + assert( tableToIndex ); } if( tableToIndex->nIndexes >= MaxIndexes ) { cout << "user warning: bad add index attempt, too many indexes for:" << tabletoidxns << endl; diff --git a/db/pdfile.h b/db/pdfile.h index 17933eb246f..8aa31ef26aa 100644 --- a/db/pdfile.h +++ b/db/pdfile.h @@ -342,11 +342,6 @@ inline BtreeBucket* DiskLoc::btree() const { return (BtreeBucket*) rec()->data; } -inline Bucket* DiskLoc::bucket() const { - assert( fileNo != -1 ); - return (Bucket*) rec()->data; -} - /*---------------------------------------------------------------------*/ // customer, or rather a customer's database -- i guess down the line diff --git a/db/query.cpp b/db/query.cpp index 81b9a35549a..fd5491421f8 100644 --- a/db/query.cpp +++ b/db/query.cpp @@ -154,10 +154,10 @@ void deleteObjects(const char *ns, JSObj pattern, bool justOne) { if( strstr(ns, ".system.") ) { if( strstr(ns, ".system.namespaces") ){ - cout << "WARNING: delete on system namespace " << ns << endl; + cout << "info: delete on system namespace " << ns << '\n'; } else if( strstr(ns, ".system.indexes") ) { - cout << "WARNING: delete on system namespace " << ns << endl; + cout << "info: delete on system namespace " << ns << '\n'; } else { cout << "ERROR: attempt to delete in system namespace " << ns << endl; @@ -636,15 +636,18 @@ inline bool _runCommands(const char *ns, JSObj& jsobj, stringstream& ss, BufBuil valid = true; string dropNs = us + '.' + e.valuestr(); NamespaceDetails *d = nsdetails(dropNs.c_str()); - cout << "CMD: clean " << dropNs << endl; - if( d ) { + cout << "CMD: drop " << dropNs << endl; + if( d == 0 ) { + anObjBuilder.append("errmsg", "ns not found"); + } + else if( d->nIndexes != 0 ) { + anObjBuilder.append("errmsg", "ns has indexes (not permitted on drop)"); + } + else { ok = true; anObjBuilder.append("ns", dropNs.c_str()); client->namespaceIndex.kill(dropNs.c_str()); } - else { - anObjBuilder.append("errmsg", "ns not found"); - } } else if( strcmp( e.fieldName(), "validate") == 0 ) { valid = true; @@ -679,6 +682,8 @@ inline bool _runCommands(const char *ns, JSObj& jsobj, stringstream& ss, BufBuil anObjBuilder.append("nIndexesWas", (double)d->nIndexes); anObjBuilder.append("msg", "all indexes deleted for collection"); cout << " alpha implementation, space not reclaimed" << endl; + for( int i = 0; i < d->nIndexes; i++ ) + d->indexes[i].kill(); d->nIndexes = 0; } else { @@ -687,6 +692,13 @@ inline bool _runCommands(const char *ns, JSObj& jsobj, stringstream& ss, BufBuil if( x >= 0 ) { cout << " d->nIndexes was " << d->nIndexes << endl; anObjBuilder.append("nIndexesWas", (double)d->nIndexes); + + /* note it is important we remove the IndexDetails with this + call, otherwise, on recreate, the old one would be reused, and its + IndexDetails::info ptr would be bad info. + */ + d->indexes[x].kill(); + d->nIndexes--; for( int i = x; i < d->nIndexes; i++ ) d->indexes[i] = d->indexes[i+1]; diff --git a/db/storage.h b/db/storage.h index dd15a38df8e..c11a548f103 100644 --- a/db/storage.h +++ b/db/storage.h @@ -15,7 +15,6 @@ class Extent; class BtreeBucket; class JSObj; class PhysicalDataFile; -class Bucket; class DiskLoc { int fileNo; /* this will be volume, file #, etc. */ @@ -84,12 +83,15 @@ public: return fileNo < b.fileNo; } + /* get the "thing" associated with this disk location. + it is assumed the object is what it is -- you must asure that: + think of this as an unchecked type cast. + */ JSObj obj() const; Record* rec() const; DeletedRecord* drec() const; Extent* ext() const; BtreeBucket* btree() const; - Bucket* bucket() const; PhysicalDataFile& pdf() const; }; diff --git a/grid/message.cpp b/grid/message.cpp index 40b6af6f7cc..d099ded693e 100644 --- a/grid/message.cpp +++ b/grid/message.cpp @@ -113,7 +113,7 @@ bool MessagingPort::recv(Message& m) { while( 1 ) { int x = ::recv(sock, lenbuf, lft, 0); if( x == 0 ) { - cout << "MessagingPort::recv(): conn closed? " << farEnd.toString() << endl; + DEV cout << "MessagingPort::recv(): conn closed? " << farEnd.toString() << endl; m.reset(); return false; } @@ -151,7 +151,7 @@ bool MessagingPort::recv(Message& m) { while( 1 ) { int x = ::recv(sock, p, left, 0); if( x == 0 ) { - cout << "MessagingPort::recv(): conn closed? " << farEnd.toString() << endl; + DEV cout << "MessagingPort::recv(): conn closed? " << farEnd.toString() << endl; m.reset(); return false; } diff --git a/util/hashtab.h b/util/hashtab.h index 9ea3c2342d5..ed3bde0c251 100644 --- a/util/hashtab.h +++ b/util/hashtab.h @@ -30,6 +30,7 @@ public: Key k; Type value; bool inUse() { return hash != 0; } + void setUnused() { hash = 0; } } *nodes; int n; @@ -85,8 +86,10 @@ public: void kill(const Key& k) { bool found; int i = _find(k, found); - if( i >= 0 && found ) + if( i >= 0 && found ) { nodes[i].k.kill(); + nodes[i].setUnused(); + } } void put(const Key& k, const Type& value) { -- cgit v1.2.1