/// <summary> /// Get suitable tags /// </summary> /// <param name="languageTag"></param> /// <returns></returns> public IEnumerable <LanguageTag> GetSuitableTags(LanguageTag languageTag) { if (_cachedResults.TryGetValue(languageTag.GetHashCode(), out var results)) { return(results.Select(s => s.Value)); } if (!_items.Any()) { return(Enumerable.Empty <LanguageTag>()); } results = new List <FallbackItem>(); var orderedItems = _items.OrderByDescending(o => o.Priority).ToList(); var skipHashCodes = new List <int>(); //step.1 filter all results by this order: ExactMatch, DefaultRegion, ScriptMatch and LanguageMatch foreach (var level in _matchLevels) { results.AddRange(Filter(orderedItems, languageTag, level, skipHashCodes)); } //step.2 add all results which priority less than the min of the result that got from step.1 results.AddRange(Filter(orderedItems, results.Min(m => m.Priority), skipHashCodes)); //step.3 add default language tag (in this case, the most less priority) if need. AddMostLessPriorityIfNeed(results, skipHashCodes); //step.4 clear skipped hashcode cache skipHashCodes.Clear(); return(Remember(languageTag, results)); }
/// <summary> /// Register language tag /// </summary> /// <param name="languageTag"></param> /// <exception cref="ArgumentNullException"></exception> public void RegisterTag(LanguageTag languageTag) { if (languageTag == null) { throw new ArgumentNullException(nameof(languageTag)); } var hashcode = languageTag.GetHashCode(); // ReSharper disable once InconsistentlySynchronizedField if (_items.Any(x => x.HashCodeCached == hashcode)) { return; } lock (_cacheLockObj) { if (_items.Any(x => x.HashCodeCached == hashcode)) { return; } //this will update all item's priority _items.Add(new FallbackItem(languageTag)); } }
/// <summary> /// Has cached result /// </summary> /// <param name="languageTag"></param> /// <returns></returns> public bool HashCachedResult(LanguageTag languageTag) { if (languageTag == null) { return(false); } return(_cachedResults.ContainsKey(languageTag.GetHashCode())); }
private IEnumerable <LanguageTag> Remember(LanguageTag left, List <FallbackItem> filteredItems) { lock (_cacheLockObj) { var hashcode = left.GetHashCode(); if (_cachedResults.ContainsKey(hashcode)) { _cachedResults[hashcode] = filteredItems; } else { _cachedResults.Add(hashcode, filteredItems); } } return(filteredItems.Select(s => s.Value)); }