IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 30388


Ignore:
Timestamp:
Jan 27, 2011, 9:48:14 AM (15 years ago)
Author:
bills
Message:

in magictool -toprocess reverse the order of the queries. First look for branch nodes
then query for skycells. The reverse order caused problems when there are a lot of
magicRuns outstanding

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ippTools/src/magictool.c

    r30374 r30388  
    835835    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
    836836
    837     // look for "inputs" that need to processed
    838     psString query = pxDataGet("magictool_toprocess_inputs.sql");
    839     if (!query) {
    840         psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
    841         return false;
    842     }
    843 
    844837    psString whereString = NULL;
    845838    if (psListLength(where->list)) {
     
    850843    psFree(where);
    851844
    852     psStringAppend(&query, "\nORDER BY priority DESC, magic_id");
    853 
    854     // treat limit == 0 as "no limit"
    855     if (limit) {
    856         // cut limit in half
    857         // hack to prevent pending leaf nodes from blocking branch nodes
    858         psString limitString = psDBGenerateLimitSQL((limit + 1) / 2);
    859         psStringAppend(&query, " %s", limitString);
    860         psFree(limitString);
    861     }
    862 
    863     if (!p_psDBRunQueryF(config->dbh, query, whereString, whereString)) {
    864         psError(PS_ERR_UNKNOWN, false, "database error");
    865         psFree(whereString);
    866         psFree(query);
    867         return false;
    868     }
    869     psFree(query);
    870 
    871     psArray *output = p_psDBFetchResult(config->dbh);
    872     if (!output) {
    873         psErrorCode err = psErrorCodeLast();
    874         switch (err) {
    875             case PS_ERR_DB_CLIENT:
    876                 psError(PXTOOLS_ERR_SYS, false, "database error");
    877             case PS_ERR_DB_SERVER:
    878                 psError(PXTOOLS_ERR_PROG, false, "database error");
    879             default:
    880                 psError(PXTOOLS_ERR_PROG, false, "unknown error");
    881         }
    882 
    883         return false;
    884     }
    885     if (!psArrayLength(output)) {
    886         psTrace("magictool", PS_LOG_INFO, "no rows found");
    887     }
    888 
    889     if (limit) {
    890         if (psArrayLength(output) >= limit) {
    891             // we've found enough (note that limit was applied to the query so '> limit' won't happen)
    892             // negative simple so the default is true
    893             if (!ippdbPrintMetadatas(stdout, output, "magicMe", !simple)) {
    894                 psError(PS_ERR_UNKNOWN, false, "failed to print array");
    895                 psFree(output);
    896                 return false;
    897             }
    898             psFree(output);
    899             return true;
    900         }
    901     }
    902 
    903     // 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.
    904849
    905850    // first find incomplete magicRuns
    906     query = pxDataGet("magictool_toprocess_runs.sql");
     851    psString query = pxDataGet("magictool_toprocess_runs.sql");
    907852    if (!query) {
    908853        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     
    910855    }
    911856
    912     // we limit the query even though it is cheap (only magic_id is selected)
    913 
    914     // XXX: if the first 1000 unfinished magicRuns have no ready nodes
    915     // that haven't faulted, later runs won't get returned even though
    916     // they have work to do. When we used a limit of 100 we actually ran
    917     // into this problem. Since we're using labels a limit of 1000 will
    918     // 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.
    919863    {
    920864        psString limitString = psDBGenerateLimitSQL( 1000 );
     
    946890        return false;
    947891    }
    948     if (!psArrayLength(magicRuns)) {
    949         psTrace("magictool", PS_LOG_INFO, "no rows found");
    950         psFree(magicRuns);
    951         return true;
    952     }
    953 
    954     query = pxDataGet("magictool_toprocess_tree.sql");
     892    psArray *output = NULL;
     893    if (psArrayLength(magicRuns)) {
     894        output = psArrayAllocEmpty(100);
     895
     896        query = pxDataGet("magictool_toprocess_tree.sql");
     897        if (!query) {
     898            psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     899            return false;
     900        }
     901
     902        for (psS64 index = 0; index < psArrayLength(magicRuns); index++) {
     903            if (limit && (psArrayLength(output) >= limit)) {
     904                break;
     905            }
     906            bool status;
     907            psS64 magic_id = psMetadataLookupS64(&status, magicRuns->data[index], "magic_id");
     908            if (!status) {
     909                psAbort("failed to lookup value for magic_id column");
     910            }
     911
     912            whereString = NULL;
     913            psStringAppend(&whereString, "\nAND (magic_id = %" PRId64 ")", magic_id);
     914            if (!p_psDBRunQueryF(config->dbh, query, whereString )) {
     915                psError(PS_ERR_UNKNOWN, false, "database error");
     916                psFree(whereString);
     917                psFree(query);
     918                return false;
     919            }
     920            psFree(whereString);
     921            psArray *magicTree = p_psDBFetchResult(config->dbh);
     922            if (!magicTree) {
     923                psErrorCode err = psErrorCodeLast();
     924                switch (err) {
     925                    case PS_ERR_DB_CLIENT:
     926                        psError(PXTOOLS_ERR_SYS, false, "database error");
     927                    case PS_ERR_DB_SERVER:
     928                        psError(PXTOOLS_ERR_PROG, false, "database error");
     929                    default:
     930                        psError(PXTOOLS_ERR_PROG, false, "unknown error");
     931                }
     932
     933                return false;
     934            }
     935            psS64 length = psArrayLength(magicTree);
     936            if (!length) {
     937                psTrace("magictool", PS_LOG_INFO, "no rows found for magic_id %" PRId64, magic_id);
     938                psFree(magicTree);
     939                continue;
     940            }
     941
     942            psHash *forest = psHashAlloc(length);
     943
     944            // convert the array of metadata into a pxTree structure
     945            for (long i = 0; i < length; i++) {
     946                bool status;
     947                psString node = psMetadataLookupStr(&status, magicTree->data[i], "node");
     948                if (!status) {
     949                    psAbort("failed to lookup value for node column");
     950                }
     951
     952                psString dep = psMetadataLookupStr(&status, magicTree->data[i], "dep");
     953                if (!status) {
     954                    psAbort("failed to lookup value for dep column");
     955                }
     956
     957                pxTreeBuilder(forest, node, dep, magicTree->data[i]);
     958
     959            }
     960
     961            // find the root of the tree
     962            pxNode *root = psMemIncrRefCounter(psHashLookup(forest, "root"));
     963            psFree(forest);
     964            //    pxTreePrint(stdout, root);
     965
     966            // crawl through the tree and looking for nodes with children that are all
     967            // "done"
     968            pxTreeCrawl(root, findReadyNodes, output);
     969            psFree(root);
     970            psFree(magicTree);
     971        }
     972
     973        int len = psArrayLength(output);
     974        if (len) {
     975            if (limit) {
     976                if (limit < psArrayLength(output)) {
     977                    // truncate the array
     978                    long arrayLength = psArrayLength(output);
     979                    for (long i = arrayLength - 1; i >= limit; i--) {
     980                        psArrayRemoveIndex(output, i);
     981                    }
     982                    // negative simple so the default is true
     983                    if (!ippdbPrintMetadatas(stdout, output, "magicMe", !simple)) {
     984                        psError(PS_ERR_UNKNOWN, false, "failed to print array");
     985                        psFree(output);
     986                        return false;
     987                    }
     988                    psFree(output);
     989                    return true;
     990                } else {
     991                    limit -= len;
     992                }
     993            }
     994        }
     995    }
     996
     997    // look for "inputs" (skycells) that need to processed
     998    query = pxDataGet("magictool_toprocess_inputs.sql");
    955999    if (!query) {
    9561000        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
     
    9581002    }
    9591003
    960     for (psS64 index = 0; index < psArrayLength(magicRuns); index++) {
    961         if (limit && (psArrayLength(output) >= limit)) {
    962             break;
    963         }
    964         bool status;
    965         psS64 magic_id = psMetadataLookupS64(&status, magicRuns->data[index], "magic_id");
    966         if (!status) {
    967             psAbort("failed to lookup value for magic_id column");
    968         }
    969 
    970         whereString = NULL;
    971         psStringAppend(&whereString, "\nAND (magic_id = %" PRId64 ")", magic_id);
    972         if (!p_psDBRunQueryF(config->dbh, query, whereString )) {
    973             psError(PS_ERR_UNKNOWN, false, "database error");
    974             psFree(whereString);
    975             psFree(query);
    976             return false;
    977         }
     1004    psStringAppend(&query, "\nORDER BY priority DESC, magic_id");
     1005
     1006    // treat limit == 0 as "no limit"
     1007    if (limit) {
     1008        psString limitString = psDBGenerateLimitSQL(limit);
     1009        psStringAppend(&query, " %s", limitString);
     1010        psFree(limitString);
     1011    }
     1012
     1013    if (!p_psDBRunQueryF(config->dbh, query, whereString, whereString)) {
     1014        psError(PS_ERR_UNKNOWN, false, "database error");
    9781015        psFree(whereString);
    979         psArray *magicTree = p_psDBFetchResult(config->dbh);
    980         if (!magicTree) {
    981             psErrorCode err = psErrorCodeLast();
    982             switch (err) {
    983                 case PS_ERR_DB_CLIENT:
    984                     psError(PXTOOLS_ERR_SYS, false, "database error");
    985                 case PS_ERR_DB_SERVER:
    986                     psError(PXTOOLS_ERR_PROG, false, "database error");
    987                 default:
    988                     psError(PXTOOLS_ERR_PROG, false, "unknown error");
    989             }
    990 
    991             return false;
    992         }
    993         psS64 length = psArrayLength(magicTree);
    994         if (!length) {
    995             psTrace("magictool", PS_LOG_INFO, "no rows found for magic_id %" PRId64, magic_id);
    996             psFree(magicTree);
    997             continue;
    998         }
    999 
    1000         psHash *forest = psHashAlloc(length);
    1001 
    1002         // convert the array of metadata into a pxTree structure
    1003         for (long i = 0; i < length; i++) {
    1004             bool status;
    1005             psString node = psMetadataLookupStr(&status, magicTree->data[i], "node");
    1006             if (!status) {
    1007                 psAbort("failed to lookup value for node column");
    1008             }
    1009 
    1010             psString dep = psMetadataLookupStr(&status, magicTree->data[i], "dep");
    1011             if (!status) {
    1012                 psAbort("failed to lookup value for dep column");
    1013             }
    1014 
    1015             pxTreeBuilder(forest, node, dep, magicTree->data[i]);
    1016 
    1017         }
    1018 
    1019         // find the root of the tree
    1020         pxNode *root = psMemIncrRefCounter(psHashLookup(forest, "root"));
    1021         psFree(forest);
    1022         //    pxTreePrint(stdout, root);
    1023 
    1024         // crawl through the tree and looking for nodes with children that are all
    1025         // "done"
    1026         pxTreeCrawl(root, findReadyNodes, output);
    1027         psFree(root);
    1028         psFree(magicTree);
    1029     }
    1030 
     1016        psFree(query);
     1017        return false;
     1018    }
     1019    psFree(query);
     1020
     1021    psArray *skycellOutput = p_psDBFetchResult(config->dbh);
     1022    if (!skycellOutput) {
     1023        psErrorCode err = psErrorCodeLast();
     1024        switch (err) {
     1025            case PS_ERR_DB_CLIENT:
     1026                psError(PXTOOLS_ERR_SYS, false, "database error");
     1027            case PS_ERR_DB_SERVER:
     1028                psError(PXTOOLS_ERR_PROG, false, "database error");
     1029            default:
     1030                psError(PXTOOLS_ERR_PROG, false, "unknown error");
     1031        }
     1032
     1033        return false;
     1034    }
     1035    // merge the arrays so that we can print them all at once
     1036    if (psArrayLength(skycellOutput)) {
     1037        int len = psArrayLength(skycellOutput);
     1038        for (int i=0; i < len; i++) {
     1039            psArrayAdd(output, 0, skycellOutput->data[i]);
     1040        }
     1041    }
     1042    psFree(skycellOutput);
    10311043    if (psArrayLength(output)) {
    1032         if (limit && (limit < psArrayLength(output))) {
    1033             // truncate the array
    1034             long arrayLength = psArrayLength(output);
    1035             for (long i = arrayLength - 1; i >= limit; i--) {
    1036                 psArrayRemoveIndex(output, i);
    1037             }
    1038         }
    1039         // negative simple so the default is true
    10401044        if (!ippdbPrintMetadatas(stdout, output, "magicMe", !simple)) {
    10411045            psError(PS_ERR_UNKNOWN, false, "failed to print array");
     
    10431047            return false;
    10441048        }
    1045     }
    1046 
     1049    } else {
     1050        psTrace("magictool", PS_LOG_INFO, "no rows found");
     1051    }
    10471052    psFree(output);
    1048 
    10491053    return true;
    10501054}
Note: See TracChangeset for help on using the changeset viewer.