/// <summary> /// Finds the gallery objects with the specified rating. Guaranteed to not return null. Albums cannot be /// rated and are thus not returned. Only items the current user is authorized to view are returned. /// </summary> /// <returns><see cref="IEnumerable<IGalleryObject>" />.</returns> private IEnumerable <IGalleryObject> FindMediaObjectsMatchingRating() { var galleryObjects = new GalleryObjectCollection(); if (SearchOptions.Filter != GalleryObjectType.Album) { galleryObjects.AddRange(GetRatedMediaObjects(SearchOptions.MaxNumberResults)); } var filteredGalleryObjects = FilterGalleryObjects(galleryObjects); if (filteredGalleryObjects.Count != galleryObjects.Count && filteredGalleryObjects.Count < SearchOptions.MaxNumberResults && galleryObjects.Count >= SearchOptions.MaxNumberResults) { // We lost some objects in the filter and now we have less than the desired MaxNumberResults. Get more. // Note: Performance can be very poor for large galleries when using a filter. For example, a gallery where 20 videos // were added and then 200,000 images were added, a search for the most recent 20 videos causes this algorithm // to load all 200,000 images into memory before finding the videos. The good news is that by default the filter // is for media objects, which will be very fast. If filters end up being commonly used, this algorithm should be improved. var max = SearchOptions.MaxNumberResults * 2; var skip = SearchOptions.MaxNumberResults; const int maxTries = 5; for (var i = 0; i < maxTries; i++) { // Add items up to maxTries times, each time doubling the number of items to retrieve. filteredGalleryObjects.AddRange(GetRatedMediaObjects(max, skip)); filteredGalleryObjects = FilterGalleryObjects(filteredGalleryObjects); if (filteredGalleryObjects.Count >= SearchOptions.MaxNumberResults) { break; } if (i < (maxTries - 1)) { skip = skip + max; max = max * 2; } } if (filteredGalleryObjects.Count < SearchOptions.MaxNumberResults) { // We still don't have enough objects. Search entire set of albums and media objects. filteredGalleryObjects.AddRange(GetRatedMediaObjects(int.MaxValue, skip)); filteredGalleryObjects = FilterGalleryObjects(filteredGalleryObjects); } } if (SearchOptions.MaxNumberResults > 0 && filteredGalleryObjects.Count > SearchOptions.MaxNumberResults) { return(filteredGalleryObjects.OrderByDescending(g => g.DateAdded).Take(SearchOptions.MaxNumberResults)); } return(filteredGalleryObjects); }
/// <summary> /// Finds the gallery objects matching tags. Guaranteed to not return null. Call this function only when the search type /// is <see cref="GalleryObjectSearchType.SearchByTag" /> or <see cref="GalleryObjectSearchType.SearchByPeople" />. /// Only items the user has permission to view are returned. /// </summary> /// <returns>An instance of <see cref="IGalleryObjectCollection" />.</returns> private IEnumerable <IGalleryObject> FindItemsMatchingTags() { var galleryObjects = new GalleryObjectCollection(); if (SearchOptions.Filter == GalleryObjectType.All || SearchOptions.Filter == GalleryObjectType.Album) { galleryObjects.AddRange(GetAlbumsHavingTags()); } if (SearchOptions.Filter != GalleryObjectType.Album) { galleryObjects.AddRange(GetMediaObjectsHavingTags()); } var filteredGalleryObjects = FilterGalleryObjects(galleryObjects); return(SearchOptions.MaxNumberResults > 0 ? filteredGalleryObjects.ToSortedList().Take(SearchOptions.MaxNumberResults) : filteredGalleryObjects); }