예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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));
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
 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;
     }
 }
예제 #8
0
        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++;
            }
        }