//---------------------------------------------------------------------- /// <summary> /// This isn't exactly a search, because the exact Party IDs of the /// desired results, in the order they're expected, are provided. This /// is primarily useful for Search Engine Marketing (SEM) landing pages /// where we want to highlight an exlicit set of Parties. /// </summary> public static ResultSet Do(ITimer timerContext, List <int> partyIds) { Timer t = new Timer(timerContext, "Search.Do() - explicit Party ID list"); try { Comparison <Result> explicitOrdering = delegate(Result lhs, Result rhs) { return(partyIds .IndexOf(lhs.PartyId) .CompareTo(partyIds.IndexOf(rhs.PartyId))); }; // The comparison delegate above depends on the specific // ordering of 'partyIds'. Make a copy of that list to pass to // our IntSet constructor, since it will "own" the list we give // it. We can't have it altering the list order we use for // sorting! List <int> partyIdsCopy = new List <int>(partyIds); ResultSet results = ResultSet.From( null, // search origin null, // max radius mi. IntSet <PartyId> .CreateFromUnsorted(partyIdsCopy)); return(FinalizeResultSet( t, explicitOrdering, ExactMatchResultCount, results, null)); } finally { t.Stop(); } }
//---------------------------------------------------------------------- private static IntSet <PartyId> SearchByBoundingBox( Timer t, AddressParserResult searchLocale, out Location centroid) { centroid = searchLocale.BoundingBox.Centroid; // KLUDGE: Justify this initial array size and make it a constant at // least or a configuration setting at best. This is a wild guess. List <int> partyIds = new List <int>(1024); Snap.Cache.Cache.PartyLocation.Search(searchLocale.BoundingBox, delegate(int partyId) { partyIds.Add(partyId); }); return(IntSet <PartyId> .CreateFromUnsorted(partyIds)); }
//---------------------------------------------------------------------- private static IntSet <PartyId> SearchNearLocation( Timer t, int desiredResultCount, Location centroid, double nonGeoMatchAbsDensity, out double?maxRadiusMi) { double searchRadiusMi = InitialGeoSearchRadiusMi; maxRadiusMi = searchRadiusMi; // KLUDGE: Scale the desired result count up by the non-geographic // match absolute density in the database. In doing so, we attempt // to return enough results that we'll get close to the desired // result count in the end. desiredResultCount = (int)(desiredResultCount / nonGeoMatchAbsDensity); // Allocate an initial list large enough that we'll (hopefully) // avoid re-allocating space as we iterate. List <int> partyIds = new List <int>(2 * desiredResultCount); Tree2D <int> tree2d = Snap.Cache.Cache.PartyLocation; int iterationCount = 0; Timer tree2dTimer = new Timer(t, String.Format( "Expand MBR to fit {0} Parties", desiredResultCount)); while ((partyIds.Count < desiredResultCount) && (searchRadiusMi < MaxGeoSearchRadiusMi)) { iterationCount++; maxRadiusMi = searchRadiusMi; partyIds.Clear(); tree2d.Search( new BoundingBox(centroid, searchRadiusMi), (partyId) => partyIds.Add(partyId)); searchRadiusMi *= GeoSearchRadiusScalar; } tree2dTimer.Stop(String.Format("in {0} iterations", iterationCount)); return(IntSet <PartyId> .CreateFromUnsorted(partyIds)); }