예제 #1
0
            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
                });
            }
예제 #2
0
 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);
        }