Merge pull request #816 from coderb/pullreq-rar-memusage
rar5 improve memory usage
This commit is contained in:
commit
498d132d8a
6 changed files with 74 additions and 30 deletions
33
src/SharpCompress/BufferPool.cs
Normal file
33
src/SharpCompress/BufferPool.cs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
using System.Buffers;
|
||||
|
||||
namespace SharpCompress;
|
||||
|
||||
internal static class BufferPool
|
||||
{
|
||||
/// <summary>
|
||||
/// gets a buffer from the pool
|
||||
/// </summary>
|
||||
/// <param name="bufferSize">size of the buffer</param>
|
||||
/// <returns>the buffer</returns>
|
||||
public static byte[] Rent(int bufferSize)
|
||||
{
|
||||
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
|
||||
return ArrayPool<byte>.Shared.Rent(bufferSize);
|
||||
#else
|
||||
return new byte[bufferSize];
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns a buffer to the pool
|
||||
/// </summary>
|
||||
/// <param name="buffer">the buffer to return</param>
|
||||
public static void Return(byte[] buffer)
|
||||
{
|
||||
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
|
||||
ArrayPool<byte>.Shared.Return(buffer);
|
||||
#else
|
||||
// no-op
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ internal class RarStream : Stream
|
|||
|
||||
private bool fetch;
|
||||
|
||||
private byte[] tmpBuffer = new byte[65536];
|
||||
private byte[] tmpBuffer = BufferPool.Rent(65536);
|
||||
private int tmpOffset;
|
||||
private int tmpCount;
|
||||
|
||||
|
|
@ -40,6 +40,11 @@ internal class RarStream : Stream
|
|||
{
|
||||
if (!isDisposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
BufferPool.Return(this.tmpBuffer);
|
||||
this.tmpBuffer = null;
|
||||
}
|
||||
isDisposed = true;
|
||||
base.Dispose(disposing);
|
||||
readStream.Dispose();
|
||||
|
|
@ -118,16 +123,7 @@ internal class RarStream : Stream
|
|||
}
|
||||
if (count > 0)
|
||||
{
|
||||
if (tmpBuffer.Length < tmpCount + count)
|
||||
{
|
||||
var newBuffer = new byte[
|
||||
tmpBuffer.Length * 2 > tmpCount + count
|
||||
? tmpBuffer.Length * 2
|
||||
: tmpCount + count
|
||||
];
|
||||
Buffer.BlockCopy(tmpBuffer, 0, newBuffer, 0, tmpCount);
|
||||
tmpBuffer = newBuffer;
|
||||
}
|
||||
EnsureBufferCapacity(count);
|
||||
Buffer.BlockCopy(buffer, offset, tmpBuffer, tmpCount, count);
|
||||
tmpCount += count;
|
||||
tmpOffset = 0;
|
||||
|
|
@ -138,4 +134,20 @@ internal class RarStream : Stream
|
|||
unpack.Suspended = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureBufferCapacity(int count)
|
||||
{
|
||||
if (this.tmpBuffer.Length < this.tmpCount + count)
|
||||
{
|
||||
var newLength =
|
||||
this.tmpBuffer.Length * 2 > this.tmpCount + count
|
||||
? this.tmpBuffer.Length * 2
|
||||
: this.tmpCount + count;
|
||||
var newBuffer = BufferPool.Rent(newLength);
|
||||
Buffer.BlockCopy(this.tmpBuffer, 0, newBuffer, 0, this.tmpCount);
|
||||
var oldBuffer = this.tmpBuffer;
|
||||
this.tmpBuffer = newBuffer;
|
||||
BufferPool.Return(oldBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using SharpCompress.Common.Rar.Headers;
|
||||
#if !Rar2017_64bit
|
||||
|
|
@ -67,15 +67,15 @@ internal partial class Unpack : IRarUnpack
|
|||
|
||||
private void UnstoreFile()
|
||||
{
|
||||
var b = new byte[0x10000];
|
||||
Span<byte> b = stackalloc byte[(int)Math.Min(0x10000, DestUnpSize)];
|
||||
do
|
||||
{
|
||||
var n = readStream.Read(b, 0, (int)Math.Min(b.Length, DestUnpSize));
|
||||
var n = readStream.Read(b);
|
||||
if (n == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
writeStream.Write(b, 0, n);
|
||||
writeStream.Write(b.Slice(0, n));
|
||||
DestUnpSize -= n;
|
||||
} while (!Suspended);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -373,8 +373,8 @@ internal partial class Unpack
|
|||
|
||||
private bool ReadTables20()
|
||||
{
|
||||
var BitLength = new byte[BC20];
|
||||
var Table = new byte[MC20 * 4];
|
||||
Span<byte> BitLength = stackalloc byte[checked((int)BC20)];
|
||||
Span<byte> Table = stackalloc byte[checked((int)MC20 * 4)];
|
||||
if (Inp.InAddr > ReadTop - 25)
|
||||
{
|
||||
if (!UnpReadBuf())
|
||||
|
|
@ -410,13 +410,13 @@ internal partial class Unpack
|
|||
TableSize = NC20 + DC20 + RC20;
|
||||
}
|
||||
|
||||
for (uint I = 0; I < BC20; I++)
|
||||
for (int I = 0; I < checked((int)BC20); I++)
|
||||
{
|
||||
BitLength[I] = (byte)(Inp.getbits() >> 12);
|
||||
Inp.addbits(4);
|
||||
}
|
||||
MakeDecodeTables(BitLength, 0, BlockTables.BD, BC20);
|
||||
for (uint I = 0; I < TableSize; )
|
||||
for (int I = 0; I < checked((int)TableSize); )
|
||||
{
|
||||
if (Inp.InAddr > ReadTop - 5)
|
||||
{
|
||||
|
|
@ -487,8 +487,7 @@ internal partial class Unpack
|
|||
MakeDecodeTables(Table, (int)NC20, BlockTables.DD, DC20);
|
||||
MakeDecodeTables(Table, (int)(NC20 + DC20), BlockTables.RD, RC20);
|
||||
}
|
||||
//x memcpy(UnpOldTable20,Table,sizeof(UnpOldTable20));
|
||||
Array.Copy(Table, UnpOldTable20, UnpOldTable20.Length);
|
||||
Table.CopyTo(this.UnpOldTable20);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#nullable disable
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using static SharpCompress.Compressors.Rar.UnpackV2017.PackDef;
|
||||
|
|
@ -752,8 +752,8 @@ internal partial class Unpack
|
|||
}
|
||||
}
|
||||
|
||||
var BitLength = new byte[BC];
|
||||
for (uint I = 0; I < BC; I++)
|
||||
Span<byte> BitLength = stackalloc byte[checked((int)BC)];
|
||||
for (int I = 0; I < BC; I++)
|
||||
{
|
||||
uint Length = (byte)(Inp.fgetbits() >> 12);
|
||||
Inp.faddbits(4);
|
||||
|
|
@ -784,9 +784,9 @@ internal partial class Unpack
|
|||
|
||||
MakeDecodeTables(BitLength, 0, Tables.BD, BC);
|
||||
|
||||
var Table = new byte[HUFF_TABLE_SIZE];
|
||||
const uint TableSize = HUFF_TABLE_SIZE;
|
||||
for (uint I = 0; I < TableSize; )
|
||||
Span<byte> Table = stackalloc byte[checked((int)HUFF_TABLE_SIZE)];
|
||||
const int TableSize = checked((int)HUFF_TABLE_SIZE);
|
||||
for (int I = 0; I < TableSize; )
|
||||
{
|
||||
if (!Inp.ExternalBuffer && Inp.InAddr > ReadTop - 5)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@ internal sealed partial class Unpack : BitInput
|
|||
// LengthTable contains the length in bits for every element of alphabet.
|
||||
// Dec is the structure to decode Huffman code/
|
||||
// Size is size of length table and DecodeNum field in Dec structure,
|
||||
private void MakeDecodeTables(byte[] LengthTable, int offset, DecodeTable Dec, uint Size)
|
||||
private void MakeDecodeTables(Span<byte> LengthTable, int offset, DecodeTable Dec, uint Size)
|
||||
{
|
||||
// Size of alphabet and DecodePos array.
|
||||
Dec.MaxNum = Size;
|
||||
|
|
@ -269,7 +269,7 @@ internal sealed partial class Unpack : BitInput
|
|||
//memset(LengthCount,0,sizeof(LengthCount));
|
||||
for (size_t I = 0; I < Size; I++)
|
||||
{
|
||||
LengthCount[LengthTable[offset + I] & 0xf]++;
|
||||
LengthCount[LengthTable[checked((int)(offset + I))] & 0xf]++;
|
||||
}
|
||||
|
||||
// We must not calculate the number of zero length codes.
|
||||
|
|
@ -318,7 +318,7 @@ internal sealed partial class Unpack : BitInput
|
|||
for (uint I = 0; I < Size; I++)
|
||||
{
|
||||
// Get the current bit length.
|
||||
var _CurBitLength = (byte)(LengthTable[offset + I] & 0xf);
|
||||
var _CurBitLength = (byte)(LengthTable[checked((int)(offset + I))] & 0xf);
|
||||
|
||||
if (_CurBitLength != 0)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue