Changeset 30586 for branches/czw_branch/20101203/ippTools/src/magictool.c
- Timestamp:
- Feb 11, 2011, 4:29:48 PM (15 years ago)
- Location:
- branches/czw_branch/20101203
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
ippTools/src/magictool.c (modified) (10 diffs, 1 prop)
Legend:
- Unmodified
- Added
- Removed
-
branches/czw_branch/20101203
- Property svn:mergeinfo changed
-
branches/czw_branch/20101203/ippTools/src/magictool.c
- Property svn:mergeinfo set to
r29625 r30586 49 49 static bool censorrunMode(pxConfig *config); 50 50 static bool exposureMode(pxConfig *config); 51 static bool setgotocleanedMode(pxConfig *config); 52 static bool tocleanupMode(pxConfig *config); 53 static bool setworkdirstateMode(pxConfig *config); 51 54 52 55 static bool setmagicRunState(pxConfig *config, psS64 magic_id, const char *state, psString setString); … … 89 92 MODECASE(MAGICTOOL_MODE_CENSORRUN, censorrunMode); 90 93 MODECASE(MAGICTOOL_MODE_EXPOSURE, exposureMode); 94 MODECASE(MAGICTOOL_MODE_SETGOTOCLEANED, setgotocleanedMode); 95 MODECASE(MAGICTOOL_MODE_TOCLEANUP, tocleanupMode); 96 MODECASE(MAGICTOOL_MODE_SETWORKDIRSTATE, setworkdirstateMode); 91 97 default: 92 98 psAbort("invalid option (this should not happen)"); … … 621 627 PXOPT_COPY_S64(config->args, where, "-magic_id", "magic_id", "=="); 622 628 PXOPT_COPY_S16(config->args, where, "-fault", "fault", "=="); 623 PXOPT_COPY_STR(config->args, where, "-label", "label", "==");629 pxAddLabelSearchArgs (config, where, "-label", "magicRun.label", "=="); 624 630 625 631 psString query = psStringCopy("UPDATE magicRun SET fault = 0 WHERE state = 'new' AND fault != 0"); … … 829 835 PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false); 830 836 831 // look for "inputs" that need to processed832 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 838 837 psString whereString = NULL; 839 838 if (psListLength(where->list)) { … … 844 843 psFree(where); 845 844 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. 898 849 899 850 // first find incomplete magicRuns 900 query = pxDataGet("magictool_toprocess_runs.sql");851 psString query = pxDataGet("magictool_toprocess_runs.sql"); 901 852 if (!query) { 902 853 psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement"); … … 904 855 } 905 856 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. 913 863 { 914 864 psString limitString = psDBGenerateLimitSQL( 1000 ); … … 940 890 return false; 941 891 } 892 942 893 if (!psArrayLength(magicRuns)) { 894 // no pending magicRuns nothing to do 943 895 psTrace("magictool", PS_LOG_INFO, "no rows found"); 944 psFree(magicRuns);945 896 return true; 946 897 } 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"); 949 1004 if (!query) { 950 1005 psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement"); … … 952 1007 } 953 1008 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"); 972 1020 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); 1025 1048 if (psArrayLength(output)) { 1026 if (limit && (limit < psArrayLength(output))) {1027 // truncate the array1028 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 true1034 1049 if (!ippdbPrintMetadatas(stdout, output, "magicMe", !simple)) { 1035 1050 psError(PS_ERR_UNKNOWN, false, "failed to print array"); … … 1037 1052 return false; 1038 1053 } 1039 } 1040 1054 } else { 1055 psTrace("magictool", PS_LOG_INFO, "no rows found"); 1056 } 1041 1057 psFree(output); 1042 1043 1058 return true; 1044 1059 } … … 1622 1637 return true; 1623 1638 } 1639 static 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 1686 static 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 } 1711 static 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.
