Пример #1
0
        public void TestDecompressionOfStreamCompression()
        {
            MemoryStream memStream = new MemoryStream();
            Random       rnd       = new Random();

            byte[] original;
            byte[] decompressed;
            int    decompressedLen;

            bool match;

            PatternCompressor compressor = new PatternCompressor
            {
                CompressedBuffer    = new byte[4 * TotalTestSampleSize],
                CompressionStrength = 31
            };

            for (int i = 0; i < TotalTestSampleSize; i++)
            {
                uint value = (uint)(rnd.NextDouble() * 100000);
                memStream.Write(BitConverter.GetBytes(value), 0, 4);
                compressor.Compress(value);
            }

            original     = memStream.ToArray();
            decompressed = new byte[PatternDecompressor.MaximumSizeDecompressed(compressor.CompressedBufferLength)];
            Buffer.BlockCopy(compressor.CompressedBuffer, 0, decompressed, 0, compressor.CompressedBufferLength);
            decompressedLen = PatternDecompressor.DecompressBuffer(decompressed, 0, compressor.CompressedBufferLength, decompressed.Length);

            match = decompressedLen == original.Length;
            for (int i = 0; match && i < decompressedLen; i++)
            {
                match = decompressed[i] == original[i];
            }

            Assert.AreEqual(original.Length, decompressedLen);
            Assert.IsTrue(match);
        }
Пример #2
0
        /// <summary>
        /// Decompresses <see cref="CompactMeasurement"/> values from the given <paramref name="source"/> buffer.
        /// </summary>
        /// <param name="source">Buffer with compressed <see cref="CompactMeasurement"/> payload.</param>
        /// <param name="signalIndexCache">Current <see cref="SignalIndexCache"/>.</param>
        /// <param name="index">Index into buffer where compressed payload begins.</param>
        /// <param name="dataLength">Length of all data within <paramref name="source"/> buffer.</param>
        /// <param name="measurementCount">Number of compressed measurements in the payload.</param>
        /// <param name="includeTime">Flag that determines if timestamps as included in the payload.</param>
        /// <param name="flags">Current <see cref="DataPacketFlags"/>.</param>
        /// <returns>Decompressed <see cref="CompactMeasurement"/> values from the given <paramref name="source"/> buffer.</returns>
        public static CompactMeasurement[] DecompressPayload(this byte[] source, SignalIndexCache signalIndexCache, int index, int dataLength, int measurementCount, bool includeTime, DataPacketFlags flags)
        {
            CompactMeasurement[] measurements = new CompactMeasurement[measurementCount];

            // Actual data length has to take into account response byte and in-response-to server command byte in the payload header
            //int dataLength = length - index - 2;
            int bufferLength = PatternDecompressor.MaximumSizeDecompressed(dataLength);

            // Copy source data into a decompression buffer
            byte[] buffer = new byte[bufferLength];
            Buffer.BlockCopy(source, index, buffer, 0, dataLength);

            // Check that OS endian-order matches endian-order of compressed data
            if (!(BitConverter.IsLittleEndian && (flags & DataPacketFlags.LittleEndianCompression) > 0))
            {
                // can be modified to decompress a payload that is in a non-native Endian order
                throw new NotImplementedException("Cannot currently decompress payload that is not in native endian-order.");
            }

            // Attempt to decompress buffer
            int uncompressedSize = PatternDecompressor.DecompressBuffer(buffer, 0, dataLength, bufferLength);

            if (uncompressedSize == 0)
            {
                throw new InvalidOperationException("Failed to decompress payload buffer - possible data corruption.");
            }

            index = 0;

            // Decode ID and state flags
            for (int i = 0; i < measurementCount; i++)
            {
                uint value = NativeEndianOrder.Default.ToUInt32(buffer, index);

                measurements[i] = new CompactMeasurement(signalIndexCache, includeTime)
                {
                    CompactStateFlags = (byte)(value >> 16),
                    RuntimeID         = (ushort)value
                };

                index += 4;
            }

            // Decode values
            for (int i = 0; i < measurementCount; i++)
            {
                measurements[i].Value = NativeEndianOrder.Default.ToSingle(buffer, index);
                index += 4;
            }

            if (includeTime)
            {
                // Decode timestamps
                for (int i = 0; i < measurementCount; i++)
                {
                    measurements[i].Timestamp = NativeEndianOrder.Default.ToInt64(buffer, index);
                    index += 8;
                }
            }

            return(measurements);
        }
Пример #3
0
        public void TestArrayOfIntCompressionOnRandomData()
        {
            StringBuilder results = new StringBuilder();
            MemoryStream  buffer  = new MemoryStream();
            Random        rnd     = new Random();

            uint value;

            for (int i = 0; i < TotalTestSampleSize; i++)
            {
                value = (uint)(rnd.NextDouble() * 100000);
                buffer.Write(BitConverter.GetBytes(value), 0, 4);
            }

            // Add one byte of extra space to accommodate compression algorithm
            buffer.WriteByte(0xFF);

            byte[] arrayOfInts = buffer.ToArray();
            byte[] copy        = arrayOfInts.BlockCopy(0, arrayOfInts.Length);

            int bufferLen = arrayOfInts.Length;
            int dataLen = bufferLen - 1;
            int gzipLen = arrayOfInts.Compress().Length;
            int compressedLen, decompressedLen, maxDecompressedLen;

            Ticks compressTime, decompressTime;
            Ticks stopTime, startTime;

            bool lossless;

            // Make sure a buffer exists in the buffer pool so that operation time will not be skewed by buffer initialization:
            startTime = DateTime.UtcNow.Ticks;
            BufferPool.ReturnBuffer(BufferPool.TakeBuffer(dataLen + TotalTestSampleSize));
            stopTime = DateTime.UtcNow.Ticks;
            results.AppendFormat("Buffer Pool initial take time: {0}\r\n", (stopTime - startTime).ToElapsedTimeString(4));

            startTime = DateTime.UtcNow.Ticks;
            BufferPool.ReturnBuffer(BufferPool.TakeBuffer(dataLen + TotalTestSampleSize));
            stopTime = DateTime.UtcNow.Ticks;
            results.AppendFormat("Buffer Pool cached take time: {0}\r\n\r\n", (stopTime - startTime).ToElapsedTimeString(4));

            startTime     = DateTime.UtcNow.Ticks;
            compressedLen = PatternCompressor.CompressBuffer(arrayOfInts, 0, dataLen, bufferLen, 31);
            stopTime      = DateTime.UtcNow.Ticks;
            compressTime  = stopTime - startTime;

            maxDecompressedLen = PatternDecompressor.MaximumSizeDecompressed(compressedLen);
            if (arrayOfInts.Length < maxDecompressedLen)
            {
                byte[] temp = new byte[maxDecompressedLen];
                Buffer.BlockCopy(arrayOfInts, 0, temp, 0, compressedLen);
                arrayOfInts = temp;
            }

            startTime       = DateTime.UtcNow.Ticks;
            decompressedLen = PatternDecompressor.DecompressBuffer(arrayOfInts, 0, compressedLen, maxDecompressedLen);
            stopTime        = DateTime.UtcNow.Ticks;
            decompressTime  = stopTime - startTime;

            lossless = decompressedLen == dataLen;
            for (int i = 0; lossless && i < Math.Min(decompressedLen, dataLen); i++)
            {
                lossless = arrayOfInts[i] == copy[i];
            }

            // Publish results to debug window
            results.AppendFormat("Results of floating point compression algorithm over sequential data:\r\n\r\n");
            results.AppendFormat("Total number of samples:  \t{0:#,##0}\r\n", TotalTestSampleSize);
            results.AppendFormat("Total number of bytes:    \t{0:#,##0}\r\n", dataLen);
            results.AppendFormat("Total compression time:   \t{0}\r\n", compressTime.ToElapsedTimeString(4));
            results.AppendFormat("Compression speed:        \t{0:#,##0.0000} MB/sec\r\n", (dataLen / (double)SI2.Mega) / compressTime.ToSeconds());
            results.AppendFormat("Total decompression time: \t{0}\r\n", decompressTime.ToElapsedTimeString(4));
            results.AppendFormat("Decompression speed:      \t{0:#,##0.0000} MB/sec\r\n", (dataLen / (double)SI2.Mega) / decompressTime.ToSeconds());
            results.AppendFormat("Compression results:      \t{0:0.00%}\r\n", (dataLen - compressedLen) / (double)dataLen);
            results.AppendFormat("Standard gzip results:    \t{0:0.00%}\r\n", (dataLen - gzipLen) / (double)dataLen);
            Debug.WriteLine(results.ToString());

            Assert.AreEqual(dataLen, decompressedLen);
            Assert.IsTrue(lossless);
        }