public void TestStreamDecompression() { MemoryStream memStream = new MemoryStream(); Random rnd = new Random(); byte[] original; byte[] decompressed; bool match; PatternCompressor compressor = new PatternCompressor { CompressedBuffer = new byte[4 * TotalTestSampleSize], CompressionStrength = 31 }; PatternDecompressor decompressor = new PatternDecompressor(); 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(); memStream = new MemoryStream(); decompressor.AugmentBuffer(compressor.CompressedBuffer, compressor.CompressedBufferLength); for (int i = 0; i < TotalTestSampleSize; i++) { uint value; decompressor.Decompress(out value); memStream.Write(BitConverter.GetBytes(value), 0, 4); } decompressed = memStream.ToArray(); match = original.Length == decompressed.Length; for (int i = 0; match && i < original.Length; i++) { match = original[i] == decompressed[i]; } Assert.AreEqual(original.Length, decompressed.Length); Assert.IsTrue(match); }
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); }
/// <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); }
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); }