Пример #1
0
        private void Cleanup()
        {
            bool waittingForCacheThreadFinish = false;

            lock (_CacheLock)
            {
                if (_CacheThread != null)
                {
                    waittingForCacheThreadFinish = true;
                    _Closing = true;
                }
            }

            if (waittingForCacheThreadFinish)
            {
                try
                {
                    if (!_CacheThread.Join(5000))
                    {
                        _CacheThread.Abort();
                    }
                }
                catch
                {
                }
            }

            if (_CacheBufferIndex != null)
            {
                long realseMemSize = 0;

                for (int index = 0; index < _CacheBufferIndex.Length; index++)
                {
                    CachedFileBufferManager.Buffer buffer = _CacheBufferIndex[index];

                    if (buffer != null)
                    {
                        realseMemSize += buffer.Close();
                    }
                }

                if (realseMemSize >= 64 * 1024 * 1024)
                {
                    //Large than 64M
                    //Force collect GC
                    GC.Collect(GC.MaxGeneration);
                }
            }
        }
Пример #2
0
        public override int Read(byte[] array, int offset, int count)
        {
            if (_CacheBufferIndex != null)
            {
                int index          = (int)(this.Position / CachedFileBufferManager.BufferUnitSize);
                int offsetInBuffer = (int)(this.Position % CachedFileBufferManager.BufferUnitSize);

                if (_CacheBufferIndex[index] != null)
                {
                    CachedFileBufferManager.Buffer buffer = _CacheBufferIndex[index];
                    byte[] data = _CacheBufferIndex[index].Data;

                    if (data != null)
                    {
                        if (data.Length - offsetInBuffer - buffer.HeadPosition >= count)
                        {
                            //Data inside one block.
                            Array.Copy(data, offsetInBuffer + buffer.HeadPosition, array, offset, count);

                            Position += count;
                            return(count);
                        }
                        else
                        {
                            if (buffer.HeadPosition > 0 || index == _CacheBufferIndex.Length - 1 || count < 10 * 1024)
                            {
                                //Data outside one block. but the index is not the beginning of the block
                                //Or it is the last block
                                //Or small count less than 10K
                                //Return part of the data

                                int len = data.Length - offsetInBuffer - buffer.HeadPosition;

                                Array.Copy(data, offsetInBuffer + buffer.HeadPosition, array, offset, len);

                                Position += len;
                                return(len);
                            }
                        }
                    }
                }

                if ((_Type == CachedType.Dynamic || _Type == CachedType.Full) &&
                    CacheAllFinished)
                {
                    OffsetLength ol = _LastOLWithBuffer[index];

                    if (offsetInBuffer >= ol.Offset && offsetInBuffer <= ol.Offset + ol.Length)
                    {
                        ol.Length += count - (ol.Offset + ol.Length - offsetInBuffer);
                    }
                    else
                    {
                        ol.Offset = offsetInBuffer;
                        ol.Length = count;
                    }

                    _LastOLWithBuffer[index] = ol;

                    if (ol.Length >= MinCacheLength)
                    {
                        //Cached
                        if (LoadToBuffer(count, Position))
                        {
                            return(Read(array, offset, count));
                        }
                    }
                }

                //return data from file
                base.Seek(Position, SeekOrigin.Begin);
                int retLen = base.Read(array, offset, count);
                Position += retLen;
                return(retLen);
            }


            return(base.Read(array, offset, count));
        }
Пример #3
0
        /// <summary>
        /// Read and output to array
        /// </summary>
        /// <param name="array">array</param>
        /// <param name="offsetInArray">offset in array</param>
        /// <param name="offset">offset in file</param>
        /// <param name="count">count want to read</param>
        /// <returns>actual read count</returns>
        public int Read(out byte[] array, out int offsetInArray, int count)
        {
            if (_CacheBufferIndex != null)
            {
                int index          = (int)(this.Position / CachedFileBufferManager.BufferUnitSize);
                int offsetInBuffer = (int)(this.Position % CachedFileBufferManager.BufferUnitSize);

                if (_CacheBufferIndex[index] != null)
                {
                    CachedFileBufferManager.Buffer buffer = _CacheBufferIndex[index];
                    byte[] data = _CacheBufferIndex[index].Data;

                    if (data != null)
                    {
                        if (data.Length - offsetInBuffer - buffer.HeadPosition >= count)
                        {
                            array         = data;
                            offsetInArray = offsetInBuffer + buffer.HeadPosition;
                            Position     += count;
                            return(count);
                        }
                        else
                        {
                            if (buffer.HeadPosition > 0 || index == _CacheBufferIndex.Length - 1 || count < 10 * 1024)
                            {
                                //Data outside one block. but the index is not the beginning of the block
                                //Or it is the last block
                                //Or small count less than 10K
                                //Return part of the data

                                array = new byte[count];

                                Stream.ReadToBuf(this, array, 0, ref count);
                                offsetInArray = 0;

                                return(count);
                            }
                        }
                    }
                }

                if ((_Type == CachedType.Dynamic || _Type == CachedType.Full) &&
                    CacheAllFinished)
                {
                    OffsetLength ol = _LastOLWithBuffer[index];

                    if (offsetInBuffer >= ol.Offset && offsetInBuffer <= ol.Offset + ol.Length)
                    {
                        ol.Length += count - (ol.Offset + ol.Length - offsetInBuffer);
                    }
                    else
                    {
                        ol.Offset = offsetInBuffer;
                        ol.Length = count;
                    }

                    _LastOLWithBuffer[index] = ol;

                    if (ol.Length >= MinCacheLength)
                    {
                        //Cached
                        if (LoadToBuffer(count, Position))
                        {
                            return(Read(out array, out offsetInArray, count));
                        }
                    }
                }

                //return data from file
                array = new byte[count];

                Stream.ReadToBuf(this, array, 0, ref count);
                offsetInArray = 0;
                return(count);
            }

            array         = new byte[count];
            offsetInArray = 0;
            Stream.ReadToBuf(this, array, 0, ref count);

            return(count);
        }
Пример #4
0
        private bool LoadToBuffer(int count, long position)
        {
            int index          = (int)(position / CachedFileBufferManager.BufferUnitSize);
            int offsetInBuffer = (int)(position % CachedFileBufferManager.BufferUnitSize);

            if (count > CachedFileBufferManager.BufferUnitSize - offsetInBuffer)
            {
                int dataremain = (count - (CachedFileBufferManager.BufferUnitSize - offsetInBuffer));

                int loadIndexes = 1 + dataremain / CachedFileBufferManager.BufferUnitSize;

                if ((dataremain % CachedFileBufferManager.BufferUnitSize) > 0)
                {
                    loadIndexes++;
                }

                int loadLength = loadIndexes * CachedFileBufferManager.BufferUnitSize;

                if (index + loadIndexes >= _CacheBufferIndex.Length)
                {
                    //To last buffer

                    loadLength = (int)(_FileLength - index * CachedFileBufferManager.BufferUnitSize);
                }

                CachedFileBufferManager.Buffer buffer = _CachedFileMgr.Alloc(loadLength);

                if (buffer == null)
                {
                    return(false);
                }

                byte[] data = buffer.Data;

                if (data != null)
                {
                    base.Seek(index * CachedFileBufferManager.BufferUnitSize, SeekOrigin.Begin);

                    int offset = 0;
                    int read   = 0;

                    while ((read = base.Read(data, offset, data.Length - offset)) > 0)
                    {
                        offset += read;
                        if (offset >= data.Length)
                        {
                            break;
                        }
                    }

                    if (offset != data.Length)
                    {
                        throw new System.IO.IOException();
                    }
                }
                else
                {
                    return(false);
                }

                lock (this)
                {
                    CachedFileBufferManager.Buffer preBuffer = null;

                    for (int i = index; i < index + loadIndexes; i++)
                    {
                        if (_CacheBufferIndex[i] != null)
                        {
                            _CacheBufferIndex[i].Close();
                        }

                        if (i == index)
                        {
                            _CacheBufferIndex[i] = buffer;
                            preBuffer            = _CacheBufferIndex[i];
                        }
                        else
                        {
                            _CacheBufferIndex[i] = buffer.Clone((i - index) * CachedFileBufferManager.BufferUnitSize);
                            preBuffer.Next       = _CacheBufferIndex[i];
                            preBuffer            = _CacheBufferIndex[i];
                        }
                    }
                }

                return(true);
            }
            else
            {
                return(InnerCacheUnit(index));
            }
        }