コード例 #1
0
        /// <inheritdoc />
        public async Task <Possible <ContentAvailabilityBatchResult, Failure> > TryLoadAvailableContentAsync(IReadOnlyList <ContentHash> hashes)
        {
            using (var hashAvailabilityMapWrapper = m_hashAvailabilityMapPool.GetInstance())
                using (var hashListWrapper = m_hashListPool.GetInstance())
                {
                    var hashAvailabilityMap = hashAvailabilityMapWrapper.Instance;
                    var hashList            = hashListWrapper.Instance;

                    var uniqueUnknownAvailabilityHashes = DeduplicateAndGetUnknownAvailabilityHashes(hashes, hashAvailabilityMap, hashList);

                    bool allContentAvailable = true;
                    if (uniqueUnknownAvailabilityHashes.Count != 0)
                    {
                        // Only query inner cache if there are hashes whose availabilty is unknown
                        var possibleBatchResult = await m_innerCache.TryLoadAvailableContentAsync(uniqueUnknownAvailabilityHashes);

                        if (!possibleBatchResult.Succeeded || uniqueUnknownAvailabilityHashes == hashes)
                        {
                            // If not successful or the hashes are the same as original hashes just return the result
                            return(possibleBatchResult);
                        }

                        // Populate hash availability map with results from inner cache
                        foreach (var result in possibleBatchResult.Result.Results)
                        {
                            hashAvailabilityMap[result.Hash] = result;
                            if (!result.IsAvailable)
                            {
                                allContentAvailable = false;
                            }
                            else
                            {
                                // Mark the hash as available for subsequent operations
                                m_availableContent.TryAdd(result.Hash, result.SourceCache);
                            }
                        }
                    }

                    ContentAvailabilityResult[] results = new ContentAvailabilityResult[hashes.Count];
                    for (int i = 0; i < hashes.Count; i++)
                    {
                        var hash = hashes[i];
                        if (hashAvailabilityMap.TryGetValue(hash, out var result))
                        {
                            results[i] = result;
                        }
                        else
                        {
                            throw Contract.AssertFailure(I($"Hash {hash} should be present in availability map."));
                        }
                    }

                    return(new ContentAvailabilityBatchResult(ReadOnlyArray <ContentAvailabilityResult> .FromWithoutCopy(results), allContentAvailable));
                }
        }
コード例 #2
0
        private IReadOnlyList <ContentHash> DeduplicateAndGetUnknownAvailabilityHashes(
            IReadOnlyList <ContentHash> hashes,
            Dictionary <ContentHash, ContentAvailabilityResult> hashAvailabilityMap,
            List <ContentHash> hashList)
        {
            bool hasDuplicateOrKnownAvailableHash = false;

            for (int i = 0; i < hashes.Count; i++)
            {
                var hash = hashes[i];
                if (!hashAvailabilityMap.TryGetValue(hash, out var result))
                {
                    if (m_availableContent.TryGetValue(hash, out var sourceCache))
                    {
                        // Known available hash
                        hasDuplicateOrKnownAvailableHash = true;
                        result = new ContentAvailabilityResult(hash, true, 0, sourceCache);
                    }

                    hashAvailabilityMap[hash] = result;
                }
                else
                {
                    // Duplicate
                    hasDuplicateOrKnownAvailableHash = true;
                }
            }

            IReadOnlyList <ContentHash> uniqueUnknownAvailabilityHashes;

            if (!hasDuplicateOrKnownAvailableHash)
            {
                // Just use original set of hashes since no duplicates or known available hashes
                uniqueUnknownAvailabilityHashes = hashes;
            }
            else
            {
                // Only submit unique hashes which are not known to be available to the inner cache
                foreach (var entry in hashAvailabilityMap)
                {
                    if (!entry.Value.IsAvailable)
                    {
                        hashList.Add(entry.Key);
                    }
                }

                uniqueUnknownAvailabilityHashes = hashList;
            }

            return(uniqueUnknownAvailabilityHashes);
        }
コード例 #3
0
        /// <inheritdoc />
        public Task <Possible <ContentAvailabilityBatchResult, Failure> > TryLoadAvailableContentAsync(IReadOnlyList <ContentHash> hashes)
        {
            return(Task.Run <Possible <ContentAvailabilityBatchResult, Failure> >(
                       () =>
            {
                lock (m_lock)
                {
                    bool allAvailable = true;
                    var results = new ContentAvailabilityResult[hashes.Count];
                    for (int i = 0; i < hashes.Count; i++)
                    {
                        CacheEntry entry;
                        bool available = m_content.TryGetValue(hashes[i], out entry);
                        long bytesTransferredRemotely;

                        // The content is now in the local site, if it wasn't already.
                        if (available)
                        {
                            bytesTransferredRemotely = (entry.Sites & CacheSites.Local) == 0
                                    ? entry.Content.Length
                                    : 0;

                            entry.Sites |= CacheSites.Local;
                        }
                        else
                        {
                            bytesTransferredRemotely = 0;
                        }

                        results[i] = new ContentAvailabilityResult(hashes[i], isAvailable: available, bytesTransferred: bytesTransferredRemotely, sourceCache: "InMemoryCache");
                        allAvailable &= available;
                    }

                    return new ContentAvailabilityBatchResult(
                        ReadOnlyArray <ContentAvailabilityResult> .FromWithoutCopy(results),
                        allContentAvailable: allAvailable);
                }
            }));
        }