virtual bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { string from = cmdObj.getStringField("clone"); if ( from.empty() ) return false; /* replication note: we must logOp() not the command, but the cloned data -- if the slave were to clone it would get a different point-in-time and not match. */ return cloneFrom(from.c_str(), errmsg, database->name, /*logForReplication=*/!fromRepl, /*slaveok*/false, /*usereplauth*/false); }
/* grab initial copy of a database from the master */ bool ReplSource::resync(string db) { string dummyNs = resyncDrop( db.c_str(), "internal" ); Client::Context ctx( dummyNs ); { log() << "resync: cloning database " << db << " to get an initial copy" << endl; ReplInfo r("resync: cloning a database"); string errmsg; bool ok = cloneFrom(hostName.c_str(), errmsg, cc().database()->name, false, /*slaveok*/ true, /*replauth*/ true, /*snapshot*/false, /*mayYield*/true, /*mayBeInterrupted*/false); if ( !ok ) { problem() << "resync of " << db << " from " << hostName << " failed " << errmsg << endl; throw SyncException(); } } log() << "resync: done with initial clone for db: " << db << endl; return true; }
virtual bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { string fromhost = cmdObj.getStringField("fromhost"); if ( fromhost.empty() ) { /* copy from self */ stringstream ss; ss << "localhost:" << cmdLine.port; fromhost = ss.str(); } string fromdb = cmdObj.getStringField("fromdb"); string todb = cmdObj.getStringField("todb"); if ( fromhost.empty() || todb.empty() || fromdb.empty() ) { errmsg = "parms missing - {copydb: 1, fromhost: <hostname>, fromdb: <db>, todb: <db>}"; return false; } setClient(todb.c_str()); bool res = cloneFrom(fromhost.c_str(), errmsg, fromdb, /*logForReplication=*/!fromRepl, /*slaveok*/false, /*replauth*/false, /*snapshot*/true); cc().clearns(); return res; }
CanMessage::CanMessage(const CanMessage &msg) { cloneFrom(msg); }
bool NTriangulation::intelligentSimplify() { bool changed; { // Begin scope for change event block. ChangeEventSpan span(this); // Reduce to a local minimum. changed = simplifyToLocalMinimum(true); // Clone to work with when we might want to roll back changes. NTriangulation* use; // Variables used for selecting random 4-4 moves. std::vector<std::pair<NEdge*, int> > fourFourAvailable; std::pair<NEdge*, int> fourFourChoice; unsigned long fourFourAttempts; unsigned long fourFourCap; NEdge* edge; EdgeIterator eit; int axis; while (true) { // --- Random 4-4 moves --- // Clone the triangulation and start making changes that might or // might not lead to a simplification. // If we've already simplified then there's no need to use a // separate clone since we won't need to undo further changes. use = (changed ? this : new NTriangulation(*this)); // Make random 4-4 moves. fourFourAttempts = fourFourCap = 0; while (true) { // Calculate the list of available 4-4 moves. fourFourAvailable.clear(); // Use edges() to ensure the skeleton has been calculated. for (eit = use->edges().begin(); eit != use->edges().end(); eit++) { edge = *eit; for (axis = 0; axis < 2; axis++) if (use->fourFourMove(edge, axis, true, false)) fourFourAvailable.push_back( std::make_pair(edge, axis)); } // Increment fourFourCap if needed. if (fourFourCap < COEFF_4_4 * fourFourAvailable.size()) fourFourCap = COEFF_4_4 * fourFourAvailable.size(); // Have we tried enough 4-4 moves? if (fourFourAttempts >= fourFourCap) break; // Perform a random 4-4 move on the clone. fourFourChoice = fourFourAvailable[ static_cast<unsigned>(rand()) % fourFourAvailable.size()]; use->fourFourMove(fourFourChoice.first, fourFourChoice.second, false, true); // See if we can simplify now. if (use->simplifyToLocalMinimum(true)) { // We have successfully simplified! // Start all over again. fourFourAttempts = fourFourCap = 0; } else fourFourAttempts++; } // Sync the real triangulation with the clone if appropriate. if (use != this) { // At this point, changed == false. if (use->size() < size()) { // The 4-4 moves were successful; accept them. cloneFrom(*use); changed = true; } delete use; } // At this point we have decided that 4-4 moves will help us // no more. // --- Open book and close book moves --- if (hasBoundaryTriangles()) { // Clone again, always -- we don't want to create gratuitous // boundary triangles if they won't be of any help. use = new NTriangulation(*this); // Perform every book opening move we can find. TriangleIterator fit; bool opened = false; bool openedNow = true; while (openedNow) { openedNow = false; for (fit = use->triangles().begin(); fit != use->triangles().end(); ++fit) if (use->openBook(*fit, true, true)) { opened = openedNow = true; break; } } // If we're lucky, we now have an edge that we can collapse. if (opened) { if (use->simplifyToLocalMinimum(true)) { // Yay! cloneFrom(*use); changed = true; } else { // No good. // Ditch use and don't open anything. opened = false; } } delete use; // If we did any book opening stuff, start all over again. if (opened) continue; // If we've made it this far then there seems to be // nothing left to do. // // Perform book *closing* moves to simplify the boundary // of the triangulation, even if this does not actually // reduce the number of tetrahedra. // // Since we always want to simplify the boundary, make // the changes directly to this triangulation. bool closed = false; EdgeIterator eit; for (eit = edges().begin(); eit != edges().end(); ++eit) if (closeBook(*eit, true, true)) { closed = true; changed = true; // We don't actually care whether we reduce the // number of tetrahedra or not. Ignore the // return value from simplifyToLocalMinimum(). simplifyToLocalMinimum(true); break; } // If we *did* manage to close a book, there might be // further internal simplifications that we can now do. // Back to the top. if (closed) continue; } // Nothing more we can do here. break; } } // End scope for change event span. return changed; }