public override SpecificLayout GetBestLayout(LayoutQuery query) { if (this.true_queryResults == null) { this.Initialize(); } numQueries++; if (numQueries % 10000 == 0) { double rate = (double)numComputations / (double)numQueries; System.Diagnostics.Debug.WriteLine("Overall LayoutCache miss rate: " + numComputations + " of " + numQueries + " = " + rate); if (rate < 0.02) { System.Diagnostics.Debug.WriteLine("Surprisingly high layoutcache hit rate"); } } SpecificLayout fastResult = this.GetBestLayout_Quickly(query); if (query.Debug) { SpecificLayout correctResult = this.Query_SubLayout(query); if (correctResult != null && !query.Accepts(correctResult)) { ErrorReporter.ReportParadox("Error: LayoutCache was given an incorrect response by its sublayout"); } bool correct = true; if (query.PreferredLayout(correctResult, fastResult) != correctResult) { ErrorReporter.ReportParadox("Error: layout cache returned incorrect (superior) result"); query.ProposedSolution_ForDebugging = fastResult; correct = false; } if (query.PreferredLayout(fastResult, correctResult) != fastResult) { ErrorReporter.ReportParadox("Error: layout cache returned incorrect (inferior) result"); query.ProposedSolution_ForDebugging = correctResult; correct = false; } if (!correct) { this.GetBestLayout_Quickly(query); this.Query_SubLayout(query); } this.debugCheck(new LayoutQuery_And_Response(query, fastResult)); return(this.prepareLayoutForQuery(correctResult, query)); } //this.debugCheck(new LayoutQuery_And_Response(query, fastResult)); if (fastResult != null) { fastResult = fastResult.Clone(); } return(this.prepareLayoutForQuery(fastResult, query)); }
public override SpecificLayout GetBestLayout(LayoutQuery query) { SpecificLayout best_specificLayout = null; SpecificLayout debugResult = query.ProposedSolution_ForDebugging; if (debugResult != null) { debugResult = debugResult.Clone(); } List <LayoutChoice_Set> good_sourceLayouts = new List <LayoutChoice_Set>(); LayoutQuery originalQuery = query; foreach (LayoutChoice_Set layoutSet in this.layoutOptions) { if (best_specificLayout != null) { // make the query more strict, so we will only ever get dimensions that are at least as good as this // TODO: figure out why it's not better to use OptimizedPastExample query = query.OptimizedUsingExample(best_specificLayout); } SpecificLayout currentLayout; if (query.Debug) { // if the proposed layout is an option, then be sure to consider it if (debugResult != null && debugResult.GetAncestors().Contains(layoutSet)) { query.ProposedSolution_ForDebugging = debugResult; currentLayout = layoutSet.GetBestLayout(query); query.ProposedSolution_ForDebugging = debugResult; return(this.prepareLayoutForQuery(currentLayout, query)); } } currentLayout = layoutSet.GetBestLayout(query); if (currentLayout != null && query.PreferredLayout(currentLayout, best_specificLayout) == currentLayout) { // keep track of this query (which must be the best so far) best_specificLayout = currentLayout; good_sourceLayouts.Add(layoutSet); if (query.Debug && query.ProposedSolution_ForDebugging != null) { if (query.PreferredLayout(query.ProposedSolution_ForDebugging, best_specificLayout) != query.ProposedSolution_ForDebugging) { ErrorReporter.ReportParadox("Error; query " + query + " prefers " + best_specificLayout + " over proposed debug solution " + query.ProposedSolution_ForDebugging); LayoutQuery debugQuery = query.DebugClone(); layoutSet.GetBestLayout(debugQuery); } } } } originalQuery.ProposedSolution_ForDebugging = debugResult; return(this.prepareLayoutForQuery(best_specificLayout, originalQuery)); }
private SpecificLayout GetBestLayout_Quickly(LayoutQuery query) { SpecificLayout result = null; // A layout of size 0 in one dimension doesn't get any points for being nonzero in the other dimension if ((query.MaxHeight == 0) != (query.MaxWidth == 0)) { result = this.GetBestLayout_Quickly(this.SizeZeroQuery); if (query.Accepts(result)) { return(result); } return(null); } // check whether we've previously saved the result if (!query.Debug) { if (this.true_queryResults.TryGetValue(query, out result) || this.inferred_queryResults.TryGetValue(query, out result)) { if (result != null) { return(result); } return(null); } } // the result wasn't saved, so we need to delegate the layout query // However, we might first be able to make the query more strict LayoutQuery_And_Response broadened = this.Find_LargerQuery(query); if (broadened != null) { if (query.Debug) { LayoutQuery debugQuery = query.Clone(); debugQuery.Debug = true; SpecificLayout correct_subLayout = this.Query_SubLayout(debugQuery); if (broadened.Query.PreferredLayout(broadened.Response, correct_subLayout) != broadened.Response) { ErrorReporter.ReportParadox("Error; incorrect result for broadened query: broadened query " + broadened.Query + " returned " + broadened.Response + " whereas the response from the sublayout for debug query " + debugQuery + " is " + correct_subLayout); LayoutQuery debugQuery2 = broadened.Query.DebugClone(); debugQuery2.ProposedSolution_ForDebugging = correct_subLayout; this.GetBestLayout(debugQuery2); } } return(this.inferredLayout(query, broadened.Response)); } LayoutQuery_And_Response shrunken = this.FindExample(query); if (query.Debug) { if (shrunken != null) { LayoutQuery debugQuery = shrunken.Query.Clone(); debugQuery.Debug = true; SpecificLayout correct_subLayout = this.Query_SubLayout(debugQuery); if (shrunken.Query.PreferredLayout(shrunken.Response, correct_subLayout) != shrunken.Response) { ErrorReporter.ReportParadox("Error; incorrect result for shrunken query"); } } } if (shrunken != null) { // If the existing example is already at the extreme, then use it if (query.MaximizesScore()) { if (shrunken.Response.Width >= query.MaxWidth && shrunken.Response.Height >= query.MaxHeight) { return(this.inferredLayout(query, shrunken.Response)); } } if (query.MinimizesWidth()) { if (shrunken.Response.Width <= 0) { return(this.inferredLayout(query, shrunken.Response)); } } if (query.MinimizesHeight()) { if (shrunken.Response.Height <= 0) { return(this.inferredLayout(query, shrunken.Response)); } } } // if we couldn't immediately return a result using the cache, we can still put a bound on the results we might get // They have to be at least as good as the sample we found if (shrunken != null) { // First, see if we can improve past what we currently have LayoutQuery strictlyImprovedQuery = query.OptimizedPastExample(shrunken.Response); bool allowCache = !strictlyImprovedQuery.Accepts(shrunken.Response); // Ask the sublayout for this result (or use the cache if we've already asked) if (allowCache) { result = this.GetBestLayout_Quickly(strictlyImprovedQuery); } else { result = this.Query_SubLayout(strictlyImprovedQuery); } if (result == null) { result = shrunken.Response; } return(this.inferredLayout(query, result)); } else { result = this.Query_SubLayout(query); } if (result == null) { if (shrunken != null && query.Accepts(shrunken.Response)) { ErrorReporter.ReportParadox("Error: cache contains an acceptable value for the current query, but the layout claims there are none"); result = shrunken.Response; } } // record that this is the exact answer to this query LayoutQuery_And_Response queryAndResponse = new LayoutQuery_And_Response(query, result); this.orderedResponses.Add(queryAndResponse); //this.debugCheck(queryAndResponse); if (result != null) { result = result.Clone(); } return(result); }