コード例 #1
0
        /// <summary>
        /// Uses BinarySearch to locate the index of the block that contains start
        /// </summary>
        /// <param name="cache"></param>
        /// <param name="start"></param>
        /// <param name="match">True if match found.  If this is false, the index returned is where the item would appear if it existed.</param>
        /// <returns>Index</returns>
        private int FindIndexOfBlockAtOffset(SparseMemoryStream cache, long start, out bool match)
        {
            if (cache.MemoryBlockCollection.Count == 0)
            {
                match = false;
                return(0);
            }

            // use BinarySearch to locate blocks of interest quickly
            if (_comparisonBlock == null)
            {
                _comparisonBlock = new MemoryStreamBlock(null, start);
            }
            else
            {
                _comparisonBlock.Offset = start;
            }

            int index = cache.MemoryBlockCollection.BinarySearch(_comparisonBlock);

            if (index < 0) // no match
            {
                // ~index represents the place at which the block we asked for
                // would appear if it existed
                index = ~index;
                match = false;
            }
            else
            {
                match = true;
            }
            return(index);
        }
コード例 #2
0
        private int ReadFromCache(SparseMemoryStream cache, long start, int count, byte[] buffer, int bufferOffset)
        {
#if DEBUG
            // debug only check for valid parameters, as we generally expect callers to verify them
            PackagingUtilities.VerifyStreamReadArgs(this, buffer, bufferOffset, count);
#endif
            Debug.Assert(cache != null);
            Debug.Assert(start >= 0);
            IList <MemoryStreamBlock> collection = cache.MemoryBlockCollection;

            checked
            {
                // use BinarySearch to locate blocks of interest quickly
                bool match;     // exact match?
                int  index = FindIndexOfBlockAtOffset(cache, start, out match);

                // if match was found, read from it
                int bytesRead = 0;
                if (match)
                {
                    MemoryStreamBlock memStreamBlock = collection[index];
                    long overlapBlockOffset;
                    long overlapBlockSize;

                    // we have got an overlap which can be used to satisfy the read request,
                    // at least  partially
                    PackagingUtilities.CalculateOverlap(memStreamBlock.Offset, memStreamBlock.Stream.Length,
                                                        start, count,
                                                        out overlapBlockOffset, out overlapBlockSize);

                    if (overlapBlockSize > 0)
                    {
                        // overlap must be starting at the start as we know for sure that
                        // memStreamBlock.Offset <= start
                        Debug.Assert(overlapBlockOffset == start);

                        memStreamBlock.Stream.Seek(overlapBlockOffset - memStreamBlock.Offset, SeekOrigin.Begin);

                        // we know that memStream will return as much data as we requested
                        // even if this logic changes we do not have to return everything
                        // a partially complete read is acceptable here
                        bytesRead = memStreamBlock.Stream.Read(buffer, bufferOffset, (int)overlapBlockSize);
                    }
                }

                return(bytesRead);
            }
        }
コード例 #3
0
        /// <summary>
        /// Uses BinarySearch to locate the index of the block that contains start
        /// </summary>
        /// <param name="cache"></param>
        /// <param name="start"></param>
        /// <param name="match">True if match found.  If this is false, the index returned is where the item would appear if it existed.</param>
        /// <returns>Index</returns>
        private int FindIndexOfBlockAtOffset(SparseMemoryStream cache, long start, out bool match)
        {
            if (cache.MemoryBlockCollection.Count == 0)
            {
                match = false;
                return 0;
            }

            // use BinarySearch to locate blocks of interest quickly
            if (_comparisonBlock == null)
                _comparisonBlock = new MemoryStreamBlock(null, start);
            else
                _comparisonBlock.Offset = start;

            int index = cache.MemoryBlockCollection.BinarySearch(_comparisonBlock);
            if (index < 0) // no match
            {
                // ~index represents the place at which the block we asked for
                // would appear if it existed
                index = ~index;
                match = false;
            }
            else
            {
                match = true;
            }
            return index;
        }