public bool TryLookupUri(Uri uri, HostNameComparisonMode hostNameComparisonMode, out TItem item) { BaseUriWithWildcard key = new BaseUriWithWildcard(uri, hostNameComparisonMode); if (TryCacheLookup(key, out item)) { return(item != null); } using (AsyncLock.TakeLock()) { // exact match failed, perform the full lookup (which will also // catch case-insensitive variations that aren't yet in our cache) bool dummy; SegmentHierarchyNode <TItem> node = FindDataNode( UriSegmenter.ToPath(key.BaseAddress, hostNameComparisonMode, includePortInComparison), out dummy); if (node != null) { item = node.Data; } // We want to cache both positive AND negative results AddToCache(key, item); return(item != null); } }
void AddToCache(BaseUriWithWildcard key, TItem item) { // Don't allow explicitly adding DBNulls. Fx.Assert(item != DBNull.Value, "Can't add DBNull to UriPrefixTable."); // HopperCache uses null as 'doesn't exist', so use DBNull as a stand-in for null. lookupCache.Add(key, item ?? (object)DBNull.Value); }
bool TryCacheLookup(BaseUriWithWildcard key, out TItem item) { object value = lookupCache.GetValue(ThisLock, key); // We might return null and true in the case of DBNull (cached negative result). // When TItem is object, the cast isn't sufficient to weed out DBNulls, so we need an explicit check. item = value == DBNull.Value ? null : (TItem)value; return(value != null); }
public override bool Equals(object o) { BaseUriWithWildcard other = o as BaseUriWithWildcard; if (other == null || other._hashCode != _hashCode || other._hostNameComparisonMode != _hostNameComparisonMode || other._comparand.Port != _comparand.Port) { return(false); } if (!ReferenceEquals(other._comparand.Scheme, _comparand.Scheme)) { return(false); } return(_comparand.Address.Equals(other._comparand.Address)); }
public bool IsRegistered(BaseUriWithWildcard key) { Uri uri = key.BaseAddress; // don't need to normalize path since SegmentHierarchyNode is // already OrdinalIgnoreCase string[] paths = UriSegmenter.ToPath(uri, key.HostNameComparisonMode, includePortInComparison); bool exactMatch; SegmentHierarchyNode <TItem> node; using (AsyncLock.TakeLock()) { node = FindDataNode(paths, out exactMatch); } return(exactMatch && node != null && node.Data != null); }
private SegmentHierarchyNode <TItem> FindOrCreateNode(BaseUriWithWildcard baseUri) { Fx.Assert(baseUri != null, "FindOrCreateNode: baseUri is null"); string[] path = UriSegmenter.ToPath(baseUri.BaseAddress, baseUri.HostNameComparisonMode, _includePortInComparison); SegmentHierarchyNode <TItem> current = _root; for (int i = 0; i < path.Length; ++i) { if (!current.TryGetChild(path[i], out SegmentHierarchyNode <TItem> next)) { next = new SegmentHierarchyNode <TItem>(path[i], _useWeakReferences); current.SetChildNode(path[i], next); } current = next; } return(current); }
public void SetData(TData data, BaseUriWithWildcard path) { this.path = path; if (useWeakReferences) { if (data == null) { weakData = null; } else { weakData = new WeakReference(data); } } else { this.data = data; } }
public void RegisterUri(Uri uri, HostNameComparisonMode hostNameComparisonMode, TItem item) { Fx.Assert(HostNameComparisonModeHelper.IsDefined(hostNameComparisonMode), "RegisterUri: Invalid HostNameComparisonMode value passed in."); using (AsyncLock.TakeLock()) { // Since every newly registered Uri could alter what Prefixes should have matched, we // should clear the cache of any existing results and start over ClearCache(); BaseUriWithWildcard key = new BaseUriWithWildcard(uri, hostNameComparisonMode); SegmentHierarchyNode <TItem> node = FindOrCreateNode(key); if (node.Data != null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format( SR.DuplicateRegistration, uri))); } node.SetData(item, key); count++; } }