コード例 #1
0
// Return the specified queue of the specified input group.
static InputQueue &
queue(int igroup_id, InputQueueName qn)
{
    InputGroup *ig = igroup(igroup_id);
    if (!ig)
        throw Exception("input group "+StringUtility::numberToString(igroup_id)+" does not exist");
    return ig->queue(qn);
}
コード例 #2
0
int
main(int argc, char *argv[])
{
    std::ios::sync_with_stdio();
    argv0 = argv[0];
    {
        size_t slash = argv0.rfind('/');
        argv0 = slash==std::string::npos ? argv0 : argv0.substr(slash+1);
        if (0==argv0.substr(0, 3).compare("lt-"))
            argv0 = argv0.substr(3);
    }

    // Parse switches
    Switches opt;
    int argno = 1, ngenerators = 0;
    for (/*void*/; argno<argc && '-'==argv[argno][0]; ++argno) {
        if (!strcmp(argv[argno], "--")) {
            ++argno;
            break;
        } else if (!strcmp(argv[argno], "--help") || !strcmp(argv[argno], "-h")) {
            usage(0);
        } else if (!strncmp(argv[argno], "--ngroups=", 10)) {
            opt.ngroups = strtoul(argv[argno]+10, NULL, 0);
            opt.ngroups_set = true;
        } else if (!strcmp(argv[argno], "--collection")) {
            opt.single_collection = true;
        } else if (!strncmp(argv[argno], "--collection=", 13)) {
            opt.collection_id = strtoul(argv[argno]+13, NULL, 0);
            opt.collection_id_set = opt.single_collection = true;
        } else if (!strncmp(argv[argno], "--default=", 10)) {
            opt.default_queue = parse_queuename(argv[argno]+10);
        } else if (!strcmp(argv[argno], "--memhash") || !strncmp(argv[argno], "--memhash=", 10)) {
            std::string s;
            if (char *equal = strchr(argv[argno], '='))
                s = equal+1;
            std::vector<std::string> valargs = StringUtility::split(',', s, 3);
            valargs.resize(3);
            if (valargs[0].empty())
                valargs[0] = "0";
            if (valargs[1].empty())
                valargs[1] = "255";
            std::vector<std::string> randargs(1, "1");
            randargs.push_back(valargs[2]);
            valargs.pop_back();
            opt.queue_modifiers.push_back(new ValuesGenerator(IQ_MEMHASH, valargs));
            opt.queue_modifiers.push_back(new RandomGenerator(IQ_MEMHASH, randargs));
            ++ngenerators;
        } else {
            std::cerr <<argv0 <<": unrecognized switch: " <<argv[argno] <<"\n"
                      <<"see \"" <<argv0 <<" --help\" for usage info.\n";
            exit(1);
        }
    }
    if (!opt.ngroups_set) {
        std::cerr <<argv0 <<": missing --ngroups switch\n"
                  <<argv0 <<": see --help for more info\n";
        exit(1);
    }

    // Parse non-switch arguments (allow the database connection string to appear anywhere in this list since simplifies
    // the run-analysis.sh script.
    for (/*void*/; argno<argc; argno++) {
        std::vector<std::string> colon_parts = StringUtility::split(':', argv[argno], 2);
        InputQueueName qn = parse_queuename(colon_parts[0]);
        if (IQ_NONE!=qn && 2==colon_parts.size()) {
            std::vector<std::string> equal_parts = StringUtility::split('=', colon_parts[1], 2);
            std::string gname = equal_parts[0];
            std::vector<std::string> args;
            try {
                if (2==equal_parts.size())
                    args = StringUtility::split(',', equal_parts[1], (size_t)-1, true);
                if (0==gname.compare("values")) {
                    opt.queue_modifiers.push_back(new ValuesGenerator(qn, args));
                } else if (0==gname.compare("set") || 0==gname.compare("reset")) {
                    opt.queue_modifiers.push_back(new ResetGenerator(qn, args));
                } else if (0==gname.compare("pad")) {
                    opt.queue_modifiers.push_back(new PaddingGenerator(qn, args));
                    ++ngenerators;
                } else if (0==gname.compare("random")) {
                    opt.queue_modifiers.push_back(new RandomGenerator(qn, args));
                    ++ngenerators;
                } else if (0==gname.compare("copy")) {
                    opt.queue_modifiers.push_back(new CopyGenerator(qn, args));
                    ++ngenerators;
                } else if (0==gname.compare("permute")) {
                    opt.queue_modifiers.push_back(new PermuteFilter(qn, args));
                } else if (0==gname.compare("shuffle")) {
                    opt.queue_modifiers.push_back(new ShuffleFilter(qn, args));
                } else if (0==gname.compare("redirect")) {
                    opt.queue_modifiers.push_back(new RedirectFilter(qn, args));
                } else {
                    std::cerr <<argv0 <<": unknown generator or filter name: " <<gname <<"\n";
                    exit(1);
                }
            } catch (const Exception &e) {
                std::cerr <<argv0 <<": " <<argv[argno] <<": " <<e <<"\n";
                exit(1);
            }
        } else if (transaction==NULL) {
            transaction = SqlDatabase::Connection::create(argv[argno])->transaction();
        } else {
            std::cerr <<argv0 <<": unknown generator or filter: " <<argv[argno] <<"\n";
            exit(1);
        }
    }
    if (transaction==NULL) {
        std::cerr <<argv0 <<": missing database URL\n"
                  <<argv0 <<": see --help for more info\n";
        exit(1);
    }
    if (opt.queue_modifiers.empty()) {
        if (opt.ngroups>0) {
            std::cerr <<argv0 <<": no generators specified; all input groups would be empty\n";
            exit(1);
        } else {
            exit(0);
        }
    }

    // Get the list of queues that are affected.
    std::vector<int> queue_modified(IQ_NQUEUES, 0);
    for (size_t i=0; i<opt.queue_modifiers.size(); ++i)
        queue_modified[opt.queue_modifiers[i]->queuename] = 1;

    // Generate the inputs
    int64_t cmd_id = start_command(transaction, argc, argv, "generating input groups");
    int first_id = transaction->statement("select coalesce(max(igroup_id),-1)+1 from semantic_inputvalues")->execute_int();
    if (!opt.collection_id_set)
        opt.collection_id = first_id;
    Progress progress(opt.ngroups);
    for (size_t gi=0; gi<opt.ngroups; ++gi) {
        ++progress;
        int igroup_id = first_id + gi;
        InputGroup igroup;
        igroup.set_collection_id(opt.single_collection ? opt.collection_id : igroup_id);

        // All queues initialize redirect to the default queue.  If any generator or filter is applied, then
        // we don't do the default redirect.
        for (size_t qi=0; qi<IQ_NQUEUES; ++qi) {
            if (!queue_modified[qi])
                igroup.queue((InputQueueName)qi).redirect(opt.default_queue);
        }

        // Build the queues
        for (size_t qmi=0; qmi<opt.queue_modifiers.size(); ++qmi) {
            QueueModifier *qm = opt.queue_modifiers[qmi];
            qm->reseed(igroup_id);
            InputQueue &q = igroup.queue(qm->queuename);
            qm->operator()(q, igroup_id);
        }

        // Save all queues
        igroup.save(transaction, igroup_id, cmd_id);
    }
    progress.clear();

    std::string desc = "generated "+StringUtility::numberToString(opt.ngroups)+" input group"+(1==opt.ngroups?"":"s")+
                       " starting at "+StringUtility::numberToString(first_id);
    if (opt.ngroups>0) {
        finish_command(transaction, cmd_id, desc);
        transaction->commit();
    }

    std::cerr <<argv0 <<": " <<desc <<"\n";
    return 0;
}