Exemple #1
0
 template <typename T> void unserialize(std::string& buf, T& obj)
 {
   diy::StringBuffer bb(buf);
   diy::load(bb, obj);
   buf.clear();
 }
Exemple #2
0
    std::string newRunQuery(Message& m, QueryMessage& q, CurOp& curop, Message &result) {
        // Validate the namespace.
        const char *ns = q.ns;
        uassert(16332, "can't have an empty ns", ns[0]);

        const NamespaceString nsString(ns);
        uassert(16256, str::stream() << "Invalid ns [" << ns << "]", nsString.isValid());

        // Set curop information.
        curop.debug().ns = ns;
        curop.debug().ntoreturn = q.ntoreturn;
        curop.debug().query = q.query;
        curop.setQuery(q.query);

        // If the query is really a command, run it.
        if (nsString.isCommand()) {
            int nToReturn = q.ntoreturn;
            uassert(16979, str::stream() << "bad numberToReturn (" << nToReturn
                                         << ") for $cmd type ns - can only be 1 or -1",
                    nToReturn == 1 || nToReturn == -1);

            curop.markCommand();

            BufBuilder bb;
            bb.skip(sizeof(QueryResult));

            BSONObjBuilder cmdResBuf;
            if (!runCommands(ns, q.query, curop, bb, cmdResBuf, false, q.queryOptions)) {
                uasserted(13530, "bad or malformed command request?");
            }

            curop.debug().iscommand = true;
            // TODO: Does this get overwritten/do we really need to set this twice?
            curop.debug().query = q.query;

            QueryResult* qr = reinterpret_cast<QueryResult*>(bb.buf());
            bb.decouple();
            qr->setResultFlagsToOk();
            qr->len = bb.len();
            curop.debug().responseLength = bb.len();
            qr->setOperation(opReply);
            qr->cursorId = 0;
            qr->startingFrom = 0;
            qr->nReturned = 1;
            result.setData(qr, true);
            return "";
        }

        // This is a read lock.  We require this because if we're parsing a $where, the
        // where-specific parsing code assumes we have a lock and creates execution machinery that
        // requires it.
        Client::ReadContext ctx(q.ns);

        // Parse the qm into a CanonicalQuery.
        CanonicalQuery* cq;
        Status canonStatus = CanonicalQuery::canonicalize(q, &cq);
        if (!canonStatus.isOK()) {
            uasserted(17287, str::stream() << "Can't canonicalize query: " << canonStatus.toString());
        }
        verify(cq);

        QLOG() << "Running query on new system: " << cq->toString();

        // Parse, canonicalize, plan, transcribe, and get a runner.
        Runner* rawRunner = NULL;

        // We use this a lot below.
        const LiteParsedQuery& pq = cq->getParsed();

        // We'll now try to get the query runner that will execute this query for us. There
        // are a few cases in which we know upfront which runner we should get and, therefore,
        // we shortcut the selection process here.
        //
        // (a) If the query is over a collection that doesn't exist, we get a special runner
        // that's is so (a runner) which doesn't return results, the EOFRunner.
        //
        // (b) if the query is a replication's initial sync one, we get a SingleSolutinRunner
        // that uses a specifically designed stage that skips extents faster (see details in
        // exec/oplogstart.h)
        //
        // Otherwise we go through the selection of which runner is most suited to the
        // query + run-time context at hand.
        Status status = Status::OK();
        if (ctx.ctx().db()->getCollection(cq->ns()) == NULL) {
            rawRunner = new EOFRunner(cq, cq->ns());
        }
        else if (pq.hasOption(QueryOption_OplogReplay)) {
            status = getOplogStartHack(cq, &rawRunner);
        }
        else {
            // Takes ownership of cq.
            size_t options = QueryPlannerParams::DEFAULT;
            if (shardingState.needCollectionMetadata(pq.ns())) {
                options |= QueryPlannerParams::INCLUDE_SHARD_FILTER;
            }
            status = getRunner(cq, &rawRunner, options);
        }

        if (!status.isOK()) {
            // NOTE: Do not access cq as getRunner has deleted it.
            uasserted(17007, "Unable to execute query: " + status.reason());
        }

        verify(NULL != rawRunner);
        auto_ptr<Runner> runner(rawRunner);

        // We freak out later if this changes before we're done with the query.
        const ChunkVersion shardingVersionAtStart = shardingState.getVersion(cq->ns());

        // Handle query option $maxTimeMS (not used with commands).
        curop.setMaxTimeMicros(static_cast<unsigned long long>(pq.getMaxTimeMS()) * 1000);
        killCurrentOp.checkForInterrupt(); // May trigger maxTimeAlwaysTimeOut fail point.

        // uassert if we are not on a primary, and not a secondary with SlaveOk query parameter set.
        replVerifyReadsOk(&pq);

        // If this exists, the collection is sharded.
        // If it doesn't exist, we can assume we're not sharded.
        // If we're sharded, we might encounter data that is not consistent with our sharding state.
        // We must ignore this data.
        CollectionMetadataPtr collMetadata;
        if (!shardingState.needCollectionMetadata(pq.ns())) {
            collMetadata = CollectionMetadataPtr();
        }
        else {
            collMetadata = shardingState.getCollectionMetadata(pq.ns());
        }

        // Run the query.
        // bb is used to hold query results
        // this buffer should contain either requested documents per query or
        // explain information, but not both
        BufBuilder bb(32768);
        bb.skip(sizeof(QueryResult));

        // How many results have we obtained from the runner?
        int numResults = 0;

        // If we're replaying the oplog, we save the last time that we read.
        OpTime slaveReadTill;

        // Do we save the Runner in a ClientCursor for getMore calls later?
        bool saveClientCursor = false;

        // We turn on auto-yielding for the runner here.  The runner registers itself with the
        // active runners list in ClientCursor.
        auto_ptr<ScopedRunnerRegistration> safety(new ScopedRunnerRegistration(runner.get()));
        runner->setYieldPolicy(Runner::YIELD_AUTO);

        BSONObj obj;
        Runner::RunnerState state;
        // uint64_t numMisplacedDocs = 0;

        // set this outside loop. we will need to use this both within loop and when deciding
        // to fill in explain information
        const bool isExplain = pq.isExplain();

        while (Runner::RUNNER_ADVANCED == (state = runner->getNext(&obj, NULL))) {
            // Add result to output buffer. This is unnecessary if explain info is requested
            if (!isExplain) {
                bb.appendBuf((void*)obj.objdata(), obj.objsize());
            }

            // Count the result.
            ++numResults;

            // Possibly note slave's position in the oplog.
            if (pq.hasOption(QueryOption_OplogReplay)) {
                BSONElement e = obj["ts"];
                if (Date == e.type() || Timestamp == e.type()) {
                    slaveReadTill = e._opTime();
                }
            }

            // TODO: only one type of 2d search doesn't support this.  We need a way to pull it out
            // of CanonicalQuery. :(
            const bool supportsGetMore = true;
            if (isExplain) {
                if (enoughForExplain(pq, numResults)) {
                    break;
                }
            }
            else if (!supportsGetMore && (enough(pq, numResults)
                                          || bb.len() >= MaxBytesToReturnToClientAtOnce)) {
                break;
            }
            else if (enoughForFirstBatch(pq, numResults, bb.len())) {
                QLOG() << "Enough for first batch, wantMore=" << pq.wantMore()
                       << " numToReturn=" << pq.getNumToReturn()
                       << " numResults=" << numResults
                       << endl;
                // If only one result requested assume it's a findOne() and don't save the cursor.
                if (pq.wantMore() && 1 != pq.getNumToReturn()) {
                    QLOG() << " runner EOF=" << runner->isEOF() << endl;
                    saveClientCursor = !runner->isEOF();
                }
                break;
            }
        }

        // If we cache the runner later, we want to deregister it as it receives notifications
        // anyway by virtue of being cached.
        //
        // If we don't cache the runner later, we are deleting it, so it must be deregistered.
        //
        // So, no matter what, deregister the runner.
        safety.reset();

        // Caller expects exceptions thrown in certain cases:
        // * in-memory sort using too much RAM.
        if (Runner::RUNNER_ERROR == state) {
            uasserted(17144, "Runner error, memory limit for sort probably exceeded");
        }

        // Why save a dead runner?
        if (Runner::RUNNER_DEAD == state) {
            saveClientCursor = false;
        }
        else if (pq.hasOption(QueryOption_CursorTailable)) {
            // If we're tailing a capped collection, we don't bother saving the cursor if the
            // collection is empty. Otherwise, the semantics of the tailable cursor is that the
            // client will keep trying to read from it. So we'll keep it around.
            Collection* collection = ctx.ctx().db()->getCollection(cq->ns());
            if (collection && collection->numRecords() != 0 && pq.getNumToReturn() != 1) {
                saveClientCursor = true;
            }
        }

        // TODO(greg): This will go away soon.
        if (!shardingState.getVersion(pq.ns()).isWriteCompatibleWith(shardingVersionAtStart)) {
            // if the version changed during the query we might be missing some data and its safe to
            // send this as mongos can resend at this point
            throw SendStaleConfigException(pq.ns(), "version changed during initial query",
                                           shardingVersionAtStart,
                                           shardingState.getVersion(pq.ns()));
        }

        // Append explain information to query results by asking the runner to produce them.
        if (isExplain) {
            TypeExplain* bareExplain;
            Status res = runner->getExplainPlan(&bareExplain);

            if (!res.isOK()) {
                error() << "could not produce explain of query '" << pq.getFilter()
                        << "', error: " << res.reason();
                // If numResults and the data in bb don't correspond, we'll crash later when rooting
                // through the reply msg.
                BSONObj emptyObj;
                bb.appendBuf((void*)emptyObj.objdata(), emptyObj.objsize());
                // The explain output is actually a result.
                numResults = 1;
                // TODO: we can fill out millis etc. here just fine even if the plan screwed up.
            }
            else {
                boost::scoped_ptr<TypeExplain> explain(bareExplain);

                // Fill in the missing run-time fields in explain, starting with propeties of
                // the process running the query.
                std::string server = mongoutils::str::stream()
                    << getHostNameCached() << ":" << serverGlobalParams.port;
                explain->setServer(server);

                // We might have skipped some results due to chunk migration etc. so our count is
                // correct.
                explain->setN(numResults);

                // Clock the whole operation.
                explain->setMillis(curop.elapsedMillis());

                BSONObj explainObj = explain->toBSON();
                bb.appendBuf((void*)explainObj.objdata(), explainObj.objsize());

                // The explain output is actually a result.
                numResults = 1;
            }
        }

        long long ccId = 0;
        if (saveClientCursor) {
            // We won't use the runner until it's getMore'd.
            runner->saveState();

            // Allocate a new ClientCursor.  We don't have to worry about leaking it as it's
            // inserted into a global map by its ctor.
            ClientCursor* cc = new ClientCursor(runner.get(), cq->getParsed().getOptions(),
                                                cq->getParsed().getFilter());
            ccId = cc->cursorid();

            QLOG() << "caching runner with cursorid " << ccId
                   << " after returning " << numResults << " results" << endl;

            // ClientCursor takes ownership of runner.  Release to make sure it's not deleted.
            runner.release();

            // TODO document
            if (pq.hasOption(QueryOption_OplogReplay) && !slaveReadTill.isNull()) {
                cc->slaveReadTill(slaveReadTill);
            }

            // TODO document
            if (pq.hasOption(QueryOption_Exhaust)) {
                curop.debug().exhaust = true;
            }

            // Set attributes for getMore.
            cc->setCollMetadata(collMetadata);
            cc->setPos(numResults);

            // If the query had a time limit, remaining time is "rolled over" to the cursor (for
            // use by future getmore ops).
            cc->setLeftoverMaxTimeMicros(curop.getRemainingMaxTimeMicros());
        }
        else {
            QLOG() << "not caching runner but returning " << numResults << " results\n";
        }

        // Add the results from the query into the output buffer.
        result.appendData(bb.buf(), bb.len());
        bb.decouple();

        // Fill out the output buffer's header.
        QueryResult* qr = static_cast<QueryResult*>(result.header());
        qr->cursorId = ccId;
        curop.debug().cursorid = (0 == ccId ? -1 : ccId);
        qr->setResultFlagsToOk();
        qr->setOperation(opReply);
        qr->startingFrom = 0;
        qr->nReturned = numResults;

        curop.debug().ntoskip = pq.getSkip();
        curop.debug().nreturned = numResults;

        // curop.debug().exhaust is set above.
        return curop.debug().exhaust ? pq.ns() : "";
    }
void Objectness::generateTrianData()
{
	const int NUM_TRAIN = _voc.trainNum;
	const int FILTER_SZ = _W*_W;
	vector<vector<Mat>> xTrainP(NUM_TRAIN), xTrainN(NUM_TRAIN);
	vector<vecI> szTrainP(NUM_TRAIN); // Corresponding size index. 
	const int NUM_NEG_BOX = 100; // Number of negative windows sampled from each image

#pragma omp parallel for
	for (int i = 0; i < NUM_TRAIN; i++)	{
		const int NUM_GT_BOX = (int)_voc.gtTrainBoxes[i].size();
		vector<Mat> &xP = xTrainP[i], &xN = xTrainN[i];
		vecI &szP = szTrainP[i];
		xP.reserve(NUM_GT_BOX*4), szP.reserve(NUM_GT_BOX*4), xN.reserve(NUM_NEG_BOX);
		Mat im3u = imread(format(_S(_voc.imgPathW), _S(_voc.trainSet[i])));

		// Get positive training data
		for (int k = 0; k < NUM_GT_BOX; k++){
			const Vec4i& bbgt =  _voc.gtTrainBoxes[i][k];
			vector<Vec4i> bbs; // bounding boxes;
			vecI bbR; // Bounding box ratios
			int nS = gtBndBoxSampling(bbgt, bbs, bbR);
			for (int j = 0; j < nS; j++){
				bbs[j][2] = min(bbs[j][2], im3u.cols);
				bbs[j][3] = min(bbs[j][3], im3u.rows);
				Mat mag1f = getFeature(im3u, bbs[j]), magF1f;
				flip(mag1f, magF1f, CV_FLIP_HORIZONTAL);
				xP.push_back(mag1f);
				xP.push_back(magF1f);
				szP.push_back(bbR[j]);
				szP.push_back(bbR[j]);
			}			
		}
		// Get negative training data
		for (int k = 0; k < NUM_NEG_BOX; k++){
			int x1 = rand() % im3u.cols + 1, x2 = rand() % im3u.cols + 1;
			int y1 = rand() % im3u.rows + 1, y2 = rand() % im3u.rows + 1;
			Vec4i bb(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));
			if (maxIntUnion(bb, _voc.gtTrainBoxes[i]) < 0.5)
				xN.push_back(getFeature(im3u, bb));
		}
	}
	
	const int NUM_R = _numT * _numT + 1;
	vecI szCount(NUM_R); // Object counts of each size (combination of scale and aspect ratio) 
	int numP = 0, numN = 0, iP = 0, iN = 0;
	for (int i = 0; i < NUM_TRAIN; i++){
		numP += xTrainP[i].size();
		numN += xTrainN[i].size();
		const vecI &rP = szTrainP[i];
		for (size_t j = 0; j < rP.size(); j++)
			szCount[rP[j]]++;
	}
	vecI szActive; // Indexes of active size
	for (int r = 1; r < NUM_R; r++){
		if (szCount[r] > 50) // If only 50- positive samples at this size, ignore it.
			szActive.push_back(r-1);			
	}
	matWrite(_modelName + ".idx", Mat(szActive));

	Mat xP1f(numP, FILTER_SZ, CV_32F), xN1f(numN, FILTER_SZ, CV_32F);
	for (int i = 0; i < NUM_TRAIN; i++)	{
		vector<Mat> &xP = xTrainP[i], &xN = xTrainN[i];
		for (size_t j = 0; j < xP.size(); j++)
			memcpy(xP1f.ptr(iP++), xP[j].data, FILTER_SZ*sizeof(float));
		for (size_t j = 0; j < xN.size(); j++)
			memcpy(xN1f.ptr(iN++), xN[j].data, FILTER_SZ*sizeof(float));
	}
	CV_Assert(numP == iP && numN == iN);
	matWrite(_modelName + ".xP", xP1f);
	matWrite(_modelName + ".xN", xN1f);
}
Exemple #4
0
/** \brief Initialize a ZipFile object from an input file.
 *
 * This constructor opens the named zip file. If the zip "file" is
 * embedded in a file that contains other data, e.g. a binary
 * program, the offset of the zip file start and end must be
 * specified.
 *
 * If the file cannot be opened or the Zip directory cannot
 * be read, then the constructor throws an exception.
 *
 * \param[in] filename  The filename of the zip file to open.
 * \param[in] s_off  Offset relative to the start of the file, that
 *                   indicates the beginning of the zip data in the file.
 * \param[in] e_off  Offset relative to the end of the file, that
 *                   indicates the end of the zip data in the file.
 *                   The offset is a positive number, even though the
 *                   offset is towards the beginning of the file.
 */
ZipFile::ZipFile(std::string const& filename, offset_t s_off, offset_t e_off)
    : FileCollection(filename)
    , m_vs(s_off, e_off)
{
    std::ifstream zipfile(m_filename, std::ios::in | std::ios::binary);
    if(!zipfile)
    {
        throw IOException("Error opening Zip archive file for reading in binary mode.");
    }

    // Find and read the End of Central Directory.
    ZipEndOfCentralDirectory eocd;
    {
        BackBuffer bb(zipfile, m_vs);
        ssize_t read_p(-1);
        for(;;)
        {
            if(read_p < 0)
            {
                if(!bb.readChunk(read_p))
                {
                    throw FileCollectionException("Unable to find zip structure: End-of-central-directory");
                }
            }
            // Note: this is pretty fast since it reads from 'bb' which
            //       caches the buffer the readChunk() function just read.
            //
            if(eocd.read(bb, read_p))
            {
                // found it!
                break;
            }
            --read_p;
        }
    }

    // Position read pointer to start of first entry in central dir.
    m_vs.vseekg(zipfile, eocd.getOffset(), std::ios::beg);

    // TBD -- is that ", 0" still necessary? (With VC2012 and better)
    // Give the second argument in the next line to keep Visual C++ quiet
    //m_entries.resize(eocd.totalCount(), 0);
    m_entries.resize(eocd.getCount());

    size_t const max_entry(eocd.getCount());
    for(size_t entry_num(0); entry_num < max_entry; ++entry_num)
    {
        m_entries[entry_num] = FileEntry::pointer_t(new ZipCentralDirectoryEntry);
        m_entries[entry_num].get()->read(zipfile);
    }

    // Consistency check #1:
    // The virtual seeker position is exactly the start offset of the
    // Central Directory plus the Central Directory size
    //
    offset_t const pos(m_vs.vtellg(zipfile));
    if(static_cast<offset_t>(eocd.getOffset() + eocd.getCentralDirectorySize()) != pos)
    {
        throw FileCollectionException("Zip file consistency problem. Zip file data fields are inconsistent with zip file layout.");
    }

    // Consistency check #2:
    // Are local headers consistent with CD headers?
    //
    for(auto it = m_entries.begin(); it != m_entries.end(); ++it)
    {
        /** \TODO
         * Make sure the entry offset is properly defined by ZipCentralDirectoryEntry.
         * Also the isEqual() is a quite advance test here!
         */
        m_vs.vseekg(zipfile, (*it)->getEntryOffset(), std::ios::beg);
        ZipLocalEntry zlh;
        zlh.read(zipfile);
        if(!zipfile || !zlh.isEqual(**it))
        {
            throw FileCollectionException("Zip file consistency problem. Zip file data fields are inconsistent with zip file layout.");
        }
    }

    // we are all good!
    m_valid = true;
}
Exemple #5
0
void GBillboardWorld::draw(GImage* pImage, double* pDepthMap, GCamera& camera)
{
	G3DVector coords[VERTEX_COUNT + 1];
	int coordMap[VERTEX_COUNT + 1];
	GVec::setAll(pDepthMap, 1e200, pImage->width() * pImage->height());
	for(vector<GBillboard*>::iterator it = m_billboards.begin(); it != m_billboards.end(); it++)
	{
		// Project each of the corners onto the view
		GBBAugmented bb(**it);
		int gap = -1;
		int coordCount = 0;
		for(int i = 0; i < VERTEX_COUNT; i++)
		{
			camera.project(bb.m_pCorners[i], &coords[coordCount]);
			if(coords[coordCount].m_vals[2] > 0.0)
				coordMap[coordCount++] = i;
			else if(gap < 0)
			{
				gap = coordCount;
				coordCount = gap + 2;
			}
		}

		// Fudge the gap due to vertices that are behind the camera
		if(gap >= 0)
		{
			if(coordCount == 0)
				continue; // Nothing to draw

			// Fudge the vertex that follows the chain of valid vertices
			G3DVector tmp;
			G3DVector tmp2;
			int indexValid = coordMap[(gap + coordCount - 1) % coordCount]; // The corner just before the gap
			int indexFudge = (indexValid + 1) % VERTEX_COUNT; // The first corner that was behind the camera
			tmp.copy(bb.m_pCorners[indexValid]);
			tmp.subtract(bb.m_pCorners[indexFudge]);
			tmp2.copy(camera.lookFromPoint());
			tmp2.subtract(bb.m_pCorners[indexFudge]);
			double d = (1e-6 + tmp2.dotProduct(camera.lookDirection())) / tmp.dotProduct(camera.lookDirection());
			tmp.multiply(d);
			tmp.add(bb.m_pCorners[indexFudge]);
			camera.project(&tmp, &coords[gap]);

			// Fudge the vertex that precedes the chain of valid vertices
			indexValid = coordMap[(gap + 2) % coordCount]; // The corner just after the gap
			indexFudge = (indexValid + VERTEX_COUNT - 1) % VERTEX_COUNT; // The last corner that was behind the camera
			tmp.copy(bb.m_pCorners[indexValid]);
			tmp.subtract(bb.m_pCorners[indexFudge]);
			tmp2.copy(camera.lookFromPoint());
			tmp2.subtract(bb.m_pCorners[indexFudge]);
			d = (1e-6 + tmp2.dotProduct(camera.lookDirection())) / tmp.dotProduct(camera.lookDirection());
			tmp.multiply(d);
			tmp.add(bb.m_pCorners[indexFudge]);
			camera.project(&tmp, &coords[gap + 1]);
		}

		// Find the starting point (which is the lowest coordinate in the view)
		int a = 0;
		for(int i = 1; i < coordCount; i++)
		{
			if(coords[i].m_vals[1] < coords[a].m_vals[1])
				a = i;
		}
		int b = a;

		// Find the left and right order in which the corners will be visted (bottom to top)
		while(true)
		{
			int c = (b + 1) % coordCount;
			if(a == c)
				break;
			int d = (a + coordCount - 1) % coordCount;
			drawSection(pImage, pDepthMap, camera, bb, &coords[a], &coords[b], &coords[c], &coords[d]);
			if(coords[d].m_vals[1] < coords[c].m_vals[1])
				a = d;
			else
				b = c;
		}
	}
}
Exemple #6
0
    /**
     * Run a query -- includes checking for and running a Command.
     * @return points to ns if exhaust mode. 0=normal mode
     * @locks the db mutex for reading (and potentially for writing temporarily to create a new db).
     * @yields the db mutex periodically after acquiring it.
     * @asserts on scan and order memory exhaustion and other cases.
     */
    const char *runQuery(Message& m, QueryMessage& q, CurOp& curop, Message &result) {
        shared_ptr<ParsedQuery> pq_shared( new ParsedQuery(q) );
        ParsedQuery& pq( *pq_shared );
        BSONObj jsobj = q.query;
        int queryOptions = q.queryOptions;
        const char *ns = q.ns;

        if( logLevel >= 2 )
            log() << "runQuery called " << ns << " " << jsobj << endl;

        curop.debug().ns = ns;
        curop.debug().ntoreturn = pq.getNumToReturn();
        curop.debug().query = jsobj;
        curop.setQuery(jsobj);

        // Run a command.
        
        if ( pq.couldBeCommand() ) {
            BufBuilder bb;
            bb.skip(sizeof(QueryResult));
            BSONObjBuilder cmdResBuf;
            if ( runCommands(ns, jsobj, curop, bb, cmdResBuf, false, queryOptions) ) {
                curop.debug().iscommand = true;
                curop.debug().query = jsobj;
                curop.markCommand();

                auto_ptr< QueryResult > qr;
                qr.reset( (QueryResult *) bb.buf() );
                bb.decouple();
                qr->setResultFlagsToOk();
                qr->len = bb.len();
                curop.debug().responseLength = bb.len();
                qr->setOperation(opReply);
                qr->cursorId = 0;
                qr->startingFrom = 0;
                qr->nReturned = 1;
                result.setData( qr.release(), true );
            }
            else {
                uasserted(13530, "bad or malformed command request?");
            }
            return 0;
        }

        bool explain = pq.isExplain();
        BSONObj order = pq.getOrder();
        BSONObj query = pq.getFilter();

        /* The ElemIter will not be happy if this isn't really an object. So throw exception
           here when that is true.
           (Which may indicate bad data from client.)
        */
        if ( query.objsize() == 0 ) {
            out() << "Bad query object?\n  jsobj:";
            out() << jsobj.toString() << "\n  query:";
            out() << query.toString() << endl;
            uassert( 10110 , "bad query object", false);
        }

        Client::ReadContext ctx( ns , dbpath ); // read locks
        const ConfigVersion shardingVersionAtStart = shardingState.getVersion( ns );

        replVerifyReadsOk(&pq);

        if ( pq.hasOption( QueryOption_CursorTailable ) ) {
            NamespaceDetails *d = nsdetails( ns );
            uassert( 13051, "tailable cursor requested on non capped collection", d && d->isCapped() );
            const BSONObj nat1 = BSON( "$natural" << 1 );
            if ( order.isEmpty() ) {
                order = nat1;
            }
            else {
                uassert( 13052, "only {$natural:1} order allowed for tailable cursor", order == nat1 );
            }
        }

        // Run a simple id query.
        
        if ( ! (explain || pq.showDiskLoc()) && isSimpleIdQuery( query ) && !pq.hasOption( QueryOption_CursorTailable ) ) {

            int n = 0;
            bool nsFound = false;
            bool indexFound = false;

            BSONObj resObject;
            Client& c = cc();
            bool found = Helpers::findById( c, ns , query , resObject , &nsFound , &indexFound );
            if ( nsFound == false || indexFound == true ) {
                
                if ( shardingState.needShardChunkManager( ns ) ) {
                    ShardChunkManagerPtr m = shardingState.getShardChunkManager( ns );
                    if ( m && ! m->belongsToMe( resObject ) ) {
                        // I have something this _id
                        // but it doesn't belong to me
                        // so return nothing
                        resObject = BSONObj();
                        found = false;
                    }
                }

                BufBuilder bb(sizeof(QueryResult)+resObject.objsize()+32);
                bb.skip(sizeof(QueryResult));
                
                curop.debug().idhack = true;
                if ( found ) {
                    n = 1;
                    fillQueryResultFromObj( bb , pq.getFields() , resObject );
                }
                auto_ptr< QueryResult > qr;
                qr.reset( (QueryResult *) bb.buf() );
                bb.decouple();
                qr->setResultFlagsToOk();
                qr->len = bb.len();
                
                curop.debug().responseLength = bb.len();
                qr->setOperation(opReply);
                qr->cursorId = 0;
                qr->startingFrom = 0;
                qr->nReturned = n;
                result.setData( qr.release(), true );
                return NULL;
            }
        }
        
        // Run a regular query.
        
        BSONObj oldPlan;
        if ( explain && ! pq.hasIndexSpecifier() ) {
            MultiPlanScanner mps( ns, query, order );
            if ( mps.usingCachedPlan() ) {
                oldPlan =
                mps.oldExplain().firstElement().embeddedObject()
                .firstElement().embeddedObject().getOwned();
            }
        }

        // In some cases the query may be retried if there is an in memory sort size assertion.
        for( int retry = 0; retry < 2; ++retry ) {
            try {
                return queryWithQueryOptimizer( m, queryOptions, ns, jsobj, curop, query, order,
                                               pq_shared, oldPlan, shardingVersionAtStart, result );
            } catch ( const QueryRetryException & ) {
                verify( retry == 0 );
            }
        }
        verify( false );
        return 0;
    }
Exemple #7
0
    /**
     * Also called by db/ops/query.cpp.  This is the new getMore entry point.
     */
    QueryResult* newGetMore(const char* ns, int ntoreturn, long long cursorid, CurOp& curop,
                            int pass, bool& exhaust, bool* isCursorAuthorized) {
        exhaust = false;
        int bufSize = 512 + sizeof(QueryResult) + MaxBytesToReturnToClientAtOnce;

        BufBuilder bb(bufSize);
        bb.skip(sizeof(QueryResult));

        // This is a read lock.  TODO: There is a cursor flag for not needing this.  Do we care?
        Client::ReadContext ctx(ns);

        // TODO: Document.
        replVerifyReadsOk();

        ClientCursorPin ccPin(cursorid);
        ClientCursor* cc = ccPin.c();

        // These are set in the QueryResult msg we return.
        int resultFlags = ResultFlag_AwaitCapable;

        int numResults = 0;
        int startingResult = 0;

        if (NULL == cc) {
            cursorid = 0;
            resultFlags = ResultFlag_CursorNotFound;
        }
        else {
            // Quote: check for spoofing of the ns such that it does not match the one originally
            // there for the cursor
            uassert(17011, "auth error", str::equals(ns, cc->ns().c_str()));
            *isCursorAuthorized = true;

            // TODO: fail point?

            // If the operation that spawned this cursor had a time limit set, apply leftover
            // time to this getmore.
            curop.setMaxTimeMicros(cc->getLeftoverMaxTimeMicros());
            // TODO:
            // curop.debug().query = BSONForQuery
            // curop.setQuery(curop.debug().query);

            // TODO: What is pass?
            if (0 == pass) { cc->updateSlaveLocation(curop); }

            CollectionMetadataPtr collMetadata = cc->getCollMetadata();

            // If we're replaying the oplog, we save the last time that we read.
            OpTime slaveReadTill;

            startingResult = cc->pos();

            Runner* runner = cc->getRunner();
            const ParsedQuery& pq = runner->getQuery().getParsed();

            // Get results out of the runner.
            // TODO: There may be special handling required for tailable cursors?
            runner->restoreState();
            BSONObj obj;
            // TODO: Differentiate EOF from error.
            while (runner->getNext(&obj)) {
                // If we're sharded make sure that we don't return any data that hasn't been
                // migrated off of our shard yet.
                if (collMetadata) {
                    KeyPattern kp(collMetadata->getKeyPattern());
                    if (!collMetadata->keyBelongsToMe(kp.extractSingleKey(obj))) { continue; }
                }

                // Add result to output buffer.
                bb.appendBuf((void*)obj.objdata(), obj.objsize());

                // Count the result.
                ++numResults;

                // Possibly note slave's position in the oplog.
                if (pq.hasOption(QueryOption_OplogReplay)) {
                    BSONElement e = obj["ts"];
                    if (Date == e.type() || Timestamp == e.type()) {
                        slaveReadTill = e._opTime();
                    }
                }

                if ((numResults && numResults >= ntoreturn)
                    || bb.len() > MaxBytesToReturnToClientAtOnce) {
                    break;
                }
            }

            cc->incPos(numResults);
            runner->saveState();

            // Possibly note slave's position in the oplog.
            if (pq.hasOption(QueryOption_OplogReplay) && !slaveReadTill.isNull()) {
                cc->slaveReadTill(slaveReadTill);
            }

            exhaust = pq.hasOption(QueryOption_Exhaust);

            // If the getmore had a time limit, remaining time is "rolled over" back to the
            // cursor (for use by future getmore ops).
            cc->setLeftoverMaxTimeMicros( curop.getRemainingMaxTimeMicros() );
        }

        QueryResult* qr = reinterpret_cast<QueryResult*>(bb.buf());
        qr->len = bb.len();
        qr->setOperation(opReply);
        qr->_resultFlags() = resultFlags;
        qr->cursorId = cursorid;
        qr->startingFrom = startingResult;
        qr->nReturned = numResults;
        bb.decouple();
        return qr;
    }
Exemple #8
0
inline BoundingBox operator+(const BoundingBox& b1, const BoundingBox& b2)
{
	BoundingBox bb(b1);

	return bb += b2;
}
Exemple #9
0
 void Top::_appendStatsEntry( BSONObjBuilder& b , const char * statsName , const UsageData& map ) const {
     BSONObjBuilder bb( b.subobjStart( statsName ) );
     bb.appendNumber( "time" , map.time );
     bb.appendNumber( "count" , map.count );
     bb.done();
 }
Exemple #10
0
    bool DBHashCmd::run(OperationContext* txn, const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) {
        Timer timer;

        set<string> desiredCollections;
        if ( cmdObj["collections"].type() == Array ) {
            BSONObjIterator i( cmdObj["collections"].Obj() );
            while ( i.more() ) {
                BSONElement e = i.next();
                if ( e.type() != String ) {
                    errmsg = "collections entries have to be strings";
                    return false;
                }
                desiredCollections.insert( e.String() );
            }
        }

        list<string> colls;
        const string ns = parseNs(dbname, cmdObj);

        // We lock the entire database in S-mode in order to ensure that the contents will not
        // change for the snapshot.
        AutoGetDb autoDb(txn, ns, MODE_S);
        Database* db = autoDb.getDb();
        if (db) {
            db->getDatabaseCatalogEntry()->getCollectionNamespaces(&colls);
            colls.sort();
        }

        result.appendNumber( "numCollections" , (long long)colls.size() );
        result.append( "host" , prettyHostName() );

        md5_state_t globalState;
        md5_init(&globalState);

        vector<string> cached;

        BSONObjBuilder bb( result.subobjStart( "collections" ) );
        for ( list<string>::iterator i=colls.begin(); i != colls.end(); i++ ) {
            string fullCollectionName = *i;
            if ( fullCollectionName.size() -1 <= dbname.size() ) {
                errmsg  = str::stream() << "weird fullCollectionName [" << fullCollectionName << "]";
                return false;
            }
            string shortCollectionName = fullCollectionName.substr( dbname.size() + 1 );

            if ( shortCollectionName.find( "system." ) == 0 )
                continue;

            if ( desiredCollections.size() > 0 &&
                 desiredCollections.count( shortCollectionName ) == 0 )
                continue;

            bool fromCache = false;
            string hash = hashCollection( txn, db, fullCollectionName, &fromCache );

            bb.append( shortCollectionName, hash );

            md5_append( &globalState , (const md5_byte_t*)hash.c_str() , hash.size() );
            if ( fromCache )
                cached.push_back( fullCollectionName );
        }
        bb.done();

        md5digest d;
        md5_finish(&globalState, d);
        string hash = digestToString( d );

        result.append( "md5" , hash );
        result.appendNumber( "timeMillis", timer.millis() );

        result.append( "fromCache", cached );

        return 1;
    }
Exemple #11
0
// Acceps a query, calls the SAT solver and generates Valid/InValid.
// if returned 0 then input is INVALID if returned 1 then input is
// VALID if returned 2 then UNDECIDED
SOLVER_RETURN_TYPE
STP::TopLevelSTPAux(SATSolver& NewSolver, const ASTNode& original_input)
{
  bm->ASTNodeStats("input asserts and query: ", original_input);

  DifficultyScore difficulty;
  if (bm->UserFlags.stats_flag)
    cerr << "Difficulty Initially:" << difficulty.score(original_input) << endl;

  // A heap object so I can easily control its lifetime.
  std::auto_ptr<BVSolver> bvSolver(new BVSolver(bm, simp));
  std::auto_ptr<PropagateEqualities> pe(
      new PropagateEqualities(simp, bm->defaultNodeFactory, bm));

  ASTNode inputToSat = original_input;

  // If the number of array reads is small. We rewrite them through.
  // The bit-vector simplifications are more thorough than the array
  // simplifications. For example,
  // we don't currently do unconstrained elimination on arrays--- but we do for
  // bit-vectors.
  // A better way to do this would be to estimate the number of axioms
  // introduced.
  // TODO: I chose the number of reads we perform this operation at randomly.
  bool removed = false;
  if (((bm->UserFlags.ackermannisation &&
        numberOfReadsLessThan(inputToSat, 50)) ||
        bm->UserFlags.isSet("upfront-ack", "0")) ||
      numberOfReadsLessThan(inputToSat, 10))
  {
    // If the number of axioms that would be added it small. Remove them.
    bm->UserFlags.ackermannisation = true;
    inputToSat = arrayTransformer->TransformFormula_TopLevel(inputToSat);
    if (bm->UserFlags.stats_flag)
    {
      cerr << "Have removed array operations" << endl;
    }
    removed = true;
  }

  const bool arrayops = containsArrayOps(inputToSat);
  if (removed) {
    assert(!arrayops);
  }

  // Run size reducing just once.
  inputToSat = sizeReducing(inputToSat, bvSolver.get(), pe.get());
  unsigned initial_difficulty_score = difficulty.score(inputToSat);
  int bitblasted_difficulty = -1;

  // Fixed point it if it's not too difficult.
  // Currently we discards all the state each time sizeReducing is called,
  // so it's expensive to call.
  if ((!arrayops && initial_difficulty_score < 1000000) ||
      bm->UserFlags.isSet("preserving-fixedpoint", "0"))
  {
    inputToSat = callSizeReducing(inputToSat, bvSolver.get(), pe.get(),
                         initial_difficulty_score, bitblasted_difficulty);
  }

  if ((!arrayops || bm->UserFlags.isSet("array-difficulty-reversion", "1")))
  {
    initial_difficulty_score = difficulty.score(inputToSat);
  }

  if (bitblasted_difficulty != -1 && bm->UserFlags.stats_flag)
    cout << "Initial Bitblasted size:" << bitblasted_difficulty << endl;

  if (bm->UserFlags.stats_flag)
    cout << "Difficulty After Size reducing:" << initial_difficulty_score
              << endl;

  // So we can delete the object and release all the hash-buckets storage.
  std::auto_ptr<Revert_to> revert(new Revert_to());

  if ((!arrayops || bm->UserFlags.isSet("array-difficulty-reversion", "1")))
  {
    revert->initialSolverMap.insert(simp->Return_SolverMap()->begin(),
                                    simp->Return_SolverMap()->end());
    revert->backup_arrayToIndexToRead.insert(
        arrayTransformer->arrayToIndexToRead.begin(),
        arrayTransformer->arrayToIndexToRead.end());
    revert->toRevertTo = inputToSat;
  }

  // round of substitution, solving, and simplification. ensures that
  // DAG is minimized as much as possibly, and ideally should
  // garuntee that all liketerms in BVPLUSes have been combined.
  bm->SimplifyWrites_InPlace_Flag = false;
  // bm->Begin_RemoveWrites = false;
  // bm->start_abstracting = false;
  bm->TermsAlreadySeenMap_Clear();

  ASTNode tmp_inputToSAT;
  do
  {
    tmp_inputToSAT = inputToSat;

    if (bm->soft_timeout_expired)
      return SOLVER_TIMEOUT;

    if (bm->UserFlags.optimize_flag)
    {
      inputToSat = pe->topLevel(inputToSat, arrayTransformer);

      // Imagine:
      // The simplifier simplifies (0 + T) to T
      // Then bvsolve introduces (0 + T)
      // Then CreateSubstitutionMap decides T maps to a constant, but leaving
      // another (0+T).
      // When we go to simplify (0 + T) will still be in the simplify cache, so
      // will be mapped to T.
      // But it shouldn't be T, it should be a constant.
      // Applying the substitution map fixes this case.
      //
      if (simp->hasUnappliedSubstitutions())
      {
        inputToSat = simp->applySubstitutionMap(inputToSat);
        simp->haveAppliedSubstitutionMap();
      }
      bm->ASTNodeStats(pe_message.c_str(), inputToSat);
      inputToSat = simp->SimplifyFormula_TopLevel(inputToSat, false);
      bm->ASTNodeStats(size_inc_message.c_str(), inputToSat);
    }

    if (bm->UserFlags.wordlevel_solve_flag && bm->UserFlags.optimize_flag)
    {
      inputToSat = bvSolver->TopLevelBVSolve(inputToSat);
      bm->ASTNodeStats(bitvec_message.c_str(), inputToSat);
    }
  } while (tmp_inputToSAT != inputToSat);

  if (bm->UserFlags.bitConstantProp_flag)
  {
    bm->GetRunTimes()->start(RunTimes::ConstantBitPropagation);
    simplifier::constantBitP::ConstantBitPropagation cb(
        simp, bm->defaultNodeFactory, inputToSat);
    inputToSat = cb.topLevelBothWays(inputToSat);
    bm->GetRunTimes()->stop(RunTimes::ConstantBitPropagation);

    if (cb.isUnsatisfiable()) {
      inputToSat = bm->ASTFalse;
    }

    bm->ASTNodeStats(cb_message.c_str(), inputToSat);
  }

  if (bm->UserFlags.isSet("use-intervals", "1"))
  {
    EstablishIntervals intervals(*bm);
    inputToSat = intervals.topLevel_unsignedIntervals(inputToSat);
    bm->ASTNodeStats(int_message.c_str(), inputToSat);
  }

  // Find pure literals.
  if (bm->UserFlags.isSet("pure-literals", "1"))
  {
    FindPureLiterals fpl;
    bool changed = fpl.topLevel(inputToSat, simp, bm);
    if (changed)
    {
      inputToSat = simp->applySubstitutionMap(inputToSat);
      simp->haveAppliedSubstitutionMap();
      bm->ASTNodeStats(pl_message.c_str(), inputToSat);
    }
  }

  if (bm->soft_timeout_expired)
    return SOLVER_TIMEOUT;

  // Simplify using Ite context
  if (bm->UserFlags.optimize_flag && bm->UserFlags.isSet("ite-context", "0"))
  {
    UseITEContext iteC(bm);
    inputToSat = iteC.topLevel(inputToSat);
    bm->ASTNodeStats("After ITE Context: ", inputToSat);
  }

  if (bm->UserFlags.isSet("aig-core-simplify", "0"))
  {
    AIGSimplifyPropositionalCore aigRR(bm);
    inputToSat = aigRR.topLevel(inputToSat);
    bm->ASTNodeStats("After AIG Core: ", inputToSat);
  }

  if (bm->UserFlags.isSet("enable-unconstrained", "1"))
  {
    // Remove unconstrained.
    RemoveUnconstrained r(*bm);
    inputToSat =
        r.topLevel(inputToSat, simp);
    bm->ASTNodeStats(uc_message.c_str(), inputToSat);
  }

  bm->TermsAlreadySeenMap_Clear();

  // bm->start_abstracting = false;
  bm->SimplifyWrites_InPlace_Flag = false;
  // bm->Begin_RemoveWrites = false;

  long final_difficulty_score = difficulty.score(inputToSat);

  bool worse = false;
  if (final_difficulty_score > 1.1 * initial_difficulty_score)
    worse = true;

  // It's of course very wasteful to do this! Later I'll make it reuse the
  // work..We bit-blast again, in order to throw it away, so that we can
  // measure whether the number of AIG nodes is smaller. The difficulty score
  // is sometimes completelywrong, the sage-app7 are the motivating examples.
  // The other way to improve it would be to fix the difficulty scorer!
  if (!worse && (bitblasted_difficulty != -1))
  {
    BBNodeManagerAIG bitblast_nodemgr;
    BitBlaster<BBNodeAIG, BBNodeManagerAIG> bb(
        &bitblast_nodemgr, simp, bm->defaultNodeFactory, &(bm->UserFlags));
    bb.BBForm(inputToSat);
    int newBB = bitblast_nodemgr.totalNumberOfNodes();
    if (bm->UserFlags.stats_flag)
      cerr << "Final BB Size:" << newBB << endl;

    if (bitblasted_difficulty < newBB)
      worse = true;
  }

  if (bm->UserFlags.stats_flag)
  {
    cerr << "Initial Difficulty Score:" << initial_difficulty_score << endl;
    cerr << "Final Difficulty Score:" << final_difficulty_score << endl;
  }

  bool optimize_enabled = bm->UserFlags.optimize_flag;
  if (worse &&
      (!arrayops || bm->UserFlags.isSet("array-difficulty-reversion", "1")) &&
      bm->UserFlags.isSet("difficulty-reversion", "1"))
  {
    // If the simplified problem is harder, than the
    // initial problem we revert back to the initial
    // problem.

    if (bm->UserFlags.stats_flag)
      cerr << "simplification made the problem harder, reverting." << endl;
    inputToSat = revert->toRevertTo;

    // I do this to clear the substitution/solver map.
    // Not sure what would happen if it contained simplifications
    // that haven't been applied.
    simp->ClearAllTables();

    simp->Return_SolverMap()->insert(revert->initialSolverMap.begin(),
                                     revert->initialSolverMap.end());
    revert->initialSolverMap.clear();

    // Copy back what we knew about arrays at the start..
    arrayTransformer->arrayToIndexToRead.clear();
    arrayTransformer->arrayToIndexToRead.insert(
        revert->backup_arrayToIndexToRead.begin(),
        revert->backup_arrayToIndexToRead.end());

    // The arrayTransformer calls simplify. We don't want
    // it to put back in all the bad simplifications.
    bm->UserFlags.optimize_flag = false;
  }
  revert.reset(NULL);

  inputToSat = arrayTransformer->TransformFormula_TopLevel(inputToSat);
  bm->ASTNodeStats("after transformation: ", inputToSat);
  bm->TermsAlreadySeenMap_Clear();

  bm->UserFlags.optimize_flag = optimize_enabled;

  SOLVER_RETURN_TYPE res;
  if (!bm->UserFlags.ackermannisation)
  {
    bm->counterexample_checking_during_refinement = true;
  }

  // We are about to solve. Clear out all the memory associated with caches
  // that we won't need again.
  simp->ClearCaches();
  simp->haveAppliedSubstitutionMap();
  bm->ClearAllTables();

  // Deleting it clears out all the buckets associated with hashmaps etc. too.
  bvSolver.reset(NULL);
  pe.reset(NULL);

  if (bm->UserFlags.stats_flag)
    simp->printCacheStatus();

  const bool maybeRefinement = arrayops && !bm->UserFlags.ackermannisation;

  simplifier::constantBitP::ConstantBitPropagation* cb = NULL;
  std::auto_ptr<simplifier::constantBitP::ConstantBitPropagation> cleaner;

  if (bm->UserFlags.bitConstantProp_flag)
  {
    bm->GetRunTimes()->start(RunTimes::ConstantBitPropagation);
    cb = new simplifier::constantBitP::ConstantBitPropagation(
        simp, bm->defaultNodeFactory, inputToSat);
    cleaner.reset(cb);
    bm->GetRunTimes()->stop(RunTimes::ConstantBitPropagation);

    bm->ASTNodeStats(cb_message.c_str(), inputToSat);

    if (cb->isUnsatisfiable())
      inputToSat = bm->ASTFalse;
  }

  ToSATAIG toSATAIG(bm, cb, arrayTransformer);
  ToSATBase* satBase =
      bm->UserFlags.isSet("traditional-cnf", "0") ? tosat : &toSATAIG;

  if (bm->soft_timeout_expired)
    return SOLVER_TIMEOUT;

  // If it doesn't contain array operations, use ABC's CNF generation.
  res = Ctr_Example->CallSAT_ResultCheck(
      NewSolver, inputToSat, original_input, satBase,
      maybeRefinement);

  if (bm->soft_timeout_expired)
  {
    if (toSATAIG.cbIsDestructed())
      cleaner.release();

    return SOLVER_TIMEOUT;
  }

  if (SOLVER_UNDECIDED != res)
  {
    // If the aig converter knows that it is never going to be called again,
    // it deletes the constant bit stuff before calling the SAT solver.
    if (toSATAIG.cbIsDestructed())
      cleaner.release();

    CountersAndStats("print_func_stats", bm);
    return res;
  }

  // should only go to abstraction refinement if there are array ops.
  assert(arrayops);
  assert(!bm->UserFlags.ackermannisation); // Refinement must be enabled too.

  res = Ctr_Example->SATBased_ArrayReadRefinement(
      NewSolver, inputToSat, original_input, satBase);
  if (SOLVER_UNDECIDED != res)
  {
    if (toSATAIG.cbIsDestructed())
      cleaner.release();

    CountersAndStats("print_func_stats", bm);
    return res;
  }

  FatalError("TopLevelSTPAux: reached the end without proper conclusion:"
             "either a divide by zero in the input or a bug in STP");
  // bogus return to make the compiler shut up
  return SOLVER_ERROR;

} 
Exemple #12
0
void TextLineSegment::draw(QPainter* painter) const
      {
      TextLine* tl   = textLine();
      qreal _spatium = spatium();

      qreal textlineLineWidth    = tl->lineWidth().val() * _spatium;
      qreal textlineTextDistance = _spatium * .5;

      QPointF pp2(pos2());

      QColor color;
      bool normalColor = false;
      if (selected() && !(score() && score()->printing()))
            color = MScore::selectColor[0];
      else if (!visible())
            color = Qt::gray;
      else {
            color = curColor();
            normalColor = true;
            }

      qreal l = 0.0;
      int sym = subtype() == SEGMENT_MIDDLE ? tl->continueSymbol() : tl->beginSymbol();
      if (_text) {
            SpannerSegmentType st = subtype();
            if (
               ((st == SEGMENT_SINGLE || st == SEGMENT_BEGIN) && (tl->beginTextPlace() == PLACE_LEFT))
               || ((st == SEGMENT_MIDDLE || st == SEGMENT_END) && (tl->continueTextPlace() == PLACE_LEFT))
               ) {
                  QRectF bb(_text->bbox());
                  l = _text->pos().x() + bb.width() + textlineTextDistance;
                  }
            painter->translate(_text->pos());
            painter->setPen(normalColor ? _text->curColor() : color);
            _text->draw(painter);
            painter->translate(-_text->pos());
            }
      else if (sym != -1) {
            const QRectF& bb = symbols[score()->symIdx()][sym].bbox(magS());
            qreal h = bb.height() * .5;
            QPointF o = tl->beginSymbolOffset() * _spatium;
            painter->setPen(color);
            symbols[score()->symIdx()][sym].draw(painter, 1.0, QPointF(o.x(), h + o.y()));
            l = bb.width() + textlineTextDistance;
            }

      QPen pen(normalColor ? tl->lineColor() : color, textlineLineWidth);
      pen.setStyle(tl->lineStyle());
      painter->setPen(pen);

      if (subtype() == SEGMENT_SINGLE || subtype() == SEGMENT_END) {
            if (tl->endSymbol() != -1) {
                  int sym = tl->endSymbol();
                  const QRectF& bb = symbols[score()->symIdx()][sym].bbox(magS());
                  qreal h = bb.height() * .5;
                  QPointF o = tl->endSymbolOffset() * _spatium;
                  pp2.setX(pp2.x() - bb.width() + textlineTextDistance);
                  symbols[score()->symIdx()][sym].draw(painter, 1.0, QPointF(pp2.x() + textlineTextDistance + o.x(), h + o.y()));
                  }
            }

      QPointF pp1(l, 0.0);

      if (tl->beginHook() && tl->beginHookType() == HOOK_45)
            pp1.rx() += fabs(tl->beginHookHeight().val() * _spatium * .4);
      if (tl->endHook() && tl->endHookType() == HOOK_45)
            pp2.rx() -= fabs(tl->endHookHeight().val() * _spatium * .4);

      painter->drawLine(QLineF(pp1.x(), pp1.y(), pp2.x(), pp2.y()));

      if (tl->beginHook()) {
            qreal hh = tl->beginHookHeight().val() * _spatium;
            if (subtype() == SEGMENT_SINGLE || subtype() == SEGMENT_BEGIN) {
                  if (tl->beginHookType() == HOOK_45)
                        painter->drawLine(QLineF(pp1.x(), pp1.y(), pp1.x() - fabs(hh * .4), pp1.y() + hh));
                  else
                        painter->drawLine(QLineF(pp1.x(), pp1.y(), pp1.x(), pp1.y() + hh));
                  }
            }
      if (tl->endHook()) {
            qreal hh = tl->endHookHeight().val() * _spatium;
            if (subtype() == SEGMENT_SINGLE || subtype() == SEGMENT_END) {
                  if (tl->endHookType() == HOOK_45)
                        painter->drawLine(QLineF(pp2.x(), pp2.y(), pp2.x() + fabs(hh * .4), pp2.y() + hh));
                  else
                        painter->drawLine(QLineF(pp2.x(), pp2.y(), pp2.x(), pp2.y() + hh));
                  }
            }
      }
Exemple #13
0
static int
esdhc_start_image(struct esdhc *esdhc, ptrdiff_t address, ptrdiff_t entry, u32 offset)
{

	void *buf = (void *)address;
	struct imx_flash_header_v2 *hdr;
	int ret, len;
	void __noreturn (*bb)(void);
	unsigned int ofs;
	int i, header_count = 1;

	len = imx_image_size();
	len = ALIGN(len, SECTOR_SIZE);

	for (i = 0; i < header_count; i++) {
		ret = esdhc_read_blocks(esdhc, buf,
					offset + SZ_1K + SECTOR_SIZE);
		if (ret)
			return ret;

		hdr = buf + offset + SZ_1K;

		if (!is_imx_flash_header_v2(hdr)) {
			pr_debug("IVT header not found on SD card. "
				 "Found tag: 0x%02x length: 0x%04x "
				 "version: %02x\n",
				 hdr->header.tag, hdr->header.length,
				 hdr->header.version);
			return -EINVAL;
		}

		if (IS_ENABLED(CONFIG_ARCH_IMX8MQ) &&
		    hdr->boot_data.plugin & PLUGIN_HDMI_IMAGE) {
			/*
			 * In images that include signed HDMI
			 * firmware, first v2 header would be
			 * dedicated to that and would not contain any
			 * useful for us information. In order for us
			 * to pull the rest of the bootloader image
			 * in, we need to re-read header from SD/MMC,
			 * this time skipping anything HDMI firmware
			 * related.
			 */
			offset += hdr->boot_data.size + hdr->header.length;
			header_count++;
		}
	}

	pr_debug("Check ok, loading image\n");

	ofs = offset + hdr->entry - hdr->boot_data.start;

	if (entry != address) {
		/*
		 * Passing entry different from address is interpreted
		 * as a request to place the image such that its entry
		 * point would be exactly at 'entry', that is:
		 *
		 *     buf + ofs = entry
		 *
		 * solving the above for 'buf' gvies us the
		 * adjustement that needs to be made:
		 *
		 *     buf = entry - ofs
		 *
		 */
		if (WARN_ON(entry - ofs < address)) {
			/*
			 * We want to make sure we won't try to place
			 * the start of the image before the beginning
			 * of the memory buffer we were given in
			 * address.
			 */
			return -EINVAL;
		}

		buf = (void *)(entry - ofs);
	}

	ret = esdhc_read_blocks(esdhc, buf, offset + len);
	if (ret) {
		pr_err("Loading image failed with %d\n", ret);
		return ret;
	}

	pr_debug("Image loaded successfully\n");

	bb = buf + ofs;

	bb();
}
  void solve(vector<vector<char>> &board) {
     int row = board.size();  //get row number
     if (row==0){return;}
     int col = board[0].size(); // get column number
      
     vector<vector<bool> > bb(row, vector<bool>(col)); //result vector
      
     queue<pair<int,int> > q; // queue for BFS
      
     //search "O" from 1st row
     for (int i=0;i<col;i++){
         if (board[0][i]=='O'){
             q.push(make_pair(0,i));
             bb[0][i]=true;
         }
     }
      
     //search "O" from 1st column
     for (int i=0;i<row;i++){
         if (board[i][0]=='O'){
             q.push(make_pair(i,0));
             bb[i][0]=true;
         }
     }
      
     //search "O" from last row
     for (int i=0;i<col;i++){
         if (board[row-1][i]=='O'){
             q.push(make_pair(row-1,i));
             bb[row-1][i]=true;
         }
     }
      
     //search "O" from last column
     for (int i=0;i<row;i++){
         if (board[i][col-1]=='O'){
             q.push(make_pair(i,col-1));
             bb[i][col-1]=true;
         }
     }
      
     //BFS
     int i,j; // current position
     while (!q.empty()){
         //get current live "O"
         i = q.front().first;
         j = q.front().second;
          
         //pop up queue
         q.pop(); 
          
         //search four directions
         if (i-1>0 && board[i-1][j]=='O' && bb[i-1][j]==false){bb[i-1][j]=true; q.push(make_pair(i-1,j));} //top
         if (i+1<row-1 && board[i+1][j]=='O'&& bb[i+1][j]==false){bb[i+1][j]=true; q.push(make_pair(i+1,j));} // bottom
         if (j-1>0 && board[i][j-1]=='O'&& bb[i][j-1]==false){bb[i][j-1]=true; q.push(make_pair(i,j-1));} // left
         if (j+1<col-1 && board[i][j+1]=='O'&& bb[i][j+1]==false){bb[i][j+1]=true; q.push(make_pair(i,j+1));} // right
     }
      
     //Get result
     for (int i=0;i<row;i++){
         for (int j=0;j<col;j++){
             if (board[i][j]=='O'&&bb[i][j]==false){
                 board[i][j]='X';
             }
         }
     }
      
     return;
         
 }
	void testPut() {
		quint8 data[100];
		quint32 size = sizeof(data);

		{
			BigEndianByteBuffer bb(data, size);
			{
				for(quint32 i = 0; i < size; i++) data[i] = (quint8)0;

				quint32 setPos = 16;
				quint8  setVal = 0x11;
				bb.setPos(setPos);
				bb.put8(setVal);
				CPPUNIT_ASSERT_EQUAL((quint32)(0x11), (quint32)(data[16]));
				CPPUNIT_ASSERT_EQUAL((quint32)(setPos + sizeof(setVal)), bb.getPos());
			}
			{
				for(quint32 i = 0; i < size; i++) data[i] = (quint8)0;

				quint32 setPos = 16;
				quint16 setVal = 0x1122;
				bb.setPos(setPos);
				bb.put16(setVal);
				// Big Endian => 11 22
				CPPUNIT_ASSERT_EQUAL((quint32)(0x11), (quint32)(data[16]));
				CPPUNIT_ASSERT_EQUAL((quint32)(0x22), (quint32)(data[17]));
				CPPUNIT_ASSERT_EQUAL((quint32)(setPos + sizeof(setVal)), bb.getPos());
			}
			{
				for(quint32 i = 0; i < size; i++) data[i] = (quint8)0;

				quint32 setPos = 16;
				quint32 setVal = 0x11223344;
				bb.setPos(setPos);
				bb.put32(setVal);
				// Big Endian => 33 44 11 22
				CPPUNIT_ASSERT_EQUAL((quint8)(0x33), data[16]);
				CPPUNIT_ASSERT_EQUAL((quint8)(0x44), data[17]);
				CPPUNIT_ASSERT_EQUAL((quint8)(0x11), data[18]);
				CPPUNIT_ASSERT_EQUAL((quint8)(0x22), data[19]);
				CPPUNIT_ASSERT_EQUAL((quint32)(setPos + sizeof(setVal)), bb.getPos());
			}
		}

		{
			LittleEndianByteBuffer bb(data, size);
			quint32 pos = 70;
			bb.setPos(pos);
			{
				for(quint32 i = 0; i < size; i++) data[i] = (quint8)0;

				quint32 setPos = 16;
				quint8  setVal = 0x11;
				bb.setPos(setPos);
				bb.put8(setVal);
				CPPUNIT_ASSERT_EQUAL((quint32)(0x11), (quint32)(data[17]));
				CPPUNIT_ASSERT_EQUAL((quint32)(setPos + sizeof(setVal)), bb.getPos());
			}
			{
				for(quint32 i = 0; i < size; i++) data[i] = (quint8)0;

				quint32 setPos = 16;
				quint16 setVal = 0x1122;
				bb.setPos(setPos);
				bb.put16(setVal);
				// Little Endian => 22 11
				CPPUNIT_ASSERT_EQUAL((quint32)(0x11), (quint32)(data[17]));
				CPPUNIT_ASSERT_EQUAL((quint32)(0x22), (quint32)(data[16]));
				CPPUNIT_ASSERT_EQUAL((quint32)(setPos + sizeof(setVal)), bb.getPos());
			}
			{
				for(quint32 i = 0; i < size; i++) data[i] = (quint8)0;

				quint32 setPos = 16;
				quint32 setVal = 0x11223344;
				bb.setPos(setPos);
				bb.put32(setVal);
				// Little Endian => 44 33 22 11
				CPPUNIT_ASSERT_EQUAL((quint8)(0x33), data[17]);
				CPPUNIT_ASSERT_EQUAL((quint8)(0x44), data[16]);
				CPPUNIT_ASSERT_EQUAL((quint8)(0x11), data[19]);
				CPPUNIT_ASSERT_EQUAL((quint8)(0x22), data[18]);
				CPPUNIT_ASSERT_EQUAL((quint32)(setPos + sizeof(setVal)), bb.getPos());
			}
		}
	}
Exemple #16
0
//Mean-Based Preconditioned GMRES  
int pregmres(const Teuchos::SerialDenseMatrix<int, double> &  A, const Teuchos::SerialDenseMatrix<int,double> &  X,const Teuchos::SerialDenseMatrix<int,double> &   B, int max_iter, double tolerance)
{
  int n; 
  int k;
  double resid;
  k=1;
  n=A.numRows();
  std::cout << A << std::endl;
  Teuchos::SerialDenseMatrix<int, double> D(n,1);

  //Get diagonal entries of A 
  for (int i=0; i<n; i++){
    D(i,0)=A(i,i);
  }
  

  Teuchos::SerialDenseMatrix<int, double> Ax(n,1);
  Ax.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,1.0, A, X, 0.0);

  Teuchos::SerialDenseMatrix<int, double> r0(B);
  r0-=Ax;
  
  resid=r0.normFrobenius();
  
  //define vector v=r/norm(r) where r=b-Ax
  Teuchos::SerialDenseMatrix<int, double> v(n,1);
  r0.scale(1/resid);
  
  Teuchos::SerialDenseMatrix<int, double> h(1,1);

  //Matrix of orthog basis vectors V
  Teuchos::SerialDenseMatrix<int, double> V(n,1);
  
   //Set v=r0/norm(r0) to be 1st col of V
   for (int i=0; i<n; i++){
        V(i,0)=r0(i,0);
       }
   //right hand side
   Teuchos::SerialDenseMatrix<int, double> bb(1,1);
   bb(0,0)=resid;
   Teuchos::SerialDenseMatrix<int, double> w(n,1);
   Teuchos::SerialDenseMatrix<int, double> c;
   Teuchos::SerialDenseMatrix<int, double> s;
       
   while (resid > tolerance && k < max_iter){
    
    std::cout << "k = " << k << std::endl;
    h.reshape(k+1,k);
    //Arnoldi iteration(Gram-Schmidt )
    V.reshape(n,k+1);    
    //set vk to be kth col of V
    Teuchos::SerialDenseMatrix<int, double> vk(Teuchos::Copy, V, n,1,0,k-1);
    //Preconditioning step w=AMj(-1)vj
    w.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1/D(k-1,0), A, vk, 0.0);  

   
    
    Teuchos::SerialDenseMatrix<int, double> vi(n,1);
    Teuchos::SerialDenseMatrix<int, double> ip(1,1);
    for (int i=0; i<k; i++){
       //set vi to be ith col of V
       Teuchos::SerialDenseMatrix<int, double> vi(Teuchos::Copy, V, n,1,0,i);    
       //Calculate inner product
       ip.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, vi, w, 0.0);
       h(i,k-1)= ip(0,0);
       //scale vi by h(i,k-1)
       vi.scale(ip(0,0));     
       w-=vi;
       }         
    h(k,k-1)=w.normFrobenius();     
    
    w.scale(1.0/w.normFrobenius());   
    //add column vk+1=w to V
    for (int i=0; i<n; i++){
          V(i,k)=w(i,0);
         } 
   //Solve upper hessenberg least squares problem via Givens rotations
   //Compute previous Givens rotations
    for (int i=0; i<k-1; i++){
       h(i,k-1)=c(i,0)*h(i,k-1)+s(i,0)*h(i+1,k-1);
       h(i+1,k-1)=-s(i,0)*h(i,k-1)+c(i,0)*h(i+1,k-1);
     }  
     //Compute next Givens rotations
     c.reshape(k,1);
     s.reshape(k,1); 
     bb.reshape(k+1,1);
     double l = sqrt(h(k-1,k-1)*h(k-1,k-1)+h(k,k-1)*h(k,k-1));
     c(k-1,0)=h(k-1,k-1)/l;
     s(k-1,0)=h(k,k-1)/l;
     std::cout <<" h(k,k-1)= " << h(k,k-1) << std::endl;
     // Givens rotation on h and bb
     h(k-1,k-1)=l;
     h(k,k-1)=0;
     bb(k-1,0)=c(k-1,0)*bb(k-1,0);
     bb(k,0)=-s(k-1,0)*bb(k-1,0);

    //Determine residual    
    resid = fabs(bb(k,0));

    std::cout << "resid = " << resid << std::endl;
    k=k+1;
  } 
   //Extract upper triangular square matrix
   bb.reshape(h.numRows()-1 ,1);

   //Solve linear system
   int info;

   Teuchos::LAPACK<int, double> lapack;
   lapack.TRTRS('U', 'N', 'N', h.numRows()-1, 1, h.values(), h.stride(), bb.values(), bb.stride(),&info); 
   //Found y=Mx
   for (int i=0; i<k-1; i++){
      bb(i,0)=bb(i,0)/D(i,0);
   }

   V.reshape(n,k-1);
   Teuchos::SerialDenseMatrix<int, double> ans(X);
   ans.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, V, bb, 1.0);
   std::cout << "ans= " << ans << std::endl;

   std::cout << "h= " << h << std::endl;



return 0;
}
	void testGet() {
		quint8 data[100];
		quint32 size = sizeof(data);

		{
			BigEndianByteBuffer bb(data, size);

			// get with position
			// get with no position
			{
				bb.setPos(0);
				for(quint32 i = 0; i < size; i++) data[i] = 0;

				quint32 pos = 16;
				quint8 val = 0xA5;
				data[pos] = val;

				CPPUNIT_ASSERT_EQUAL(val, bb.get8(pos));
				CPPUNIT_ASSERT_EQUAL((quint32)0, bb.getPos());

				bb.setPos(pos);
				CPPUNIT_ASSERT_EQUAL(val, bb.get8());
				CPPUNIT_ASSERT_EQUAL(quint32(pos + sizeof(val)), bb.getPos());
			}

			{
				bb.setPos(0);
				for(quint32 i = 0; i < size; i++) data[i] = 0;

				quint32 pos = 16;
				quint16 val = 0x1122;
				data[16] = 0x11;
				data[17] = 0x22;

				CPPUNIT_ASSERT_EQUAL(val, bb.get16(pos));
				CPPUNIT_ASSERT_EQUAL((quint32)0, bb.getPos());

				bb.setPos(pos);
				CPPUNIT_ASSERT_EQUAL(val, bb.get16());
				CPPUNIT_ASSERT_EQUAL(quint32(pos + sizeof(val)), bb.getPos());
			}

			{
				bb.setPos(0);
				for(quint32 i = 0; i < size; i++) data[i] = 0;

				quint32 pos = 16;
				quint32 val = 0x11223344;
				data[16] = 0x33;
				data[17] = 0x44;
				data[18] = 0x11;
				data[19] = 0x22;

				CPPUNIT_ASSERT_EQUAL(val, bb.get32(pos));
				CPPUNIT_ASSERT_EQUAL((quint32)0, bb.getPos());

				bb.setPos(pos);
				CPPUNIT_ASSERT_EQUAL(val, bb.get32());
				CPPUNIT_ASSERT_EQUAL(quint32(pos + sizeof(val)), bb.getPos());
			}
		}

		{
			LittleEndianByteBuffer bb(data, size);

			// get with position
			// get with no position
			{
				bb.setPos(0);
				for(quint32 i = 0; i < size; i++) data[i] = 0;

				quint32 pos = 16;
				quint8 val = 0x11;
				data[17] = 0x11;

				CPPUNIT_ASSERT_EQUAL(val, bb.get8(pos));
				CPPUNIT_ASSERT_EQUAL((quint32)0, bb.getPos());

				bb.setPos(pos);
				CPPUNIT_ASSERT_EQUAL(val, bb.get8());
				CPPUNIT_ASSERT_EQUAL(quint32(pos + sizeof(val)), bb.getPos());
			}

			{
				bb.setPos(0);
				for(quint32 i = 0; i < size; i++) data[i] = 0;

				quint32 pos = 16;
				quint16 val = 0x1122;
				data[17] = 0x11;
				data[16] = 0x22;

				CPPUNIT_ASSERT_EQUAL(val, bb.get16(pos));
				CPPUNIT_ASSERT_EQUAL((quint32)0, bb.getPos());

				bb.setPos(pos);
				CPPUNIT_ASSERT_EQUAL(val, bb.get16());
				CPPUNIT_ASSERT_EQUAL(quint32(pos + sizeof(val)), bb.getPos());
			}

			{
				bb.setPos(0);
				for(quint32 i = 0; i < size; i++) data[i] = 0;

				quint32 pos = 16;
				quint32 val = 0x11223344;
				data[17] = 0x33;
				data[16] = 0x44;
				data[19] = 0x11;
				data[18] = 0x22;

				CPPUNIT_ASSERT_EQUAL(val, bb.get32(pos));
				CPPUNIT_ASSERT_EQUAL((quint32)0, bb.getPos());

				bb.setPos(pos);
				CPPUNIT_ASSERT_EQUAL(val, bb.get32());
				CPPUNIT_ASSERT_EQUAL(quint32(pos + sizeof(val)), bb.getPos());
			}
		}
	}
int main(void)
{
   struct tm *newtime;
   time_t ltime; 
   time(&ltime);                 /* Get the time in seconds */
   newtime = localtime(&ltime);  /* Convert it to the structure tm */
   char * st;            // gen purpose string for bcd's
   st = new char[35];   // 32 digits + sign + decimal pt + '\0'
 ofstream dout("bcdrun.log");
   bcd numa("1234567890987654.123");  // fraction will be dropped
   bcd numb(4321.6789);               // ditto - we are using integer rules
   bcd numc(-24681357L);
   bcd numd = numa + numb;
   bcd e(0.0);
   bcd f(0L);
   bcd g(-0.0);
   bcd h(-0L);
   bcd w(1L);
   bcd x(-1.0);
   bcd y("-2.0");
   bcd z("300.");
   bcd aa("99999999999999999999999999999999");
   bcd bb("1");
   bcd cc("10000000000000000");
   bcd dd(".00000000000000001");
   bcd m1(12L);
   bcd m2(2L);
   bcd m3(123456789L);
   bcd m4(4096L);
   bcd m5(748345987654321.0);
   bcd m6(288834570200345.0);
   bcd m7("8599238847786248452455563809");
   bcd d1("8765432109876");
   bcd d2(24687L);
   bcd d3(75237L);
   bcd d4(45263L);
   bcd d5 ("92732081006447");
   bcd s1("1234567890987654");

   dout << "                 Regression Log for " << asctime(newtime) << endl;

   dout << "significant digits test: 1 = " << w.sigD() << ", 3 = " << z.sigD()
        << ", 32 = " << aa.sigD() << ", 0 = " << dd.sigD() << "\n" << endl;

   int rc = numa.bcdToString(st); // convert numa to string no decimal point
   dout << "bcd to string test = " << st << "\n"
        << "          expected:  +1234567890987654" << endl;
   rc = numa.bcdToString(st,1);   // numa to str with 1 psn to right of dec pt
   dout << "bcd to string test = " << st << "\n"
        << "          expected:  +123456789098765.4" << endl;
   rc = numa.bcdToString(st,6);   // numa to str with 6 psns to rt of decimal pt
   dout << "bcd to string test = " << st << "\n"
        << "          expected:  +1234567890.987654" << "\n" << endl;

   rc = m3.bcdToString(st); // convert m3 to string no decimal point
   dout << "bcd to string test  = " << st << "\n"
        << "          expected:   +123456789" << endl;
   rc = m3.bcdToString(st,1);   // m3 to str with 1 psn to right of dec pt
   dout << "bcd to string test  = " << st << "\n"
        << "          expected:   +12345678.9" << endl;
   rc = m3.bcdToString(st,6);   // m3 to str with 6 psns to rt of decimal pt
   dout << "bcd to string test  = " << st << "\n"
        << "          expected:   +123.456789" << "\n" << endl;

   rc = h.bcdToString(st); // convert h to string no decimal point
   dout << "bcd to string test  = " << st << "\n"
        << "          expected:   +0" << endl;
   rc = h.bcdToString(st,1);   // convert h to str with 1 psn to right of dec pt
   dout << "bcd to string test  = " << st << "\n"
        << "          expected:   +0.0" << endl;
   rc = h.bcdToString(st,6);   // h to str with 6 psns to rt of decimal pt
   dout << "bcd to string test  = " << st << "\n"
        << "          expected:   +0.0" << "\n" << endl;

   rc = m2.bcdToString(st); // convert m2 to string no decimal point
   dout << "bcd to string test  = " << st << "\n"
        << "          expected:   +2" << endl;
   rc = m2.bcdToString(st,1);   // m2 to str with 1 psn to right of dec pt
   dout << "bcd to string test  = " << st << "\n"
        << "          expected:   +0.2" << endl;
   rc = m2.bcdToString(st,6);   // m2 to str with 6 psns to rt of decimal pt
   dout << "bcd to string test  = " << st << "\n"
        << "          expected:   +0.000002" << "\n" << endl;

   s1.shl(1);
   dout << "shift test 1234567890987654 shifted left 1 = " << s1 
        << "   expected                                = +00000000000000012345678909876540 cc: 0\n" << endl;
   s1.shl(2);
   dout << "shift test 1234567890987654 shifted left 2 = " << s1 
        << "   expected                                = +00000000000001234567890987654000 cc: 0\n" << endl;
   s1.shl(3);
   dout << "shift test 1234567890987654 shifted left 3 = " << s1 
        << "   expected                                = +00000000001234567890987654000000 cc: 0\n" << endl;
   s1.shl(13);
   dout << "shift test 1234567890987654 shfted left 13 = " << s1 
        << "   expected                                = +00000000001234567890987654000000 cc: 16\n" << endl;
   s1.shr(1);
   dout << "shift test 1234567890987654 shifted rt 1 = " << s1 
        << "   expected                              = +00000000000123456789098765400000 cc: 0\n" << endl;
   s1.shr(2);
   dout << "shift test 1234567890987654 shifted rt 2 = " << s1 
        << "   expected                              = +00000000000001234567890987654000 cc: 0\n" << endl;
   s1.shr(5);
   dout << "shift test 1234567890987654 shifted rt 5 = " << s1 
        << "   expected                              = +00000000000000000012345678909876 cc: 0\n" << endl;
   s1.shrRnd(4);
   dout << "shift test 12345678909876 sh rt 4 & rnd  = " << s1
        << "   expected                              = +00000000000000000000001234567891 cc: 0\n" << endl;
   s1.shrRnd(4);
   dout << "shift test 12345678909876 sh rt 4 & rnd  = " << s1
        << "   expected                              = +00000000000000000000000000123457 cc: 0\n" << endl;
   s1.shrRnd(5);
   dout << "shift test 12345678909876 sh rt 5 & rnd  = " << s1
        << "   expected                              = +00000000000000000000000000000001 cc: 0\n" << endl;
   s1.shl(31);
   dout << "shift test 12345678909876 sh lt 31       = " << s1
        << "   expected                              = +10000000000000000000000000000000 cc: 0\n" << endl;

   bcd s2("1234567890987654321");
   s2.shrCpld(s1,6);               // odd shift even
   dout << "coupled shift s2 > s1,   s1 = " << s1
        << "                expected s1 = +00000000000000000000000000654321 cc: 0\n"
        << "                         s2 = " << s2
        << "                expected s2 = +00000000000000000001234567890987 cc: 0\n" << endl;
   s2.shrCpld(s1,5);               // odd shift odd
   dout << "coupled shift s2 > s1,   s1 = " << s1
        << "                expected s1 = +00000000000000000000000000090987 cc: 0\n"
        << "                         s2 = " << s2
        << "                expected s2 = +00000000000000000000000012345678 cc: 0\n" << endl;
   s2.shrCpld(s1,4);               // even shift even
   dout << "coupled shift s2 > s1,   s1 = " << s1
        << "                expected s1 = +00000000000000000000000000005678 cc: 0\n"
        << "                         s2 = " << s2
        << "                expected s2 = +00000000000000000000000000001234 cc: 0\n" << endl;
   s2.shrCpld(s1,3);               // odd shift odd
   dout << "coupled shift s2 > s1,   s1 = " << s1
        << "                expected s1 = +00000000000000000000000000000234 cc: 0\n"
        << "                         s2 = " << s2
        << "                expected s2 = +00000000000000000000000000000001 cc: 0\n" << endl;

   dout << "logical test 1 < 2   = " << int(bb<m2) << "\n"
        << "expected             = 1 \n" << endl;
   dout << "logical test 1 > 2   = " << int(bb>m2) << "\n"
        << "expected             = 0 \n" << endl;
   dout << "logical test 1 = 2   = " << int(bb==m2) << "\n"
        << "expected             = 0 \n" << endl;
   dout << "logical test 2 < 1   = " << int(m2<bb) << "\n"
        << "expected             = 0 \n" << endl;
   dout << "logical test 2 > 1   = " << int(m2>bb) << "\n"
        << "expected             = 1 \n" << endl;
   dout << "logical test 2 = 1   = " << int(m2==bb) << "\n"
        << "expected             = 0 \n" << endl;
   dout << "logical test 1 < 12  = " << int(bb<m1) << "\n"
        << "expected             = 1 \n" << endl;
   dout << "logical test 1 > 12  = " << int(bb>m1) << "\n"
        << "expected             = 0 \n" << endl;
   dout << "logical test 1 = 12  = " << int(bb==m1) << "\n"
        << "expected             = 0 \n" << endl;
   dout << "logical test 12 < 1  = " << int(m1<bb) << "\n"
        << "expected             = 0 \n" << endl;
   dout << "logical test 12 > 1  = " << int(m1>bb) << "\n"
        << "expected             = 1 \n" << endl;
   dout << "logical test 12 = 1  = " << int(m1==bb) << "\n"
        << "expected             = 0 \n" << endl;
   dout << "logical test -1 < 2  = " << int(x<m2) << "\n"
        << "expected             = 1 \n" << endl;
   dout << "logical test -1 > 2  = " << int(x>m2) << "\n"
        << "expected             = 0 \n" << endl;
   dout << "logical test -1 = 2  = " << int(x==m2) << "\n"
        << "expected             = 0 \n" << endl;
   dout << "logical test 2 < -1  = " << int(m2<x) << "\n"
        << "expected             = 0 \n" << endl;
   dout << "logical test -1 != 2  = " << int(x!=m2) << "\n"
        << "expected              = 1 \n" << endl;
   dout << "logical test 2 != -1  = " << int(m2!=x) << "\n"
        << "expected              = 1 \n" << endl;
   dout << "logical test 2 != 2   = " << int(m2!=m2) << "\n"
        << "expected              = 0 \n" << endl;
   dout << "logical test 2 > -1  = " << int(m2>x) << "\n"
        << "expected             = 1 \n" << endl;
   dout << "logical test 2 = -1  = " << int(m2==x) << "\n"
        << "expected             = 0 \n" << endl;
   dout << "logical test d1 = d1 = " << int(d1==d1) << "\n"
        << "expected             = 1 \n" << endl;
   dout << "logical test 0 = -0  = " << int(f==h) << "\n"
        << "expected             = 1 \n" << endl;
   dout << "logical test -0 = 0  = " << int(h==f) << "\n"
        << "expected             = 1 \n" << endl;
   dout << "logical test 0 = 0   = " << int(f==f) << "\n"
        << "expected             = 1 \n" << endl;
   dout << "logical test -0 = -0 = " << int(h==h) << "\n"
        << "expected             = 1 \n" << endl;
   dout << "divide test 8765432109876/24687 = " << d1/d2
        << "expected                        = +00000000000000000000000355062669 cc: 0\n" << endl;
   dout << "divide tst 92732081006447/45263 = " << d5/d4
        << "expected                        = +00000000000000000000002048739169 cc: 0\n" << endl;
   dout << "divide test 8765432109876/75237 = " << d1/d3
        << "expected                        = +00000000000000000000000116504274 cc: 0\n" << endl;
   dout << "divide test 1/24687             = " << bb/d2
        << "expected                        = +00000000000000000000000000000000 cc: 0\n" << endl;
   dout << "   test 10000000000000000/24687 = " << cc/d2
        << "expected                        = +00000000000000000000405071495118 cc: 0\n" << endl;
   dout << "   test 10000000000000000/3     = " << cc/3L
        << "expected                        = +00000000000000003333333333333333 cc: 0\n" << endl;
   dout << "   test 10000000000000000/6     = " << cc/6L
        << "expected                        = +00000000000000001666666666666666 cc: 0\n" << endl;
   dout << "   test 10000000000000000/7     = " << cc/7L
        << "expected                        = +00000000000000001428571428571428 cc: 0\n" << endl;
   dout << " div test 22000000000000000/7   = " << (cc*22L)/7L
        << "expected                        = +00000000000000031428571428571428 cc: 0\n" << endl;
   dout << "modulus test 24687%1000         = " << d2%1000L
        << "expected                        = +00000000000000000000000000000687 cc: 0\n" << endl;
   dout << "divide by zero test 75237/0     = " << d3/0L
        << "expected                        = +00000000000000000000000000075237 cc: 16\n" << endl;
   dout << "divide d1/d1 test               = " << d1/d1
        << "expected                        = +00000000000000000000000000000001 cc: 0\n" << endl;
   dout << "re-subtract test: 12345 - 12346 = " << bcd(12345L) - 12346L
        << "expected                        = -00000000000000000000000000000001 cc: 0\n"
        << " reverse opnds:   12346 - 12345 = " << bcd(12346L) - 12345L
        << "expected                        = +00000000000000000000000000000001 cc: 0\n" << endl;
   dout << "8599238847786248452455563809*45263       = " << m7 * d4
        << "                               expected:   +00008599238847786248452455563809 cc: 15\n" << endl;
   dout << "748345987654321 x 288834570200345        = " << m5 * m6
        << "                               expected:   +00216148191705288491573574940745 cc: 0\n" << endl;
   dout << "748345987654321 x 288834570200345 x 10   = " << m5 * m6 * 10.0
        << "                               expected:   +02161481917052884915735749407450 cc: 0\n" << endl;
   dout << "748345987654321 x 288834570200345 x 100  = " << m5 * m6 * 100.0
        << "                               expected:   +21614819170528849157357494074500 cc: 0\n" << endl;
   dout << "748345987654321 x 288834570200345 x 1000 = " << m5 * m6 * 1000.0
        << "                               expected:   +00216148191705288491573574940745 cc: 16\n" << endl;
   dout << "123456789 x 123456789 x 123456789        = " << m3 * m3 * m3
        << "                               expected:   +00000001881676371789154860897069 cc: 0\n" << endl;
   dout << "123456789 x 123456789 x 123456789 x 123456789 = " << m3 * m3 * m3 * m3
        << "                                    expected:   +00000001881676371789154860897069 cc: 16\n" << endl;
   dout << "                                        2 x 2 = " << m2*m2
        << "                                    expected:   +00000000000000000000000000000004 cc: 0\n" << endl;
   dout << "                                       2 x 12 = " << m2*m1
        << "                                    expected:   +00000000000000000000000000000024 cc: 0\n" << endl;
   dout << "                                2 x 123456789 = " << m2 * m3
        << "                                    expected:   +00000000000000000000000246913578 cc: 0\n" << endl;
   dout << "                                123456789 x 2 = " << m3 * m2
        << "                                    expected:   +00000000000000000000000246913578 cc: 0\n" << endl;
   dout << " 4096 x 2 = " << m4 * m2
        << "expected:   +00000000000000000000000000008192 cc: 0\n" << endl;
   dout << " 2 x 4096 = " << m2 * m4
        << "expected:   +00000000000000000000000000008192 cc: 0\n" << endl;
   dout << " 2 x 12 x 4096 = " << m2 * m1 * m4
        << "expected:        +00000000000000000000000000098304 cc: 0\n" << endl;
   dout << "    aa = " << aa
        << "    bb = " << bb
        << " aa-bb = " << aa-bb
        << "expected:+99999999999999999999999999999998 cc: 0\n"
        << " aa+bb = " << aa+bb 
        << "expected:+00000000000000000000000000000000 cc: 1\n" << endl;
   dout << "     e = " << e
        << "     f = " << f
        << " e + f = " << e+f
        << "expected:+00000000000000000000000000000000 cc: 0\n" 
        << " e - f = " << e-f 
        << "expected:+00000000000000000000000000000000 cc: 0\n" << endl;
   dout << "     g = " << g
        << "     h = " << h
        << " g + h = " << g+h
        << "expected:+00000000000000000000000000000000 cc: 0\n"
        << " g - h = " << g-h 
        << "expected:+00000000000000000000000000000000 cc: 0\n" << endl;
   dout << "     w = " << w
        << "     x = " << x
        << " w + x = " << w+x
        << "expected:+00000000000000000000000000000000 cc: 0\n"
        << " w - x = " << w-x 
        << "expected:+00000000000000000000000000000002 cc: 0\n" << endl;
   dout << "     y = " << y
        << "     z = " << z
        << " y + z = " << y+z
        << "expected:+00000000000000000000000000000298 cc: 0\n"
        << " y - z = " << y-z 
        << "expected:-00000000000000000000000000000302 cc: 0\n" << endl;
   dout << "numa =      " << numa 
        << "numb =      " << numb
        << "numa+numb = " << numd
        << "expected:   +00000000000000001234567890991975 cc: 0\n"
        << "numb+numa = " << numb+numa 
        << "expected:   +00000000000000001234567890991975 cc: 0\n" << endl;
   dout << "numa =      " << numa 
        << "numc =      " << numc
        << "numa+numc = " << numa+numc 
        << "expected:   +00000000000000001234567866306297 cc: 0\n"
        << "numc+numa = " << numc+numa
        << "expected:   +00000000000000001234567866306297 cc: 0\n" << endl;
   dout << "numb =      " << numb
        << "numc =      " << numc
        << "numb+numc = " << numb+numc 
        << "expected:   -00000000000000000000000024677036 cc: 0\n"
        << "numc+numb = " << numc+numb 
        << "expected:   -00000000000000000000000024677036 cc: 0\n" << endl;
   dout << "numa =      " << numa 
        << "numb =      " << numb
        << "numa-numb = " << numa-numb 
        << "expected:   +00000000000000001234567890983333 cc: 0\n" 
        << "numb-numa = " << numb-numa 
        << "expected:   -00000000000000001234567890983333 cc: 0\n" << endl;
   dout << "numa =      " << numa 
        << "numc =      " << numc
        << "numa-numc = " << numa-numc 
        << "expected:   +00000000000000001234567915669011 cc: 0\n"
        << "numc-numa = " << numc-numa 
        << "expected:   -00000000000000001234567915669011 cc: 0\n" << endl;
   dout << "numb =      " << numb
        << "numc =      " << numc
        << "numb-numc = " << numb-numc 
        << "expected:   +00000000000000000000000024685678 cc: 0\n"
        << "numc-numb = " << numc-numb
        << "expected:   -00000000000000000000000024685678 cc: 0\n" << endl;
   dout.close();
   delete st;
   return 0;
}
Exemple #19
0
osg::ref_ptr<osg::Node> OSGConverter::setupGraph(const std::string filename, bool autoRotate) {

	// get some privacy
	tthread::lock_guard<tthread::recursive_mutex> lock(_cacheMutex);

	/**
	 *  root (model pose)
	 *    - rotate (autoRotate to face largest side)
	 *      - modelCenter (center model)
	 *        - model (actual model)
	 */

	long now = tthread::chrono::system_clock::now();

	{

		// do we have it in the cache?
		if (_models.find(filename) == _models.end()) {
			osg::ref_ptr<osg::Node> model = osgDB::readNodeFile(filename);
			if (!model.valid()) {
				LOG(ERROR) << "Cannot load model from " << filename;
				return new osg::MatrixTransform();
			}
			_models[filename] = std::make_pair(now, model);
		}
		_models[filename].first = now;

#if 1
		// remove old models from cache
		std::map<std::string, std::pair<long, osg::ref_ptr<osg::Node> > >::iterator modelIter = _models.begin();
		while(modelIter != _models.end()) {
			// delete every model unused for 1 minutes
			if (now - modelIter->second.first > 6000) {
				_models.erase(modelIter++);
			} else {
				modelIter++;
			}
		}

#endif
	}

	osg::ref_ptr<osg::MatrixTransform> root = new osg::MatrixTransform();
	osg::ref_ptr<osg::MatrixTransform> rotate = new osg::MatrixTransform();
	osg::ref_ptr<osg::Node> model = _models[filename].second;

	// translation matrix to move model into center
	osg::ref_ptr<osg::MatrixTransform> modelCenter = new osg::MatrixTransform();
	modelCenter->addChild(model);
	rotate->addChild(modelCenter);

	// move bounding sphere center into origin
	osg::BoundingSphere bs = model->getBound();
	modelCenter->setMatrix(osg::Matrix::translate(bs.center() *= -1));

	// get bounding box
	osg::ComputeBoundsVisitor cbv;
	osg::BoundingBox& bb(cbv.getBoundingBox());
	modelCenter->accept(cbv);

	if (autoRotate) {
		double depth = bb.zMax() - bb.zMin();
		double width = bb.xMax() - bb.xMin();
		double height = bb.yMax() - bb.yMin();

		double frontArea = width * height;
		double sideArea = depth * height;
		double topArea = depth * width;

		// rotate by multiples of 90deg to face largest area
		if (frontArea < sideArea || frontArea < topArea) {
			if (sideArea < topArea) {
				// top needs to come to front -> rotate on x
				rotate->setMatrix(osg::Matrix::rotate(M_PI_2, osg::Vec3f(1.0,0,0)));
			} else {
				// side needs to come to front
				rotate->setMatrix(osg::Matrix::rotate(M_PI_2, osg::Vec3f(0,1.0,0)));
			}
		}
	}

	// add rotation to root
	root->addChild(rotate);
	return root;
}
Exemple #20
0
osg::Node* createLogo(const std::string& filename, const std::string& label, const std::string& subscript)
{
    osg::BoundingBox bb(osg::Vec3(0.0f,0.0f,0.0f),osg::Vec3(100.0f,100.0f,100.0f));
    float chordRatio = 0.5f; 
    float sphereRatio = 0.6f; 

    // create a group to hold the whole model.
    osg::Group* logo_group = new osg::Group;

    osg::Quat r1,r2;
    r1.makeRotate(-osg::inDegrees(45.0f),0.0f,0.0f,1.0f);
    r2.makeRotate(osg::inDegrees(45.0f),1.0f,0.0f,0.0f);


    MyBillboardTransform* xform = new MyBillboardTransform;
    xform->setPivotPoint(bb.center());
    xform->setPosition(bb.center());
    xform->setAttitude(r1*r2);


//     // create a transform to orientate the box and globe.
//     osg::MatrixTransform* xform = new osg::MatrixTransform;
//     xform->setDataVariance(osg::Object::STATIC);
//     xform->setMatrix(osg::Matrix::translate(-bb.center())*
//                      osg::Matrix::rotate(-osg::inDegrees(45.0f),0.0f,0.0f,1.0f)*
//                      osg::Matrix::rotate(osg::inDegrees(45.0f),1.0f,0.0f,0.0f)*
//                      osg::Matrix::translate(bb.center()));

    // add the box and globe to it.
    //xform->addChild(createBox(bb,chordRatio));
    //xform->addChild(createBoxNo5(bb,chordRatio));
    xform->addChild(createBoxNo5No2(bb,chordRatio));
    // add the transform to the group.
    logo_group->addChild(xform);

    logo_group->addChild(createGlobe(bb,sphereRatio,filename));

    // add the text to the group.
    //group->addChild(createTextBelow(bb));
    logo_group->addChild(createTextLeft(bb, label, subscript));
    
    
    // create the backdrop to render the shadow to.
    osg::Vec3 corner(-900.0f,150.0f,-100.0f);
    osg::Vec3 top(0.0f,0.0f,300.0f); top += corner;
    osg::Vec3 right(1100.0f,0.0f,0.0f); right += corner;
    
    
//     osg::Group* backdrop = new osg::Group;
//     backdrop->addChild(createBackdrop(corner,top,right));

    osg::ClearNode* backdrop = new osg::ClearNode;
    backdrop->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,0.0f));

    //osg::Vec3 lightPosition(-500.0f,-2500.0f,500.0f);
    //osg::Node* scene = createShadowedScene(logo_group,backdrop,lightPosition,0.0f,0);

    osg::Group* scene = new osg::Group;

    osg::StateSet* stateset = scene->getOrCreateStateSet();
    stateset->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);


    scene->addChild(logo_group);
    scene->addChild(backdrop);

    return scene;
}
Exemple #21
0
    /**
     * This is called by db/ops/query.cpp.  This is the entry point for answering a query.
     */
    string newRunQuery(Message& m, QueryMessage& q, CurOp& curop, Message &result) {
        // This is a read lock.
        Client::ReadContext ctx(q.ns, dbpath);

        // Parse, canonicalize, plan, transcribe, and get a runner.
        Runner* rawRunner;
        Status status = getRunner(q, &rawRunner);
        if (!status.isOK()) {
            uasserted(17007, "Couldn't process query " + q.query.toString()
                         + " why: " + status.reason());
        }
        verify(NULL != rawRunner);
        auto_ptr<Runner> runner(rawRunner);

        // We freak out later if this changes before we're done with the query.
        const ChunkVersion shardingVersionAtStart = shardingState.getVersion(q.ns);

        // We use this a lot below.
        const ParsedQuery& pq = runner->getQuery().getParsed();

        // TODO: Document why we do this.
        replVerifyReadsOk(&pq);

        // If this exists, the collection is sharded.
        // If it doesn't exist, we can assume we're not sharded.
        // If we're sharded, we might encounter data that is not consistent with our sharding state.
        // We must ignore this data.
        CollectionMetadataPtr collMetadata;
        if (!shardingState.needCollectionMetadata(pq.ns())) {
            collMetadata = CollectionMetadataPtr();
        }
        else {
            collMetadata = shardingState.getCollectionMetadata(pq.ns());
        }

        // Run the query.
        BufBuilder bb(32768);
        bb.skip(sizeof(QueryResult));

        // How many results have we obtained from the runner?
        int numResults = 0;

        // If we're replaying the oplog, we save the last time that we read.
        OpTime slaveReadTill;

        // Do we save the Runner in a ClientCursor for getMore calls later?
        bool saveClientCursor = false;

        BSONObj obj;
        // TODO: Differentiate EOF from error.
        while (runner->getNext(&obj)) {
            // If we're sharded make sure that we don't return any data that hasn't been migrated
            // off of our shared yet.
            if (collMetadata) {
                // This information can change if we yield and as such we must make sure to re-fetch
                // it if we yield.
                KeyPattern kp(collMetadata->getKeyPattern());
                // This performs excessive BSONObj creation but that's OK for now.
                if (!collMetadata->keyBelongsToMe(kp.extractSingleKey(obj))) { continue; }
            }

            // Add result to output buffer.
            bb.appendBuf((void*)obj.objdata(), obj.objsize());

            // Count the result.
            ++numResults;

            // Possibly note slave's position in the oplog.
            if (pq.hasOption(QueryOption_OplogReplay)) {
                BSONElement e = obj["ts"];
                if (Date == e.type() || Timestamp == e.type()) {
                    slaveReadTill = e._opTime();
                }
            }

            // TODO: only one type of 2d search doesn't support this.  We need a way to pull it out
            // of CanonicalQuery. :(
            const bool supportsGetMore = true;
            const bool isExplain = pq.isExplain();
            if (isExplain && pq.enoughForExplain(numResults)) {
                break;
            }
            else if (!supportsGetMore && (pq.enough(numResults)
                                          || bb.len() >= MaxBytesToReturnToClientAtOnce)) {
                break;
            }
            else if (pq.enoughForFirstBatch(numResults, bb.len())) {
                // If only one result requested assume it's a findOne() and don't save the cursor.
                if (pq.wantMore() && 1 != pq.getNumToReturn()) {
                    saveClientCursor = true;
                }
                break;
            }
        }

        // TODO: Stage creation can set tailable depending on what's in the parsed query.  We have
        // the full parsed query available during planning...set it there.
        //
        // TODO: If we're tailable we want to save the client cursor.  Make sure we do this later.
        //if (pq.hasOption(QueryOption_CursorTailable) && pq.getNumToReturn() != 1) { ... }

        // TODO(greg): This will go away soon.
        if (!shardingState.getVersion(pq.ns()).isWriteCompatibleWith(shardingVersionAtStart)) {
            // if the version changed during the query we might be missing some data and its safe to
            // send this as mongos can resend at this point
            throw SendStaleConfigException(pq.ns(), "version changed during initial query",
                                           shardingVersionAtStart,
                                           shardingState.getVersion(pq.ns()));
        }

        long long ccId = 0;
        if (saveClientCursor) {
            // Allocate a new ClientCursor.
            ClientCursorHolder ccHolder;
            ccHolder.reset(new ClientCursor(runner.get()));
            ccId = ccHolder->cursorid();

            // We won't use the runner until it's getMore'd.
            runner->saveState();

            // ClientCursor takes ownership of runner.  Release to make sure it's not deleted.
            runner.release();

            if (pq.hasOption(QueryOption_OplogReplay) && !slaveReadTill.isNull()) {
                ccHolder->slaveReadTill(slaveReadTill);
            }

            if (pq.hasOption(QueryOption_Exhaust)) {
                curop.debug().exhaust = true;
            }

            // Set attributes for getMore.
            ccHolder->setCollMetadata(collMetadata);
            ccHolder->setPos(numResults);

            // If the query had a time limit, remaining time is "rolled over" to the cursor (for
            // use by future getmore ops).
            ccHolder->setLeftoverMaxTimeMicros(curop.getRemainingMaxTimeMicros());

            // Give up our reference to the CC.
            ccHolder.release();
        }

        // Add the results from the query into the output buffer.
        result.appendData(bb.buf(), bb.len());
        bb.decouple();

        // Fill out the output buffer's header.
        QueryResult* qr = static_cast<QueryResult*>(result.header());
        qr->cursorId = ccId;
        curop.debug().cursorid = (0 == ccId ? -1 : ccId);
        qr->setResultFlagsToOk();
        qr->setOperation(opReply);
        qr->startingFrom = 0;
        qr->nReturned = numResults;
        // TODO: nscanned is bogus.
        // curop.debug().nscanned = ( cursor ? cursor->nscanned() : 0LL );
        curop.debug().ntoskip = pq.getSkip();
        curop.debug().nreturned = numResults;

        // curop.debug().exhaust is set above.
        return curop.debug().exhaust ? pq.ns() : "";
    }
Exemple #22
0
 void Model::append( const char * name , BSONObjBuilder& b ){
     BSONObjBuilder bb( b.subobjStart( name ) );
     serialize( bb );
     bb.done();
 }
Exemple #23
0
        bool run(const string& dbname, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl ) {
            Timer t;
            string ns = dbname + '.' + cmdObj.firstElement().valuestr();

            string key = cmdObj["key"].valuestrsafe();
            BSONObj keyPattern = BSON( key << 1 );

            BSONObj query = getQuery( cmdObj );

            int bufSize = BSONObjMaxUserSize - 4096;
            BufBuilder bb( bufSize );
            char * start = bb.buf();

            BSONArrayBuilder arr( bb );
            BSONElementSet values;

            long long nscanned = 0; // locations looked at
            long long nscannedObjects = 0; // full objects looked at
            long long n = 0; // matches
            MatchDetails md;

            NamespaceDetails * d = nsdetails( ns.c_str() );

            if ( ! d ) {
                result.appendArray( "values" , BSONObj() );
                result.append( "stats" , BSON( "n" << 0 << "nscanned" << 0 << "nscannedObjects" << 0 ) );
                return true;
            }

            shared_ptr<Cursor> cursor;
            if ( ! query.isEmpty() ) {
                cursor = NamespaceDetailsTransient::getCursor(ns.c_str() , query , BSONObj() );
            }
            else {

                // query is empty, so lets see if we can find an index
                // with the key so we don't have to hit the raw data
                NamespaceDetails::IndexIterator ii = d->ii();
                while ( ii.more() ) {
                    IndexDetails& idx = ii.next();

                    if ( d->isMultikey( ii.pos() - 1 ) )
                        continue;

                    if ( idx.inKeyPattern( key ) ) {
                        cursor = bestGuessCursor( ns.c_str() , BSONObj() , idx.keyPattern() );
                        if( cursor.get() ) break;
                    }

                }

                if ( ! cursor.get() )
                    cursor = NamespaceDetailsTransient::getCursor(ns.c_str() , query , BSONObj() );

            }

            
            assert( cursor );
            string cursorName = cursor->toString();
            
            auto_ptr<ClientCursor> cc (new ClientCursor(QueryOption_NoCursorTimeout, cursor, ns));

            while ( cursor->ok() ) {
                nscanned++;
                bool loadedObject = false;

                if ( cursor->currentMatches( &md ) && !cursor->getsetdup( cursor->currLoc() ) ) {
                    n++;

                    BSONObj holder;
                    BSONElementSet temp;
                    loadedObject = ! cc->getFieldsDotted( key , temp, holder );

                    for ( BSONElementSet::iterator i=temp.begin(); i!=temp.end(); ++i ) {
                        BSONElement e = *i;
                        if ( values.count( e ) )
                            continue;

                        int now = bb.len();

                        uassert(10044,  "distinct too big, 16mb cap", ( now + e.size() + 1024 ) < bufSize );

                        arr.append( e );
                        BSONElement x( start + now );

                        values.insert( x );
                    }
                }

                if ( loadedObject || md._loadedObject )
                    nscannedObjects++;

                cursor->advance();

                if (!cc->yieldSometimes( ClientCursor::MaybeCovered )) {
                    cc.release();
                    break;
                }

                RARELY killCurrentOp.checkForInterrupt();
            }

            assert( start == bb.buf() );

            result.appendArray( "values" , arr.done() );

            {
                BSONObjBuilder b;
                b.appendNumber( "n" , n );
                b.appendNumber( "nscanned" , nscanned );
                b.appendNumber( "nscannedObjects" , nscannedObjects );
                b.appendNumber( "timems" , t.millis() );
                b.append( "cursor" , cursorName );
                result.append( "stats" , b.obj() );
            }

            return true;
        }
Exemple #24
0
    /**
     * This is called by db/ops/query.cpp.  This is the entry point for answering a query.
     */
    string newRunQuery(Message& m, QueryMessage& q, CurOp& curop, Message &result) {
        // This is a read lock.
        Client::ReadContext ctx(q.ns, dbpath);

        // Parse, canonicalize, plan, transcribe, and get a runner.
        Runner* rawRunner;
        CanonicalQuery* cq;
        Status status = getRunner(q, &rawRunner, &cq);
        if (!status.isOK()) {
            uasserted(17007, "Couldn't process query " + q.query.toString()
                         + " why: " + status.reason());
        }
        verify(NULL != rawRunner);
        auto_ptr<Runner> runner(rawRunner);

        log() << "Running query on new system: " << cq->toString();

        // We freak out later if this changes before we're done with the query.
        const ChunkVersion shardingVersionAtStart = shardingState.getVersion(q.ns);

        // We use this a lot below.
        const LiteParsedQuery& pq = cq->getParsed();

        // TODO: Remove when impl'd
        if (pq.hasOption(QueryOption_OplogReplay)) {
            warning() << "haven't implemented findingstartcursor yet\n";
        }

        // Handle query option $maxTimeMS (not used with commands).
        curop.setMaxTimeMicros(static_cast<unsigned long long>(pq.getMaxTimeMS()) * 1000);
        killCurrentOp.checkForInterrupt(); // May trigger maxTimeAlwaysTimeOut fail point.

        // uassert if we are not on a primary, and not a secondary with SlaveOk query parameter set.
        replVerifyReadsOk(&pq);

        // If this exists, the collection is sharded.
        // If it doesn't exist, we can assume we're not sharded.
        // If we're sharded, we might encounter data that is not consistent with our sharding state.
        // We must ignore this data.
        CollectionMetadataPtr collMetadata;
        if (!shardingState.needCollectionMetadata(pq.ns())) {
            collMetadata = CollectionMetadataPtr();
        }
        else {
            collMetadata = shardingState.getCollectionMetadata(pq.ns());
        }

        // Run the query.
        // bb is used to hold query results
        // this buffer should contain either requested documents per query or
        // explain information, but not both
        BufBuilder bb(32768);
        bb.skip(sizeof(QueryResult));

        // How many results have we obtained from the runner?
        int numResults = 0;

        // If we're replaying the oplog, we save the last time that we read.
        OpTime slaveReadTill;

        // Do we save the Runner in a ClientCursor for getMore calls later?
        bool saveClientCursor = false;

        // We turn on auto-yielding for the runner here.  The runner registers itself with the
        // active runners list in ClientCursor.
        ClientCursor::registerRunner(runner.get());
        runner->setYieldPolicy(Runner::YIELD_AUTO);
        auto_ptr<DeregisterEvenIfUnderlyingCodeThrows> safety(
            new DeregisterEvenIfUnderlyingCodeThrows(runner.get()));

        BSONObj obj;
        Runner::RunnerState state;

        // set this outside loop. we will need to use this both within loop and when deciding
        // to fill in explain information
        const bool isExplain = pq.isExplain();

        while (Runner::RUNNER_ADVANCED == (state = runner->getNext(&obj, NULL))) {
            // If we're sharded make sure that we don't return any data that hasn't been migrated
            // off of our shared yet.
            if (collMetadata) {
                // This information can change if we yield and as such we must make sure to re-fetch
                // it if we yield.
                KeyPattern kp(collMetadata->getKeyPattern());
                // This performs excessive BSONObj creation but that's OK for now.
                if (!collMetadata->keyBelongsToMe(kp.extractSingleKey(obj))) { continue; }
            }

            // Add result to output buffer. This is unnecessary if explain info is requested
            if (!isExplain) {
                bb.appendBuf((void*)obj.objdata(), obj.objsize());
            }

            // Count the result.
            ++numResults;

            // Possibly note slave's position in the oplog.
            if (pq.hasOption(QueryOption_OplogReplay)) {
                BSONElement e = obj["ts"];
                if (Date == e.type() || Timestamp == e.type()) {
                    slaveReadTill = e._opTime();
                }
            }

            // TODO: only one type of 2d search doesn't support this.  We need a way to pull it out
            // of CanonicalQuery. :(
            const bool supportsGetMore = true;
            if (isExplain) {
                if (enoughForExplain(pq, numResults)) {
                    break;
                }
            }
            else if (!supportsGetMore && (enough(pq, numResults)
                                          || bb.len() >= MaxBytesToReturnToClientAtOnce)) {
                break;
            }
            else if (enoughForFirstBatch(pq, numResults, bb.len())) {
                // If only one result requested assume it's a findOne() and don't save the cursor.
                if (pq.wantMore() && 1 != pq.getNumToReturn()) {
                    saveClientCursor = true;
                }
                break;
            }
        }

        // If we cache the runner later, we want to deregister it as it receives notifications
        // anyway by virtue of being cached.
        //
        // If we don't cache the runner later, we are deleting it, so it must be deregistered.
        //
        // So, no matter what, deregister the runner.
        safety.reset();

        // Caller expects exceptions thrown in certain cases:
        // * in-memory sort using too much RAM.
        if (Runner::RUNNER_ERROR == state) {
            uasserted(17144, "Runner error, memory limit for sort probably exceeded");
        }

        // Why save a dead runner?
        if (Runner::RUNNER_DEAD == state) {
            saveClientCursor = false;
        }
        else if (pq.hasOption(QueryOption_CursorTailable) && (1 != pq.getNumToReturn())) {
            // If pq.hasOption(tailable) the only plan the planner will output is a collscan with
            // tailable set.
            saveClientCursor = true;
        }

        // TODO(greg): This will go away soon.
        if (!shardingState.getVersion(pq.ns()).isWriteCompatibleWith(shardingVersionAtStart)) {
            // if the version changed during the query we might be missing some data and its safe to
            // send this as mongos can resend at this point
            throw SendStaleConfigException(pq.ns(), "version changed during initial query",
                                           shardingVersionAtStart,
                                           shardingState.getVersion(pq.ns()));
        }

        long long ccId = 0;
        if (saveClientCursor) {
            // We won't use the runner until it's getMore'd.
            runner->saveState();

            // Allocate a new ClientCursor.  We don't have to worry about leaking it as it's
            // inserted into a global map by its ctor.
            ClientCursor* cc = new ClientCursor(runner.get(), cq->getParsed().getOptions(),
                                                cq->getParsed().getFilter());
            ccId = cc->cursorid();

            log() << "caching runner with cursorid " << ccId
                  << " after returning " << numResults << " results" << endl;

            // ClientCursor takes ownership of runner.  Release to make sure it's not deleted.
            runner.release();

            // TODO document
            if (pq.hasOption(QueryOption_OplogReplay) && !slaveReadTill.isNull()) {
                cc->slaveReadTill(slaveReadTill);
            }

            // TODO document
            if (pq.hasOption(QueryOption_Exhaust)) {
                curop.debug().exhaust = true;
            }

            // Set attributes for getMore.
            cc->setCollMetadata(collMetadata);
            cc->setPos(numResults);

            // If the query had a time limit, remaining time is "rolled over" to the cursor (for
            // use by future getmore ops).
            cc->setLeftoverMaxTimeMicros(curop.getRemainingMaxTimeMicros());
        }

        // append explain information to query results
        if (isExplain) {
            BSONObjBuilder bob;
            bob.append("n", numResults);
            BSONObj obj = bob.done();
            bb.appendBuf((void*)obj.objdata(), obj.objsize());
            // The explain output is actually a result.
            numResults = 1;
        }

        // Add the results from the query into the output buffer.
        result.appendData(bb.buf(), bb.len());
        bb.decouple();

        // Fill out the output buffer's header.
        QueryResult* qr = static_cast<QueryResult*>(result.header());
        qr->cursorId = ccId;
        curop.debug().cursorid = (0 == ccId ? -1 : ccId);
        qr->setResultFlagsToOk();
        qr->setOperation(opReply);
        qr->startingFrom = 0;
        qr->nReturned = numResults;
        // TODO: nscanned is bogus.
        // curop.debug().nscanned = ( cursor ? cursor->nscanned() : 0LL );
        curop.debug().ntoskip = pq.getSkip();
        curop.debug().nreturned = numResults;

        // curop.debug().exhaust is set above.
        return curop.debug().exhaust ? pq.ns() : "";
    }
Exemple #25
0
    /**
     * Also called by db/ops/query.cpp.  This is the new getMore entry point.
     */
    QueryResult* newGetMore(const char* ns, int ntoreturn, long long cursorid, CurOp& curop,
                            int pass, bool& exhaust, bool* isCursorAuthorized) {
        exhaust = false;
        int bufSize = 512 + sizeof(QueryResult) + MaxBytesToReturnToClientAtOnce;

        BufBuilder bb(bufSize);
        bb.skip(sizeof(QueryResult));

        // This is a read lock.
        scoped_ptr<Client::ReadContext> ctx(new Client::ReadContext(ns));

        QLOG() << "running getMore in new system, cursorid " << cursorid << endl;

        // This checks to make sure the operation is allowed on a replicated node.  Since we are not
        // passing in a query object (necessary to check SlaveOK query option), the only state where
        // reads are allowed is PRIMARY (or master in master/slave).  This function uasserts if
        // reads are not okay.
        replVerifyReadsOk();

        // A pin performs a CC lookup and if there is a CC, increments the CC's pin value so it
        // doesn't time out.  Also informs ClientCursor that there is somebody actively holding the
        // CC, so don't delete it.
        ClientCursorPin ccPin(cursorid);
        ClientCursor* cc = ccPin.c();

        // These are set in the QueryResult msg we return.
        int resultFlags = ResultFlag_AwaitCapable;

        int numResults = 0;
        int startingResult = 0;

        if (NULL == cc) {
            cursorid = 0;
            resultFlags = ResultFlag_CursorNotFound;
        }
        else {
            // Quote: check for spoofing of the ns such that it does not match the one originally
            // there for the cursor
            uassert(17011, "auth error", str::equals(ns, cc->ns().c_str()));
            *isCursorAuthorized = true;

            // Reset timeout timer on the cursor since the cursor is still in use.
            cc->setIdleTime(0);

            // TODO: fail point?

            // If the operation that spawned this cursor had a time limit set, apply leftover
            // time to this getmore.
            curop.setMaxTimeMicros(cc->getLeftoverMaxTimeMicros());
            killCurrentOp.checkForInterrupt(); // May trigger maxTimeAlwaysTimeOut fail point.

            // TODO:
            // curop.debug().query = BSONForQuery
            // curop.setQuery(curop.debug().query);

            // TODO: What is pass?
            if (0 == pass) { cc->updateSlaveLocation(curop); }

            if (cc->isAggCursor) {
                // Agg cursors handle their own locking internally.
                ctx.reset(); // unlocks
            }

            CollectionMetadataPtr collMetadata = cc->getCollMetadata();

            // If we're replaying the oplog, we save the last time that we read.
            OpTime slaveReadTill;

            // What number result are we starting at?  Used to fill out the reply.
            startingResult = cc->pos();

            // What gives us results.
            Runner* runner = cc->getRunner();
            const int queryOptions = cc->queryOptions();

            // Get results out of the runner.
            runner->restoreState();

            BSONObj obj;
            Runner::RunnerState state;
            while (Runner::RUNNER_ADVANCED == (state = runner->getNext(&obj, NULL))) {
                // Add result to output buffer.
                bb.appendBuf((void*)obj.objdata(), obj.objsize());

                // Count the result.
                ++numResults;

                // Possibly note slave's position in the oplog.
                if (queryOptions & QueryOption_OplogReplay) {
                    BSONElement e = obj["ts"];
                    if (Date == e.type() || Timestamp == e.type()) {
                        slaveReadTill = e._opTime();
                    }
                }

                if ((ntoreturn && numResults >= ntoreturn)
                    || bb.len() > MaxBytesToReturnToClientAtOnce) {
                    break;
                }
            }

            if (Runner::RUNNER_EOF == state && 0 == numResults
                && (queryOptions & QueryOption_CursorTailable)
                && (queryOptions & QueryOption_AwaitData) && (pass < 1000)) {
                // If the cursor is tailable we don't kill it if it's eof.  We let it try to get
                // data some # of times first.
                return 0;
            }

            bool saveClientCursor = false;

            if (Runner::RUNNER_DEAD == state || Runner::RUNNER_ERROR == state) {
                // If we're dead there's no way to get more results.
                saveClientCursor = false;
                // In the old system tailable capped cursors would be killed off at the
                // cursorid level.  If a tailable capped cursor is nuked the cursorid
                // would vanish.
                // 
                // In the new system they die and are cleaned up later (or time out).
                // So this is where we get to remove the cursorid.
                if (0 == numResults) {
                    resultFlags = ResultFlag_CursorNotFound;
                }
            }
            else if (Runner::RUNNER_EOF == state) {
                // EOF is also end of the line unless it's tailable.
                saveClientCursor = queryOptions & QueryOption_CursorTailable;
            }
            else {
                verify(Runner::RUNNER_ADVANCED == state);
                saveClientCursor = true;
            }

            if (!saveClientCursor) {
                ccPin.deleteUnderlying();
                // cc is now invalid, as is the runner
                cursorid = 0;
                cc = NULL;
                QLOG() << "getMore NOT saving client cursor, ended w/state "
                       << Runner::statestr(state)
                       << endl;
            }
            else {
                // Continue caching the ClientCursor.
                cc->incPos(numResults);
                runner->saveState();
                QLOG() << "getMore saving client cursor ended w/state "
                       << Runner::statestr(state)
                       << endl;

                // Possibly note slave's position in the oplog.
                if ((queryOptions & QueryOption_OplogReplay) && !slaveReadTill.isNull()) {
                    cc->slaveReadTill(slaveReadTill);
                }

                exhaust = (queryOptions & QueryOption_Exhaust);

                // If the getmore had a time limit, remaining time is "rolled over" back to the
                // cursor (for use by future getmore ops).
                cc->setLeftoverMaxTimeMicros( curop.getRemainingMaxTimeMicros() );
            }
        }

        QueryResult* qr = reinterpret_cast<QueryResult*>(bb.buf());
        qr->len = bb.len();
        qr->setOperation(opReply);
        qr->_resultFlags() = resultFlags;
        qr->cursorId = cursorid;
        qr->startingFrom = startingResult;
        qr->nReturned = numResults;
        bb.decouple();
        QLOG() << "getMore returned " << numResults << " results\n";
        return qr;
    }
Exemple #26
0
// This is the main loop for the worker thread
UINT CHexEditDoc::RunSearchThread()
{
	// Keep looping until we get the kill signal
	for (;;)
	{
		{
			CSingleLock sl(&docdata_, TRUE);
			search_state_ = WAITING;
		}
		TRACE1("+++ BGSearch: waiting %p\n", this);
		DWORD wait_status = ::WaitForSingleObject(HANDLE(start_search_event_), INFINITE);
		docdata_.Lock();
		search_state_ = SCANNING;
		docdata_.Unlock();
		start_search_event_.ResetEvent();      // Force ourselves to wait
		ASSERT(wait_status == WAIT_OBJECT_0);
		TRACE1("+++ BGSearch: got event for %p\n", this);

		if (SearchProcessStop())
			continue;

		size_t buf_len;
		int count = 0;

		theApp.appdata_.Lock();
		ASSERT(theApp.pboyer_ != NULL);
		boyer bb(*theApp.pboyer_);             // Take a copy of needed info
		BOOL ignorecase = theApp.icase_;
		int tt = theApp.text_type_;
		BOOL wholeword = theApp.wholeword_;
		int alignment = theApp.alignment_;
		int offset = theApp.offset_;
		theApp.appdata_.Unlock();

		docdata_.Lock();
		search_fin_ = false;
		FILE_ADDRESS file_len = length_;
		FILE_ADDRESS base_addr = base_addr_;
		docdata_.Unlock();

		ASSERT(bb.length() > 0);
		ASSERT(tt == 0 || tt == 1 || tt == 2 || tt == 3);

		if (bb.length() > file_len)
		{
			// Nothing can be found
			CSingleLock sl(&docdata_, TRUE);
			to_search_.clear();
			found_.clear();
			find_total_ = 0;
			search_fin_ = true;
			continue;
		}

		buf_len = (size_t)min(file_len, 32768 + bb.length() - 1);
		ASSERT(search_buf_ == NULL);
		search_buf_ = new unsigned char[buf_len + 1];

		// Search all to_search_ blocks
		for (;;)
		{
			if (SearchProcessStop())
				break;

			FILE_ADDRESS start, end;    // Current part of file to search

			// Get the next block to search
			{
				CSingleLock sl(&docdata_, TRUE); // Protect shared data access

				// Check if there has been a file insertion/deletion
				while (!to_adjust_.empty())
				{
					FixFound(to_adjust_.front().start_, 
							 to_adjust_.front().end_,
							 to_adjust_.front().address_,
							 to_adjust_.front().adjust_);

					// start, end should have already been adjusted at this point
					to_adjust_.pop_front();
				}
				file_len = length_;

				// Find where we have to search
				if (to_search_.empty())
				{
					find_total_ = 0;
					search_fin_ = true;
					TRACE1("+++ BGSearch: finished search of %p\n", this);
					break;
				}
				start = to_search_.front().first;
				if (start < 0) start = 0;
				end = to_search_.front().second;
				if (end < 0) end = file_len;
			}

			// We need to extend the search a little for wholeword searches since even though the pattern match
			// does not change the fact that a match is discarded due to the "alphabeticity" of characters at
			// either end changing when chars are inserted or deleted.
			if (wholeword)
			{
				if (start > 0) start--;
				if (tt == 2 && start > 0) start--;  // Go back 2 bytes for Unicode searches
				++end;                  // No test needed here since "end" is adjusted below if past EOF
			}

			FILE_ADDRESS addr_buf = start;  // Current location in doc of start of search_buf_
			// Make sure we get extra bytes past end for length of search string
			end = min(end + bb.length() - 1, file_len);

			find_done_ = 0.0;               // We haven't searched any of this to_search_ block yet

			while (addr_buf + bb.length() <= end)
			{
				size_t got;
				bool alpha_before = false;
				bool alpha_after = false;

				// Get the next block
				{
					CSingleLock sl(&docdata_, TRUE);   // For accessing file data

					// Check if search cancelled or thread killed
					if (search_command_ != NONE)
						goto stop_search;

					// Check for any file insertions/deletions
					while (!to_adjust_.empty())
					{
						TRACE("+++ Adjusting already found\n");
						FixFound(to_adjust_.front().start_, 
								 to_adjust_.front().end_,
								 to_adjust_.front().address_,
								 to_adjust_.front().adjust_);
						TRACE("+++ Finished adjusting\n");

						if (start >= to_adjust_.front().address_)
						{
							start += to_adjust_.front().adjust_;
							if (start < to_adjust_.front().address_)
								start = to_adjust_.front().address_;
						}
						if (end >= to_adjust_.front().address_)
						{
							end += to_adjust_.front().adjust_;
							if (end < to_adjust_.front().address_)
								end = to_adjust_.front().address_;
						}
						if (addr_buf >= to_adjust_.front().address_)
						{
							addr_buf += to_adjust_.front().adjust_;
							if (addr_buf < to_adjust_.front().address_)
								addr_buf = to_adjust_.front().address_;
						}
						to_adjust_.pop_front();
					}
					file_len = length_;   // file length may have changed

					// Get a buffer full (plus an extra char for wholeword test at end of buffer)
					got = GetData(search_buf_, size_t(min(FILE_ADDRESS(buf_len), end - addr_buf)) + 1, addr_buf, 2);
					ASSERT(got == min(buf_len, end - addr_buf) || got == min(buf_len, end - addr_buf) + 1);

					if (wholeword)
					{
						// Work out whether the character before the buf is alphabetic
						if (addr_buf > 0 && tt == 1)
						{
							// Check if alphabetic ASCII
							unsigned char cc;
							VERIFY(GetData(&cc, 1, addr_buf-1, 2) == 1);

							alpha_before = isalnum(cc) != 0;
						}
						else if (addr_buf > 1 && tt == 2)
						{
							// Check if alphabetic Unicode
							unsigned char cc[2];
							VERIFY(GetData(cc, 2, addr_buf-2, 2) == 2);

							alpha_before = isalnum(cc[0]) != 0;  // Check if low byte has ASCII alpha
						}
						else if (addr_buf > 0 && tt == 3)
						{
							// Check if alphabetic EBCDIC
							unsigned char cc;
							VERIFY(GetData(&cc, 1, addr_buf-1, 2) == 1);

							alpha_before = isalnum(e2a_tab[cc]) != 0;
						}

						// If we read an extra character check if it is alphabetic
						if (got == min(buf_len, end - addr_buf) + 1)
						{
							if (tt == 3)
								alpha_after = isalnum(e2a_tab[search_buf_[got-1]]) != 0;
							else
								alpha_after = isalnum(search_buf_[got-1]) != 0;
						}
					}

					// Remove extra character obtained for wholeword test
					if (got == min(buf_len, end - addr_buf) + 1)
						got--;
				}
#ifdef TESTING1
				// For testing we allow 2 seconds for some changes to be made to the first
				// search block so that we can check that found_ is updated correctly
				if (addr_buf == 0)
				{
					::Sleep(2000);
					TRACE1("+++ Finished sleep in %p\n", this);
				}
#endif

				for (unsigned char *pp = search_buf_;
					 (pp = bb.findforw(pp, got - (pp-search_buf_), ignorecase, tt, wholeword,
						  alpha_before, alpha_after, alignment, offset, base_addr, addr_buf + (pp-search_buf_))) != NULL;
					 ++pp)
				{
					// Found one
					++count;

					CSingleLock sl(&docdata_, TRUE);

					if (search_command_ != NONE)
						goto stop_search;

					found_.insert(addr_buf + (pp - search_buf_));

					if (tt == 1)
						alpha_before = isalnum(*pp) != 0;
					else if (tt == 3)
						alpha_before = isalnum(e2a_tab[*pp]) != 0;
					else if (pp > search_buf_)
						alpha_before = isalnum(*(pp-1)) != 0;   // Check low byte of Unicode
					else
						alpha_before = false;                   // Only one byte before - we need 2 for Unicode
				}

				addr_buf += got - (bb.length() - 1);

				find_done_ = double(addr_buf - start) / double(end - start);
			} // while there is more to search

			{
				CSingleLock sl(&docdata_, TRUE);

				// Check for any file insertions/deletions
				while (!to_adjust_.empty())
				{
					FixFound(to_adjust_.front().start_, 
							 to_adjust_.front().end_,
							 to_adjust_.front().address_,
							 to_adjust_.front().adjust_);

					to_adjust_.pop_front();
				}
				file_len = length_;

				// Remove the block just searched from to_search_
				to_search_.pop_front();
			}
		stop_search:
			;
		} // for
		delete[] search_buf_;
		search_buf_ = NULL;
	}
}
Exemple #27
0
/*! Build the BVH, given an input data set
 *  - Handling our own stack is quite a bit faster than the recursive style.
 *  - Each build stack entry's parent field eventually stores the offset 
 *    to the parent of that node. Before that is finally computed, it will
 *    equal exactly three other values. (These are the magic values Untouched,
 *    Untouched-1, and TouchedTwice).
 *  - The partition here was also slightly faster than std::partition.
 */
void BVH::build()
{
 BVHBuildEntry todo[128];
 uint32_t stackptr = 0;
	const uint32_t Untouched    = 0xffffffff;
	const uint32_t TouchedTwice = 0xfffffffd;

 // Push the root
 todo[stackptr].start = 0;
 todo[stackptr].end = build_prims->size();
 todo[stackptr].parent = 0xfffffffc;
 stackptr++;

	BVHFlatNode node;
	std::vector<BVHFlatNode> buildnodes;
	buildnodes.reserve(build_prims->size()*2);

 while(stackptr > 0) {
		// Pop the next item off of the stack
		BVHBuildEntry &bnode( todo[--stackptr] );
		uint32_t start = bnode.start;
		uint32_t end = bnode.end;
		uint32_t nPrims = end - start;
	
		nNodes++;
		node.start = start;
		node.nPrims = nPrims;
		node.rightOffset = Untouched;

		// Calculate the bounding box for this node
		BBox bb( (*build_prims)[start]->getBBox());
		BBox bc( (*build_prims)[start]->getCentroid());
		for(uint32_t p = start+1; p < end; ++p) {
			bb.expandToInclude( (*build_prims)[p]->getBBox());
			bc.expandToInclude( (*build_prims)[p]->getCentroid());
		}
		node.bbox = bb;

  // If the number of primitives at this point is less than the leaf
  // size, then this will become a leaf. (Signified by rightOffset == 0)		
		if(nPrims <= leafSize) {
			node.rightOffset = 0;
			nLeafs++;
		}
		
		buildnodes.push_back(node);
		
		// Child touches parent...
		// Special case: Don't do this for the root.
		if(bnode.parent != 0xfffffffc) {
			buildnodes[bnode.parent].rightOffset --;

			// When this is the second touch, this is the right child.
			// The right child sets up the offset for the flat tree.
			//sunf:right offset is the offset of the right child of the node 
			if( buildnodes[bnode.parent].rightOffset == TouchedTwice ) {
				buildnodes[bnode.parent].rightOffset = nNodes - 1 - bnode.parent;
			}
		}

		// If this is a leaf, no need to subdivide.
		if(node.rightOffset == 0)
			continue;

		// Set the split dimensions
		uint32_t split_dim = bc.maxDimension();

		// Split on the center of the longest axis
		float split_coord = .5f * (bc.min[split_dim] + bc.max[split_dim]);
		
		// Partition the list of objects on this split
		uint32_t mid = start;
		for(uint32_t i=start;i<end;++i) {
			if( (*build_prims)[i]->getCentroid()[split_dim] < split_coord ) {
				std::swap( (*build_prims)[i], (*build_prims)[mid] );
				++mid;
			}
		}

		// If we get a bad split, just choose the center...
		if(mid == start || mid == end) {
			mid = start + (end-start)/2;
		}

		// Push right child
		todo[stackptr].start = mid;
		todo[stackptr].end = end;
		todo[stackptr].parent = nNodes-1;
		stackptr++;
		
		// Push left child
		todo[stackptr].start = start;
		todo[stackptr].end = mid;
		todo[stackptr].parent = nNodes-1;
		stackptr++;
 }

	// Copy the temp node data to a flat array
	flatTree = new BVHFlatNode[nNodes];
	for(uint32_t n=0; n<nNodes; ++n) 
		flatTree[n] = buildnodes[n];
}
Exemple #28
0
//GMRES  
int gmres(const  Teuchos::SerialDenseMatrix<int, double> &  A, Teuchos::SerialDenseMatrix<int,double>   X,const Teuchos::SerialDenseMatrix<int,double> &   B, int max_iter, double tolerance)

{
  int n; 
  int k;
  double resid;
  k=1;
  n=A.numRows();
  std::cout << "A= " << A << std::endl;
  std::cout << "B= " << B << std::endl;
  //Teuchos::SerialDenseMatrix<int, double> Ax(n,1);
  //Ax.multiply(Teuchos::NO_TRANS,Teuchos::NO_TRANS,1.0, A, X, 0.0);

  Teuchos::SerialDenseMatrix<int, double> r0(B);
  //r0-=Ax;
    
  resid=r0.normFrobenius();
  std::cout << "resid= " << resid << std::endl;
  //define vector v=r/norm(r) where r=b-Ax
  
  r0.scale(1/resid);
  
  Teuchos::SerialDenseMatrix<int, double> h(1,1);

  //Matrix of orthog basis vectors V
  Teuchos::SerialDenseMatrix<int, double> V(n,1);
  
   //Set v=r0/norm(r0) to be 1st col of V
   for (int i=0; i<n; i++){
        V(i,0)=r0(i,0);
       }
   //right hand side
   Teuchos::SerialDenseMatrix<int, double> bb(1,1);
   bb(0,0)=resid;
   Teuchos::SerialDenseMatrix<int, double> w(n,1);
   Teuchos::SerialDenseMatrix<int, double> c;
   Teuchos::SerialDenseMatrix<int, double> s;
  
   while (resid > tolerance && k < max_iter){
    
    std::cout << "k = " << k << std::endl;
    h.reshape(k+1,k);
    //Arnoldi iteration(Gram-Schmidt )
    V.reshape(n,k+1);    
    //set vk to be kth col of V
    Teuchos::SerialDenseMatrix<int, double> vk(Teuchos::Copy, V, n,1,0,k-1);
    
    w.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, A, vk, 0.0);  
    Teuchos::SerialDenseMatrix<int, double> vi(n,1);
    Teuchos::SerialDenseMatrix<int, double> ip(1,1);
    for (int i=0; i<k; i++){
       //set vi to be ith col of V
       Teuchos::SerialDenseMatrix<int, double> vi(Teuchos::Copy, V, n,1,0,i);    
       //Calculate inner product
       ip.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, vi, w, 0.0);
       h(i,k-1)= ip(0,0);
       //scale vi by h(i,k-1)
       vi.scale(ip(0,0));     
       w-=vi;
       }         
    h(k,k-1)=w.normFrobenius();     
 
    w.scale(1.0/w.normFrobenius());   
    //add column vk+1=w to V
    for (int i=0; i<n; i++){
          V(i,k)=w(i,0);
         } 
    
   //Solve upper hessenberg least squares problem via Givens rotations
   //Compute previous Givens rotations
    for (int i=0; i<k-1; i++){
     //  double hi=h(i,k-1);
     //  double hi1=h(i+1,k-1);

     // h(i,k-1)=c(i,0)*h(i,k-1)+s(i,0)*h(i+1,k-1);
     // h(i+1,k-1)=-1*s(i,0)*h(i,k-1)+c(i,0)*h(i+1,k-1);
      // h(i,k-1)=c(i,0)*hi+s(i,0)*hi1;
      // h(i+1,k-1)=-1*s(i,0)*hi+c(i,0)*hi1;   
     
     double q=c(i,0)*h(i,k-1)+s(i,0)*h(i+1,k-1);
     h(i+1,k-1)=-1*s(i,0)*h(i,k-1)+c(i,0)*h(i+1,k-1);
     h(i,k-1)=q;




     }  
     //Compute next Givens rotations
     c.reshape(k,1);
     s.reshape(k,1); 
     bb.reshape(k+1,1);
     double l = sqrt(h(k-1,k-1)*h(k-1,k-1)+h(k,k-1)*h(k,k-1));
     c(k-1,0)=h(k-1,k-1)/l;
     s(k-1,0)=h(k,k-1)/l;
     
     std::cout << "c  "  <<  c(k-1,0)<<std::endl;
     std::cout << "s "  <<  s(k-1,0)<<std::endl;

    
     // Givens rotation on h and bb
       
   //  h(k-1,k-1)=l;
     
  //  h(k,k-1)=0;
       double hk=h(k,k-1);
       double hk1=h(k-1,k-1);

      h(k-1,k-1)=c(k-1,0)*hk1+s(k-1,0)*hk;
      h(k,k-1)=-1*s(k-1,0)*hk1+c(k-1,0)*hk;

     std::cout << "l = " << l <<std::endl;
     std::cout << "h(k-1,k-1) = should be l  " << h(k-1,k-1) <<std::endl;
     std::cout << "h(k,k-1) = should be 0  " << h(k,k-1) <<std::endl;
     bb(k,0)=-1*s(k-1,0)*bb(k-1,0); 
     bb(k-1,0)=c(k-1,0)*bb(k-1,0);
     
   
    //Determine residual    
     resid =fabs(bb(k,0));
      
     std::cout << "resid = " << resid <<std::endl;
     k++;
  } 
  
  //Extract upper triangular square matrix
   bb.reshape(h.numRows()-1 ,1);
   
   //Solve linear system
   int info;
   std::cout  << "bb pre solve = " << bb << std::endl;
   std::cout << "h= " << h << std::endl;
   Teuchos::LAPACK<int, double> lapack;
   lapack.TRTRS('U', 'N', 'N', h.numRows()-1, 1, h.values(), h.stride(), bb.values(), bb.stride(),&info); 

   V.reshape(n,k-1);
   
   std::cout  << "V= " << V << std::endl;
   std::cout  << "y= " << bb << std::endl;
   X.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, V, bb, 1.0);
   std::cout << "X=  " << X << std::endl;

  


   //Check V is orthogoanl
  // Teuchos::SerialDenseMatrix<int, double> vtv(V);
  // vtv.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, V, V, 0.0);
  // std::cout << "Vtv" << vtv << std::endl;

return 0;
}
/*! \internal

    Determines the color in the color triangle at the point \a p. Uses
    linear interpolation to find the colors to the left and right of
    \a p, then uses the same technique to find the color at \a p using
    these two colors.
*/
QColor QtColorTriangle::colorFromPoint(const QPointF &p) const
{
    // Find the outer radius of the hue gradient.
    int outerRadius = (contentsRect().width() - 1) / 2;
    if ((contentsRect().height() - 1) / 2 < outerRadius)
	outerRadius = (contentsRect().height() - 1) / 2;

    // Find the center coordinates
    double cx = (double) contentsRect().center().x();
    double cy = (double) contentsRect().center().y();

    // Find the a, b and c from their angles, the center of the rect
    // and the radius of the hue gradient donut.
    QPointF pa(cx + (cos(a) * (outerRadius - (outerRadius / 5.0))),
		   cy - (sin(a) * (outerRadius - (outerRadius / 5.0))));
    QPointF pb(cx + (cos(b) * (outerRadius - (outerRadius / 5.0))),
		   cy - (sin(b) * (outerRadius - (outerRadius / 5.0))));
    QPointF pc(cx + (cos(c) * (outerRadius - (outerRadius / 5.0))),
		   cy - (sin(c) * (outerRadius - (outerRadius / 5.0))));

    // Find the hue value from the angle of the 'a' point.
    double angle = a - PI/2.0;
    if (angle < 0) angle += TWOPI;
    double hue = (360.0 * angle) / TWOPI;

    // Create the color of the 'a' corner point. We know that b is
    // black and c is white.
    QColor color;
    color.setHsv(360 - (int) floor(hue), 255, 255);

    // See also drawTrigon(), which basically does exactly the same to
    // determine all colors in the trigon.
    Vertex aa(color, pa);
    Vertex bb(Qt::black, pb);
    Vertex cc(Qt::white, pc);

    // Make sure p1 is above p2, which is above p3.
    Vertex *p1 = &aa;
    Vertex *p2 = &bb;
    Vertex *p3 = &cc;
    if (p1->point.y() > p2->point.y()) swap(&p1, &p2);
    if (p1->point.y() > p3->point.y()) swap(&p1, &p3);
    if (p2->point.y() > p3->point.y()) swap(&p2, &p3);

    // Find the slopes of all edges in the trigon. All the three y
    // deltas here are positive because of the above sorting.
    double p1p2ydist = p2->point.y() - p1->point.y();
    double p1p3ydist = p3->point.y() - p1->point.y();
    double p2p3ydist = p3->point.y() - p2->point.y();
    double p1p2xdist = p2->point.x() - p1->point.x();
    double p1p3xdist = p3->point.x() - p1->point.x();
    double p2p3xdist = p3->point.x() - p2->point.x();

    // The first x delta decides wether we have a lefty or a righty
    // trigon. A lefty trigon has its tallest edge on the right hand
    // side of the trigon. The righty trigon has it on its left side.
    // This property determines wether the left or the right set of x
    // coordinates will be continuous.
    bool lefty = p1p2xdist < 0;

    // Find whether the selector's y is in the first or second shorty,
    // counting from the top and downwards. This is used to find the
    // color at the selector point.
    bool firstshorty = (p.y() >= p1->point.y() && p.y() < p2->point.y());

    // From the y value of the selector's position, find the left and
    // right x values.
    double leftx;
    double rightx;
    if (lefty) {
        if (firstshorty) {
            leftx = p1->point.x();
            if (floor(p1p2ydist) != 0.0) {
                leftx += (p1p2xdist * (p.y() - p1->point.y())) / p1p2ydist;
            } else {
                leftx = qMin(p1->point.x(), p2->point.x());
            }
        } else {
            leftx = p2->point.x();
            if (floor(p2p3ydist) != 0.0) {
                leftx += (p2p3xdist * (p.y() - p2->point.y())) / p2p3ydist;
            } else {
                leftx = qMin(p2->point.x(), p3->point.x());
            }
        }

        rightx = p1->point.x();
        rightx += (p1p3xdist * (p.y() - p1->point.y())) / p1p3ydist;
    } else {
        leftx = p1->point.x();
        leftx += (p1p3xdist * (p.y() - p1->point.y())) / p1p3ydist;

        if (firstshorty) {
            rightx = p1->point.x();
            if (floor(p1p2ydist) != 0.0) {
                rightx += (p1p2xdist * (p.y() - p1->point.y())) / p1p2ydist;
            } else {
                rightx = qMax(p1->point.x(), p2->point.x());
            }
        } else {
            rightx = p2->point.x(); 
            if (floor(p2p3ydist) != 0.0) {
                rightx += (p2p3xdist * (p.y() - p2->point.y())) / p2p3ydist;
            } else {
                rightx = qMax(p2->point.x(), p3->point.x());
            }
        }
    }

    // Find the r,g,b values of the points on the trigon's edges that
    // are to the left and right of the selector.
    double rshort = 0, gshort = 0, bshort = 0;
    double rlong = 0, glong = 0, blong = 0;
    if (firstshorty) {
        if (floor(p1p2ydist) != 0.0) {
            rshort  = p2->color.r * (p.y() - p1->point.y()) / p1p2ydist;
            gshort  = p2->color.g * (p.y() - p1->point.y()) / p1p2ydist;
            bshort  = p2->color.b * (p.y() - p1->point.y()) / p1p2ydist;
            rshort += p1->color.r * (p2->point.y() - p.y()) / p1p2ydist;
            gshort += p1->color.g * (p2->point.y() - p.y()) / p1p2ydist;
            bshort += p1->color.b * (p2->point.y() - p.y()) / p1p2ydist;
        } else {
            if (lefty) {
                if (p1->point.x() <= p2->point.x()) {
                    rshort  = p1->color.r;
                    gshort  = p1->color.g;
                    bshort  = p1->color.b;
                } else {
                    rshort  = p2->color.r;
                    gshort  = p2->color.g;
                    bshort  = p2->color.b;
                }
            } else {
                if (p1->point.x() > p2->point.x()) {
                    rshort  = p1->color.r;
                    gshort  = p1->color.g;
                    bshort  = p1->color.b;
                } else {
                    rshort  = p2->color.r;
                    gshort  = p2->color.g;
                    bshort  = p2->color.b;
                }
            }
        }
    } else {
        if (floor(p2p3ydist) != 0.0) {
            rshort  = p3->color.r * (p.y() - p2->point.y()) / p2p3ydist;
            gshort  = p3->color.g * (p.y() - p2->point.y()) / p2p3ydist;
            bshort  = p3->color.b * (p.y() - p2->point.y()) / p2p3ydist;
            rshort += p2->color.r * (p3->point.y() - p.y()) / p2p3ydist;
            gshort += p2->color.g * (p3->point.y() - p.y()) / p2p3ydist;
            bshort += p2->color.b * (p3->point.y() - p.y()) / p2p3ydist;
        } else {
            if (lefty) {
                if (p2->point.x() <= p3->point.x()) {
                    rshort  = p2->color.r;
                    gshort  = p2->color.g;
                    bshort  = p2->color.b;
                } else {
                    rshort  = p3->color.r;
                    gshort  = p3->color.g;
                    bshort  = p3->color.b;
                }
            } else {
                if (p2->point.x() > p3->point.x()) {
                    rshort  = p2->color.r;
                    gshort  = p2->color.g;
                    bshort  = p2->color.b;
                } else {
                    rshort  = p3->color.r;
                    gshort  = p3->color.g;
                    bshort  = p3->color.b;
                }
            }
        }
    }

    // p1p3ydist is never 0
    rlong  = p3->color.r * (p.y() - p1->point.y()) / p1p3ydist;
    glong  = p3->color.g * (p.y() - p1->point.y()) / p1p3ydist;
    blong  = p3->color.b * (p.y() - p1->point.y()) / p1p3ydist;
    rlong += p1->color.r * (p3->point.y() - p.y()) / p1p3ydist;
    glong += p1->color.g * (p3->point.y() - p.y()) / p1p3ydist;
    blong += p1->color.b * (p3->point.y() - p.y()) / p1p3ydist;

    // rshort,gshort,bshort is the color on one of the shortys.
    // rlong,glong,blong is the color on the longy. So depending on
    // wether we have a lefty trigon or not, we can determine which
    // colors are on the left and right edge.
    double rl, gl, bl, rr, gr, br;
    if (lefty) {
	rl = rshort; gl = gshort; bl = bshort;
	rr = rlong; gr = glong; br = blong;
    } else {
	rl = rlong; gl = glong; bl = blong;
	rr = rshort; gr = gshort; br = bshort;
    }

    // Find the distance from the left x to the right x (xdist). Then
    // find the distances from the selector to each of these (saxdist
    // and saxdist2). These distances are used to find the color at
    // the selector.
    double xdist = rightx - leftx;
    double saxdist = p.x() - leftx;
    double saxdist2 = xdist - saxdist;

    // Now determine the r,g,b values of the selector using a linear
    // approximation.
    double r, g, b;
    if (xdist != 0.0) {
	r = (saxdist2 * rl / xdist) + (saxdist * rr / xdist);
	g = (saxdist2 * gl / xdist) + (saxdist * gr / xdist);
	b = (saxdist2 * bl / xdist) + (saxdist * br / xdist);
    } else {
	// In theory, the left and right color will be equal here. But
	// because of the loss of precision, we get an error on both
	// colors. The best approximation we can get is from adding
	// the two errors, which in theory will eliminate the error
	// but in practise will only minimize it.
	r = (rl + rr) / 2;
        g = (gl + gr) / 2;
	b = (bl + br) / 2;
    }

    // Now floor the color components and fit them into proper
    // boundaries. This again is to compensate for the error caused by
    // loss of precision.
    int ri = (int) floor(r);
    int gi = (int) floor(g);
    int bi = (int) floor(b);
    if (ri < 0) ri = 0;
    else if (ri > 255) ri = 255;
    if (gi < 0) gi = 0;
    else if (gi > 255) gi = 255;
    if (bi < 0) bi = 0;
    else if (bi > 255) bi = 255;

    // Voila, we have the color at the point of the selector.
    return QColor(ri, gi, bi);
}
Exemple #30
0
 template <typename T> void serialize(const T& obj, std::string& buf)
 {
   buf.clear();
   diy::StringBuffer bb(buf);
   diy::save(bb, obj);
 }