hackedteam/vector-edk

View on GitHub
vector-uefi/insyde/7zip/Java/SevenZip/LzmaBench.java

Summary

Maintainability
D
1 day
Test Coverage
package SevenZip;

import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;

public class LzmaBench
{
    static final int kAdditionalSize = (1 << 21);
    static final int kCompressedAdditionalSize = (1 << 10);
    
    static class CRandomGenerator
    {
        int A1;
        int A2;
        public CRandomGenerator() { Init(); }
        public void Init() { A1 = 362436069; A2 = 521288629; }
        public int GetRnd()
        {
            return
                ((A1 = 36969 * (A1 & 0xffff) + (A1 >>> 16)) << 16) ^
                ((A2 = 18000 * (A2 & 0xffff) + (A2 >>> 16)));
        }
    };
    
    static class CBitRandomGenerator
    {
        CRandomGenerator RG = new CRandomGenerator();
        int Value;
        int NumBits;
        public void Init()
        {
            Value = 0;
            NumBits = 0;
        }
        public int GetRnd(int numBits)
        {
            int result;
            if (NumBits > numBits)
            {
                result = Value & ((1 << numBits) - 1);
                Value >>>= numBits;
                NumBits -= numBits;
                return result;
            }
            numBits -= NumBits;
            result = (Value << numBits);
            Value = RG.GetRnd();
            result |= Value & (((int)1 << numBits) - 1);
            Value >>>= numBits;
            NumBits = 32 - numBits;
            return result;
        }
    };
    
    static class CBenchRandomGenerator
    {
        CBitRandomGenerator RG = new CBitRandomGenerator();
        int Pos;
        int Rep0;

        public int BufferSize;
        public byte[] Buffer = null;

        public CBenchRandomGenerator() { }
        public void Set(int bufferSize)
        {
            Buffer = new byte[bufferSize];
            Pos = 0;
            BufferSize = bufferSize;
        }
        int GetRndBit() { return RG.GetRnd(1); }
        int GetLogRandBits(int numBits)
        {
            int len = RG.GetRnd(numBits);
            return RG.GetRnd((int)len);
        }
        int GetOffset()
        {
            if (GetRndBit() == 0)
                return GetLogRandBits(4);
            return (GetLogRandBits(4) << 10) | RG.GetRnd(10);
        }
        int GetLen1() { return RG.GetRnd(1 + (int)RG.GetRnd(2)); }
        int GetLen2() { return RG.GetRnd(2 + (int)RG.GetRnd(2)); }
        public void Generate()
        {
            RG.Init();
            Rep0 = 1;
            while (Pos < BufferSize)
            {
                if (GetRndBit() == 0 || Pos < 1)
                    Buffer[Pos++] = (byte)(RG.GetRnd(8));
                else
                {
                    int len;
                    if (RG.GetRnd(3) == 0)
                        len = 1 + GetLen1();
                    else
                    {
                        do
                            Rep0 = GetOffset();
                        while (Rep0 >= Pos);
                        Rep0++;
                        len = 2 + GetLen2();
                    }
                    for (int i = 0; i < len && Pos < BufferSize; i++, Pos++)
                        Buffer[Pos] = Buffer[Pos - Rep0];
                }
            }
        }
    };
    
    static class CrcOutStream extends java.io.OutputStream
    {
        public CRC CRC = new CRC();
        
        public void Init()
        { 
            CRC.Init(); 
        }
        public int GetDigest()
        { 
            return CRC.GetDigest(); 
        }
        public void write(byte[] b)
        {
            CRC.Update(b);
        }
        public void write(byte[] b, int off, int len)
        {
            CRC.Update(b, off, len);
        }
        public void write(int b)
        {
            CRC.UpdateByte(b);
        }
    };

    static class MyOutputStream extends java.io.OutputStream
    {
        byte[] _buffer;
        int _size;
        int _pos;
        
        public MyOutputStream(byte[] buffer)
        {
            _buffer = buffer;
            _size = _buffer.length;
        }
        
        public void reset()
        { 
            _pos = 0; 
        }
        
        public void write(int b) throws IOException
        {
            if (_pos >= _size)
                throw new IOException("Error");
            _buffer[_pos++] = (byte)b;
        }
        
        public int size()
        {
            return _pos;
        }
    };

    static class MyInputStream extends java.io.InputStream
    {
        byte[] _buffer;
        int _size;
        int _pos;
        
        public MyInputStream(byte[] buffer, int size)
        {
            _buffer = buffer;
            _size = size;
        }
        
        public void reset()
        { 
            _pos = 0; 
        }
        
        public int read()
        {
            if (_pos >= _size)
                return -1;
            return _buffer[_pos++] & 0xFF;
        }
    };
    
    static class CProgressInfo implements ICodeProgress
    {
        public long ApprovedStart;
        public long InSize;
        public long Time;
        public void Init()
        { InSize = 0; }
        public void SetProgress(long inSize, long outSize)
        {
            if (inSize >= ApprovedStart && InSize == 0)
            {
                Time = System.currentTimeMillis();
                InSize = inSize;
            }
        }
    }
    static final int kSubBits = 8;
    
    static int GetLogSize(int size)
    {
        for (int i = kSubBits; i < 32; i++)
            for (int j = 0; j < (1 << kSubBits); j++)
                if (size <= ((1) << i) + (j << (i - kSubBits)))
                    return (i << kSubBits) + j;
        return (32 << kSubBits);
    }
    
    static long MyMultDiv64(long value, long elapsedTime)
    {
        long freq = 1000; // ms
        long elTime = elapsedTime;
        while (freq > 1000000)
        {
            freq >>>= 1;
            elTime >>>= 1;
        }
        if (elTime == 0)
            elTime = 1;
        return value * freq / elTime;
    }
    
    static long GetCompressRating(int dictionarySize, long elapsedTime, long size)
    {
        long t = GetLogSize(dictionarySize) - (18 << kSubBits);
        long numCommandsForOne = 1060 + ((t * t * 10) >> (2 * kSubBits));
        long numCommands = (long)(size) * numCommandsForOne;
        return MyMultDiv64(numCommands, elapsedTime);
    }
    
    static long GetDecompressRating(long elapsedTime, long outSize, long inSize)
    {
        long numCommands = inSize * 220 + outSize * 20;
        return MyMultDiv64(numCommands, elapsedTime);
    }
    
    static long GetTotalRating(
            int dictionarySize,
            long elapsedTimeEn, long sizeEn,
            long elapsedTimeDe,
            long inSizeDe, long outSizeDe)
    {
        return (GetCompressRating(dictionarySize, elapsedTimeEn, sizeEn) +
                GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2;
    }
    
    static void PrintValue(long v)
    {
        String s = "";
        s += v;
        for (int i = 0; i + s.length() < 6; i++)
            System.out.print(" ");
        System.out.print(s);
    }
    
    static void PrintRating(long rating)
    {
        PrintValue(rating / 1000000);
        System.out.print(" MIPS");
    }
    
    static void PrintResults(
            int dictionarySize,
            long elapsedTime,
            long size,
            boolean decompressMode, long secondSize)
    {
        long speed = MyMultDiv64(size, elapsedTime);
        PrintValue(speed / 1024);
        System.out.print(" KB/s  ");
        long rating;
        if (decompressMode)
            rating = GetDecompressRating(elapsedTime, size, secondSize);
        else
            rating = GetCompressRating(dictionarySize, elapsedTime, size);
        PrintRating(rating);
    }
    
    static public int LzmaBenchmark(int numIterations, int dictionarySize) throws Exception
    {
        if (numIterations <= 0)
            return 0;
        if (dictionarySize < (1 << 18))
        {
            System.out.println("\nError: dictionary size for benchmark must be >= 18 (256 KB)");
            return 1;
        }
        System.out.print("\n       Compressing                Decompressing\n\n");
        
        SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder();
        SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder();
        
        if (!encoder.SetDictionarySize(dictionarySize))
            throw new Exception("Incorrect dictionary size");
        
        int kBufferSize = dictionarySize + kAdditionalSize;
        int kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;
        
        ByteArrayOutputStream propStream = new ByteArrayOutputStream();
        encoder.WriteCoderProperties(propStream);
        byte[] propArray = propStream.toByteArray();
        decoder.SetDecoderProperties(propArray);
        
        CBenchRandomGenerator rg = new CBenchRandomGenerator();

        rg.Set(kBufferSize);
        rg.Generate();
        CRC crc = new CRC();
        crc.Init();
        crc.Update(rg.Buffer, 0, rg.BufferSize);
        
        CProgressInfo progressInfo = new CProgressInfo();
        progressInfo.ApprovedStart = dictionarySize;
        
        long totalBenchSize = 0;
        long totalEncodeTime = 0;
        long totalDecodeTime = 0;
        long totalCompressedSize = 0;
        
        MyInputStream inStream = new MyInputStream(rg.Buffer, rg.BufferSize);

        byte[] compressedBuffer = new byte[kCompressedBufferSize];
        MyOutputStream compressedStream = new MyOutputStream(compressedBuffer);
        CrcOutStream crcOutStream = new CrcOutStream();
        MyInputStream inputCompressedStream = null;
        int compressedSize = 0;
        for (int i = 0; i < numIterations; i++)
        {
            progressInfo.Init();
            inStream.reset();
            compressedStream.reset();
            encoder.Code(inStream, compressedStream, -1, -1, progressInfo);
            long encodeTime = System.currentTimeMillis() - progressInfo.Time;
            
            if (i == 0)
            {
                compressedSize = compressedStream.size();
                inputCompressedStream = new MyInputStream(compressedBuffer, compressedSize);
            }
            else if (compressedSize != compressedStream.size())
                throw (new Exception("Encoding error"));
                
            if (progressInfo.InSize == 0)
                throw (new Exception("Internal ERROR 1282"));

            long decodeTime = 0;
            for (int j = 0; j < 2; j++)
            {
                inputCompressedStream.reset();
                crcOutStream.Init();
                
                long outSize = kBufferSize;
                long startTime = System.currentTimeMillis();
                if (!decoder.Code(inputCompressedStream, crcOutStream, outSize))
                    throw (new Exception("Decoding Error"));;
                decodeTime = System.currentTimeMillis() - startTime;
                if (crcOutStream.GetDigest() != crc.GetDigest())
                    throw (new Exception("CRC Error"));
            }
            long benchSize = kBufferSize - (long)progressInfo.InSize;
            PrintResults(dictionarySize, encodeTime, benchSize, false, 0);
            System.out.print("     ");
            PrintResults(dictionarySize, decodeTime, kBufferSize, true, compressedSize);
            System.out.println();
            
            totalBenchSize += benchSize;
            totalEncodeTime += encodeTime;
            totalDecodeTime += decodeTime;
            totalCompressedSize += compressedSize;
        }
        System.out.println("---------------------------------------------------");
        PrintResults(dictionarySize, totalEncodeTime, totalBenchSize, false, 0);
        System.out.print("     ");
        PrintResults(dictionarySize, totalDecodeTime,
                kBufferSize * (long)numIterations, true, totalCompressedSize);
        System.out.println("    Average");
        return 0;
    }
}