IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Feb 11, 2011, 4:29:48 PM (15 years ago)
Author:
watersc1
Message:

Trying to merge back into trunk.

Location:
branches/czw_branch/20101203
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/czw_branch/20101203

  • branches/czw_branch/20101203/ippTools/src/magictool.c

    r29625 r30586  
    4949static bool censorrunMode(pxConfig *config);
    5050static bool exposureMode(pxConfig *config);
     51static bool setgotocleanedMode(pxConfig *config);
     52static bool tocleanupMode(pxConfig *config);
     53static bool setworkdirstateMode(pxConfig *config);
    5154
    5255static bool setmagicRunState(pxConfig *config, psS64 magic_id, const char *state, psString setString);
     
    8992        MODECASE(MAGICTOOL_MODE_CENSORRUN,           censorrunMode);
    9093        MODECASE(MAGICTOOL_MODE_EXPOSURE,            exposureMode);
     94        MODECASE(MAGICTOOL_MODE_SETGOTOCLEANED,      setgotocleanedMode);
     95        MODECASE(MAGICTOOL_MODE_TOCLEANUP,           tocleanupMode);
     96        MODECASE(MAGICTOOL_MODE_SETWORKDIRSTATE,     setworkdirstateMode);
    9197        default:
    9298            psAbort("invalid option (this should not happen)");
     
    621627    PXOPT_COPY_S64(config->args, where, "-magic_id", "magic_id", "==");
    622628    PXOPT_COPY_S16(config->args, where, "-fault", "fault", "==");
    623     PXOPT_COPY_STR(config->args, where, "-label", "label", "==");
     629    pxAddLabelSearchArgs (config, where, "-label", "magicRun.label", "==");
    624630
    625631    psString query = psStringCopy("UPDATE magicRun SET fault = 0 WHERE state = 'new' AND fault != 0");
     
    829835    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
    830836
    831     // look for "inputs" that need to processed
    832     psString query = pxDataGet("magictool_toprocess_inputs.sql");
    833     if (!query) {
    834         psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
    835         return false;
    836     }
    837 
    838837    psString whereString = NULL;
    839838    if (psListLength(where->list)) {
     
    844843    psFree(where);
    845844
    846     psStringAppend(&query, "\nORDER BY priority DESC, magic_id");
    847 
    848     // treat limit == 0 as "no limit"
    849     if (limit) {
    850         // cut limit in half
    851         // hack to prevent pending leaf nodes from blocking branch nodes
    852         psString limitString = psDBGenerateLimitSQL((limit + 1) / 2);
    853         psStringAppend(&query, " %s", limitString);
    854         psFree(limitString);
    855     }
    856 
    857     if (!p_psDBRunQueryF(config->dbh, query, whereString, whereString)) {
    858         psError(PS_ERR_UNKNOWN, false, "database error");
    859         psFree(whereString);
    860         psFree(query);
    861         return false;
    862     }
    863     psFree(query);
    864 
    865     psArray *output = p_psDBFetchResult(config->dbh);
    866     if (!output) {
    867         psErrorCode err = psErrorCodeLast();
    868         switch (err) {
    869             case PS_ERR_DB_CLIENT:
    870                 psError(PXTOOLS_ERR_SYS, false, "database error");
    871             case PS_ERR_DB_SERVER:
    872                 psError(PXTOOLS_ERR_PROG, false, "database error");
    873             default:
    874                 psError(PXTOOLS_ERR_PROG, false, "unknown error");
    875         }
    876 
    877         return false;
    878     }
    879     if (!psArrayLength(output)) {
    880         psTrace("magictool", PS_LOG_INFO, "no rows found");
    881     }
    882 
    883     if (limit) {
    884         if (psArrayLength(output) >= limit) {
    885             // we've found enough (note that limit was applied to the query so '> limit' won't happen)
    886             // negative simple so the default is true
    887             if (!ippdbPrintMetadatas(stdout, output, "magicMe", !simple)) {
    888                 psError(PS_ERR_UNKNOWN, false, "failed to print array");
    889                 psFree(output);
    890                 return false;
    891             }
    892             psFree(output);
    893             return true;
    894         }
    895     }
    896 
    897     // look for tree nodes that need to be processed
     845    // First look for branch nodes that need to be processed.
     846    // These get priority over skycells because they are from runs
     847    // that are already in progress and there are fewer of them.
     848    // When we looked for skycells first we got starved.
    898849
    899850    // first find incomplete magicRuns
    900     query = pxDataGet("magictool_toprocess_runs.sql");
     851    psString query = pxDataGet("magictool_toprocess_runs.sql");
    901852    if (!query) {
    902853        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     
    904855    }
    905856
    906     // we limit the query even though it is cheap (only magic_id is selected)
    907 
    908     // XXX: if the first 1000 unfinished magicRuns have no ready nodes
    909     // that haven't faulted, later runs won't get returned even though
    910     // they have work to do. When we used a limit of 100 we actually ran
    911     // into this problem. Since we're using labels a limit of 1000 will
    912     // probably be ok.
     857    // Find outstanding magicRuns in new state.
     858    // We limit the query, but this is problematic. In practice do
     859    // we need to?
     860    // XXX: If the first 1000 magicRuns have no branch nodes ready
     861    // but higher runs do we they won't be noticed.
     862    // Perhaps have this limit be an argument.
    913863    {
    914864        psString limitString = psDBGenerateLimitSQL( 1000 );
     
    940890        return false;
    941891    }
     892
    942893    if (!psArrayLength(magicRuns)) {
     894        // no pending magicRuns nothing to do
    943895        psTrace("magictool", PS_LOG_INFO, "no rows found");
    944         psFree(magicRuns);
    945896        return true;
    946897    }
    947 
    948     query = pxDataGet("magictool_toprocess_tree.sql");
     898    psArray *output = psArrayAllocEmpty(100);
     899
     900    {
     901        query = pxDataGet("magictool_toprocess_tree.sql");
     902        if (!query) {
     903            psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     904            return false;
     905        }
     906
     907        for (psS64 index = 0; index < psArrayLength(magicRuns); index++) {
     908            if (limit && (psArrayLength(output) >= limit)) {
     909                break;
     910            }
     911            bool status;
     912            psS64 magic_id = psMetadataLookupS64(&status, magicRuns->data[index], "magic_id");
     913            if (!status) {
     914                psAbort("failed to lookup value for magic_id column");
     915            }
     916
     917            whereString = NULL;
     918            psStringAppend(&whereString, "\nAND (magic_id = %" PRId64 ")", magic_id);
     919            if (!p_psDBRunQueryF(config->dbh, query, whereString )) {
     920                psError(PS_ERR_UNKNOWN, false, "database error");
     921                psFree(whereString);
     922                psFree(query);
     923                return false;
     924            }
     925            psFree(whereString);
     926            psArray *magicTree = p_psDBFetchResult(config->dbh);
     927            if (!magicTree) {
     928                psErrorCode err = psErrorCodeLast();
     929                switch (err) {
     930                    case PS_ERR_DB_CLIENT:
     931                        psError(PXTOOLS_ERR_SYS, false, "database error");
     932                    case PS_ERR_DB_SERVER:
     933                        psError(PXTOOLS_ERR_PROG, false, "database error");
     934                    default:
     935                        psError(PXTOOLS_ERR_PROG, false, "unknown error");
     936                }
     937
     938                return false;
     939            }
     940            psS64 length = psArrayLength(magicTree);
     941            if (!length) {
     942                psTrace("magictool", PS_LOG_INFO, "no rows found for magic_id %" PRId64, magic_id);
     943                psFree(magicTree);
     944                continue;
     945            }
     946
     947            psHash *forest = psHashAlloc(length);
     948
     949            // convert the array of metadata into a pxTree structure
     950            for (long i = 0; i < length; i++) {
     951                bool status;
     952                psString node = psMetadataLookupStr(&status, magicTree->data[i], "node");
     953                if (!status) {
     954                    psAbort("failed to lookup value for node column");
     955                }
     956
     957                psString dep = psMetadataLookupStr(&status, magicTree->data[i], "dep");
     958                if (!status) {
     959                    psAbort("failed to lookup value for dep column");
     960                }
     961
     962                pxTreeBuilder(forest, node, dep, magicTree->data[i]);
     963
     964            }
     965
     966            // find the root of the tree
     967            pxNode *root = psMemIncrRefCounter(psHashLookup(forest, "root"));
     968            psFree(forest);
     969            //    pxTreePrint(stdout, root);
     970
     971            // crawl through the tree and looking for nodes with children that are all
     972            // "done"
     973            pxTreeCrawl(root, findReadyNodes, output);
     974            psFree(root);
     975            psFree(magicTree);
     976        }
     977
     978        int len = psArrayLength(output);
     979        if (len) {
     980            if (limit) {
     981                if (limit < psArrayLength(output)) {
     982                    // truncate the array
     983                    long arrayLength = psArrayLength(output);
     984                    for (long i = arrayLength - 1; i >= limit; i--) {
     985                        psArrayRemoveIndex(output, i);
     986                    }
     987                    // negative simple so the default is true
     988                    if (!ippdbPrintMetadatas(stdout, output, "magicMe", !simple)) {
     989                        psError(PS_ERR_UNKNOWN, false, "failed to print array");
     990                        psFree(output);
     991                        return false;
     992                    }
     993                    psFree(output);
     994                    return true;
     995                } else {
     996                    limit -= len;
     997                }
     998            }
     999        }
     1000    }
     1001
     1002    // look for "inputs" (skycells) that need to processed
     1003    query = pxDataGet("magictool_toprocess_inputs.sql");
    9491004    if (!query) {
    9501005        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     
    9521007    }
    9531008
    954     for (psS64 index = 0; index < psArrayLength(magicRuns); index++) {
    955         if (limit && (psArrayLength(output) >= limit)) {
    956             break;
    957         }
    958         bool status;
    959         psS64 magic_id = psMetadataLookupS64(&status, magicRuns->data[index], "magic_id");
    960         if (!status) {
    961             psAbort("failed to lookup value for magic_id column");
    962         }
    963 
    964         whereString = NULL;
    965         psStringAppend(&whereString, "\nAND (magic_id = %" PRId64 ")", magic_id);
    966         if (!p_psDBRunQueryF(config->dbh, query, whereString )) {
    967             psError(PS_ERR_UNKNOWN, false, "database error");
    968             psFree(whereString);
    969             psFree(query);
    970             return false;
    971         }
     1009    psStringAppend(&query, "\nORDER BY priority DESC, magic_id");
     1010
     1011    // treat limit == 0 as "no limit"
     1012    if (limit) {
     1013        psString limitString = psDBGenerateLimitSQL(limit);
     1014        psStringAppend(&query, " %s", limitString);
     1015        psFree(limitString);
     1016    }
     1017
     1018    if (!p_psDBRunQueryF(config->dbh, query, whereString, whereString)) {
     1019        psError(PS_ERR_UNKNOWN, false, "database error");
    9721020        psFree(whereString);
    973         psArray *magicTree = p_psDBFetchResult(config->dbh);
    974         if (!magicTree) {
    975             psErrorCode err = psErrorCodeLast();
    976             switch (err) {
    977                 case PS_ERR_DB_CLIENT:
    978                     psError(PXTOOLS_ERR_SYS, false, "database error");
    979                 case PS_ERR_DB_SERVER:
    980                     psError(PXTOOLS_ERR_PROG, false, "database error");
    981                 default:
    982                     psError(PXTOOLS_ERR_PROG, false, "unknown error");
    983             }
    984 
    985             return false;
    986         }
    987         psS64 length = psArrayLength(magicTree);
    988         if (!length) {
    989             psTrace("magictool", PS_LOG_INFO, "no rows found for magic_id %" PRId64, magic_id);
    990             psFree(magicTree);
    991             continue;
    992         }
    993 
    994         psHash *forest = psHashAlloc(length);
    995 
    996         // convert the array of metadata into a pxTree structure
    997         for (long i = 0; i < length; i++) {
    998             bool status;
    999             psString node = psMetadataLookupStr(&status, magicTree->data[i], "node");
    1000             if (!status) {
    1001                 psAbort("failed to lookup value for node column");
    1002             }
    1003 
    1004             psString dep = psMetadataLookupStr(&status, magicTree->data[i], "dep");
    1005             if (!status) {
    1006                 psAbort("failed to lookup value for dep column");
    1007             }
    1008 
    1009             pxTreeBuilder(forest, node, dep, magicTree->data[i]);
    1010 
    1011         }
    1012 
    1013         // find the root of the tree
    1014         pxNode *root = psMemIncrRefCounter(psHashLookup(forest, "root"));
    1015         psFree(forest);
    1016         //    pxTreePrint(stdout, root);
    1017 
    1018         // crawl through the tree and looking for nodes with children that are all
    1019         // "done"
    1020         pxTreeCrawl(root, findReadyNodes, output);
    1021         psFree(root);
    1022         psFree(magicTree);
    1023     }
    1024 
     1021        psFree(query);
     1022        return false;
     1023    }
     1024    psFree(query);
     1025
     1026    psArray *skycellOutput = p_psDBFetchResult(config->dbh);
     1027    if (!skycellOutput) {
     1028        psErrorCode err = psErrorCodeLast();
     1029        switch (err) {
     1030            case PS_ERR_DB_CLIENT:
     1031                psError(PXTOOLS_ERR_SYS, false, "database error");
     1032            case PS_ERR_DB_SERVER:
     1033                psError(PXTOOLS_ERR_PROG, false, "database error");
     1034            default:
     1035                psError(PXTOOLS_ERR_PROG, false, "unknown error");
     1036        }
     1037
     1038        return false;
     1039    }
     1040    // merge the arrays so that we can print them all at once
     1041    if (psArrayLength(skycellOutput)) {
     1042        int len = psArrayLength(skycellOutput);
     1043        for (int i=0; i < len; i++) {
     1044            psArrayAdd(output, 0, skycellOutput->data[i]);
     1045        }
     1046    }
     1047    psFree(skycellOutput);
    10251048    if (psArrayLength(output)) {
    1026         if (limit && (limit < psArrayLength(output))) {
    1027             // truncate the array
    1028             long arrayLength = psArrayLength(output);
    1029             for (long i = arrayLength - 1; i >= limit; i--) {
    1030                 psArrayRemoveIndex(output, i);
    1031             }
    1032         }
    1033         // negative simple so the default is true
    10341049        if (!ippdbPrintMetadatas(stdout, output, "magicMe", !simple)) {
    10351050            psError(PS_ERR_UNKNOWN, false, "failed to print array");
     
    10371052            return false;
    10381053        }
    1039     }
    1040 
     1054    } else {
     1055        psTrace("magictool", PS_LOG_INFO, "no rows found");
     1056    }
    10411057    psFree(output);
    1042 
    10431058    return true;
    10441059}
     
    16221637    return true;
    16231638}
     1639static bool setgotocleanedMode(pxConfig *config)
     1640{
     1641    PS_ASSERT_PTR_NON_NULL(config, false);
     1642
     1643    psMetadata *where = psMetadataAlloc();
     1644    PXOPT_COPY_S64(config->args, where, "-magic_id", "magicRun.magic_id", "==");
     1645    PXOPT_COPY_S64(config->args, where, "-exp_id", "magicRun.exp_id", "==");
     1646    PXOPT_COPY_STR(config->args, where, "-label", "magicRun.label", "LIKE");
     1647    PXOPT_COPY_STR(config->args, where, "-data_group", "magicRun.data_group", "LIKE");
     1648
     1649    PXOPT_LOOKUP_STR(set_label, config->args, "-set_label", false, false);
     1650
     1651    psString query = psStringCopy("UPDATE magicRun SET workdir_state = 'goto_cleaned'\n");
     1652    if (set_label) {
     1653        psStringAppend(&query, ", label = '%s'", set_label);
     1654    }
     1655    // This mode doubles as a revert function for cleanup errors
     1656    PXOPT_LOOKUP_BOOL(clearfault, config->args, "-clearfault", false);
     1657    if (!clearfault) {
     1658        psStringAppend(&query, "WHERE workdir_state = 'dirty'");
     1659    } else {
     1660        psStringAppend(&query, "WHERE workdir_state = 'error_cleaned'");
     1661    }
     1662    psStringAppend(&query, "\nAND (magicRun.state = 'full' OR magicRun.state = 'drop')");
     1663
     1664    // Require search parameters unless we're just clearing faults
     1665    if (psListLength(where->list)) {
     1666        psString clause = psDBGenerateWhereConditionSQL(where, NULL);
     1667        psStringAppend(&query, "\nAND %s", clause);
     1668        psFree(clause);
     1669        psFree(where);
     1670    } else if ( !clearfault) {
     1671        psError(PS_ERR_UNKNOWN, false, "search parameters are required");
     1672        psFree(where);
     1673        return false;
     1674    }
     1675
     1676    if (!p_psDBRunQuery(config->dbh, query)) {
     1677        psError(PS_ERR_UNKNOWN, false, "database error");
     1678        psFree(query);
     1679        return false;
     1680    }
     1681    psFree(query);
     1682
     1683    return true;
     1684}
     1685
     1686static bool setworkdirstateMode(pxConfig *config)
     1687{
     1688    PS_ASSERT_PTR_NON_NULL(config, false);
     1689
     1690    // required
     1691    PXOPT_LOOKUP_S64(magic_id, config->args, "-magic_id", true, false);
     1692    PXOPT_LOOKUP_STR(workdir_state, config->args, "-set_workdir_state", true, false);
     1693
     1694    if (strcmp(workdir_state, "cleaned") && strcmp(workdir_state, "error_cleaned")) {
     1695        psError(PS_ERR_UNKNOWN, true, "%s is not a valid value for workdir_state", workdir_state);
     1696        return false;
     1697    }
     1698   
     1699    psString query = NULL;
     1700    psStringAppend(&query, "UPDATE magicRun SET workdir_state = '%s' WHERE magic_id = %" PRId64, workdir_state, magic_id);
     1701
     1702    if (!p_psDBRunQuery(config->dbh, query)) {
     1703        psError(PS_ERR_UNKNOWN, false, "database error");
     1704        psFree(query);
     1705        return false;
     1706    }
     1707    psFree(query);
     1708
     1709    return true;
     1710}
     1711static bool tocleanupMode(pxConfig *config)
     1712{
     1713    PS_ASSERT_PTR_NON_NULL(config, false);
     1714
     1715    psMetadata *where = psMetadataAlloc();
     1716    PXOPT_COPY_S64(config->args, where, "-magic_id", "magicRun.magic_id", "==");
     1717    pxAddLabelSearchArgs (config, where, "-label", "magicRun.label", "==");
     1718    pxAddLabelSearchArgs (config, where, "-data_group", "magicRun.data_group", "==");
     1719
     1720    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
     1721    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
     1722
     1723    psString query = pxDataGet("magictool_tocleanup.sql");
     1724    if (!query) {
     1725        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     1726        return false;
     1727    }
     1728
     1729    if (psListLength(where->list)) {
     1730        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     1731        psStringAppend(&query, " AND %s", whereClause);
     1732        psFree(whereClause);
     1733    }
     1734    psFree(where);
     1735
     1736    psStringAppend(&query, "\nORDER BY priority DESC, magic_id");
     1737
     1738    // treat limit == 0 as "no limit"
     1739    if (limit) {
     1740        psString limitString = psDBGenerateLimitSQL(limit);
     1741        psStringAppend(&query, " %s", limitString);
     1742        psFree(limitString);
     1743    }
     1744
     1745    if (!p_psDBRunQuery(config->dbh, query)) {
     1746        psError(PS_ERR_UNKNOWN, false, "database error");
     1747        psFree(query);
     1748        return false;
     1749    }
     1750    psFree(query);
     1751
     1752    psArray *output = p_psDBFetchResult(config->dbh);
     1753    if (!output) {
     1754        psErrorCode err = psErrorCodeLast();
     1755        switch (err) {
     1756            case PS_ERR_DB_CLIENT:
     1757                psError(PXTOOLS_ERR_SYS, false, "database error");
     1758            case PS_ERR_DB_SERVER:
     1759                psError(PXTOOLS_ERR_PROG, false, "database error");
     1760            default:
     1761                psError(PXTOOLS_ERR_PROG, false, "unknown error");
     1762        }
     1763
     1764        return false;
     1765    }
     1766    if (!psArrayLength(output)) {
     1767        psTrace("magictool", PS_LOG_INFO, "no rows found");
     1768        psFree(output);
     1769        return true;
     1770    }
     1771
     1772    if (psArrayLength(output)) {
     1773        // negative simple so the default is true
     1774        if (!ippdbPrintMetadatas(stdout, output, "tocleanup", !simple)) {
     1775            psError(PS_ERR_UNKNOWN, false, "failed to print array");
     1776            psFree(output);
     1777            return false;
     1778        }
     1779    }
     1780
     1781    psFree(output);
     1782
     1783    return true;
     1784}
Note: See TracChangeset for help on using the changeset viewer.