public ArraySubblock ToArraySubblock(ReduceSurfaceAreaByReordering sorter) { var translaterow = Enumerable.Range(this.Row, this.RowHeight).Select(s => sorter.Rows[s]); var translatecol = Enumerable.Range(this.Col, this.ColWidth).Select(s => sorter.Columns[s]); return(new ArraySubblock(translaterow, translatecol) { Row = this.Row, Col = this.Col }); }
public BiggestContiguousBlock(ReduceSurfaceAreaByReordering reordering) { this.Sorter = reordering; this.Area = reordering.Area; }
//we want a system of ordering the requests to make best use of caching... order the requests by origin and destination public DistanceResults GetDistanceMatrix(IList <string> origin, IList <string> dest) { DistanceResults matrix = new DistanceResults() { Status = "OK" }; matrix.Origin.AddRange(origin); matrix.Destination.AddRange(dest); matrix.OriginResponse = new string[origin.Count]; matrix.DestinationResponse = new string[dest.Count]; //find out if an existing resultset was requested and cached var filename = getNTFSName(matrix.ToFilename()); //hash the filename to comply with NTFS rules if (File.Exists(filename)) { try { return(_service.ReadXML(filename)); //return GoogleDistanceMatrix.ReadXML(filename); } catch { File.Delete(filename); } } //resultset not cached matrix.Row.AddRange(origin.Select(s => new List <DistElement>(dest.Select <string, DistElement>(s2 => null)))); //so assume some are cached...some are not... //how do we group the stuff not cached which gets send remotely //get the stuff cached, and assign scores to each origin with a correlated misses //getting the misses is easy... how do we group the misses together, so we make a one big request with stuff we want. //previously, we did it with same counts... // we can do it with flags ANDed together // A B C D E F // Z 1 1 1 0 0 1 = 4 (previous code grouped all the 4's together and tried to figure which dest matched) // Y 1 1 1 0 0 1 = 4 // X 1 1 0 1 0 1 = 4 // W 1 1 0 0 1 1 = 4 // ---------------- // 1 1 0 0 0 1 = 3 But if we AND all the bits, then look at it, we know we only request [Z Y X W] x [A B F] // But this means we have to do a cross-AND with every row, of every origin with same number of misses, to determine 2nd-order sort // plus the excluded [Z Y X W] x [C D E], which only has 4x 1's, out of 12 requests // // so this turns above into // A B F C D E // Z 1 1 1 = 3 1 0 0 // Y 1 1 1 = 3 1 0 0 // X 1 1 1 = 3 0 1 0 // W 1 1 1 = 3 0 0 1 // // C // Z 1 // Y 1 // D // X 1 // E // W 1 // // so to minimize the number of costable requests to google..., though we can call [Z Y X W] x [C D E], with a 75% miss rate // is a var notfound = false; var matrixRow = matrix.Row; var oricount = origin.Count; var destcount = dest.Count; bool[,] found = new bool[destcount, oricount]; for (int j = 0; j < oricount; j++) { for (int i = 0; i < destcount; i++) { var from = origin[j]; var to = dest[i]; if (this.Contains(from, to)) { found[j, i] = true; matrixRow[j][i] = this[from, to]; } else if (!notfound) { notfound = true; } } } if (notfound) { ReduceSurfaceAreaByReordering waterdrop = new ReduceSurfaceAreaByReordering() { Area = found }; waterdrop.SortPass += delegate(object sender, EventArgs e) { Console.WriteLine("Finding missing elements"); }; BiggestContiguousBlock skimmer = new BiggestContiguousBlock(waterdrop); foreach (var item in skimmer.Chunkify(false)) { //item.SetAllTrue(); const int GOOGLE_MAX_ORIGIN_OR_DEST = 25; const int GOOGLE_MAX_REQUESTS = 100; const int GOOGLE_DEFACTO_MAX_ORIGIN_AND_DEST = 10; foreach (var subitem in item.Chunkify(GOOGLE_DEFACTO_MAX_ORIGIN_AND_DEST)) { var suborigin = subitem.RowIndices.Select(s => origin[s]).ToArray(); var subdest = subitem.ColIndices.Select(s => dest[s]).ToArray(); if (this.RemoteRetreive != null) { this.RemoteRetreive(this, new UserRequestEventArgs("[" + string.Join("; ", suborigin) + "] to [" + string.Join("; ", subdest) + "]")); } var googleresults = _service.RetryDistancesFromGoogle(10, 1000, suborigin, subdest); //GetDistancesFromGoogle(suborigin, subdest); //change this to var row = 0; var col = 0; foreach (var fromindex in subitem.RowIndices) { col = 0; foreach (var toindex in subitem.ColIndices) { var from = origin[fromindex]; var to = dest[toindex]; var data = googleresults.Row[row][col++]; if (data.Status == "OK") { matrixRow[fromindex][toindex] = data; } else if (this.UserRequestError != null) { this.UserRequestError(this, new UserRequestEventArgs("[" + from + "] to [" + to + "]", data.Status)); } } row++; } //until alias system is up, update with user requested name row = 0; col = 0; foreach (var fromindex in subitem.RowIndices) { matrix.OriginResponse[fromindex] = googleresults.Origin[row++]; } foreach (var toindex in subitem.ColIndices) { matrix.DestinationResponse[toindex] = googleresults.Destination[col++]; } subitem.SetAllTrue(); } } _service.WriteXML(matrix, filename); } //and group the stuff cached, in such a way that it takes the best use of the deserialized object cache... (obviously file caching works better too) return(matrix); }