Changeset 30388 for trunk/ippTools/src/magictool.c
- Timestamp:
- Jan 27, 2011, 9:48:14 AM (15 years ago)
- File:
-
- 1 edited
-
trunk/ippTools/src/magictool.c (modified) (6 diffs, 1 prop)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ippTools/src/magictool.c
- Property svn:mergeinfo set to
r30374 r30388 835 835 PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false); 836 836 837 // look for "inputs" that need to processed838 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 844 837 psString whereString = NULL; 845 838 if (psListLength(where->list)) { … … 850 843 psFree(where); 851 844 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. 904 849 905 850 // first find incomplete magicRuns 906 query = pxDataGet("magictool_toprocess_runs.sql");851 psString query = pxDataGet("magictool_toprocess_runs.sql"); 907 852 if (!query) { 908 853 psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement"); … … 910 855 } 911 856 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. 919 863 { 920 864 psString limitString = psDBGenerateLimitSQL( 1000 ); … … 946 890 return false; 947 891 } 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"); 955 999 if (!query) { 956 1000 psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement"); … … 958 1002 } 959 1003 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"); 978 1015 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); 1031 1043 if (psArrayLength(output)) { 1032 if (limit && (limit < psArrayLength(output))) {1033 // truncate the array1034 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 true1040 1044 if (!ippdbPrintMetadatas(stdout, output, "magicMe", !simple)) { 1041 1045 psError(PS_ERR_UNKNOWN, false, "failed to print array"); … … 1043 1047 return false; 1044 1048 } 1045 } 1046 1049 } else { 1050 psTrace("magictool", PS_LOG_INFO, "no rows found"); 1051 } 1047 1052 psFree(output); 1048 1049 1053 return true; 1050 1054 }
Note:
See TracChangeset
for help on using the changeset viewer.
