private static void AllocateUncompressedBuffer(CompressedWorkItem compressedWorkItem) { Debug.Assert(compressedWorkItem.UncompressedSize != 0); // remember, our goal is to reduce the # of allocations done for compressedWorkItem.UncompressedBuffer // CompressedWorkItems are cached as a pool, and if our buffer size is large enough, we can // avoid a re-allocation. if (compressedWorkItem.UncompressedBuffer != null && compressedWorkItem.UncompressedBuffer.Length >= compressedWorkItem.UncompressedSize) { return; } // go a little more than we need to avoid // re-use needing to re-allocate. // works because our uncompressedsize shouldn't change much const float unscientificMultiplierGuess = 1.2f; var size = (int)(compressedWorkItem.UncompressedSize * unscientificMultiplierGuess); compressedWorkItem.UncompressedBuffer = new byte[size]; }
public void FreeCompressedWorkItem(ref CompressedWorkItem compressedItem) { // don't kill the big buffers. main point of this pool is to hopefully re-use them later. if (compressedItem == null) { return; } // keep the capacity, but kill the contents. // also, go a little overkill and kill the references to WorkItem list heads inside the List. if (compressedItem.ListHeads != null) { for (var i = 0; i < compressedItem.ListHeads.Count; ++i) { compressedItem.ListHeads[0] = null; } compressedItem.ListHeads.Clear(); } poolCompressedWorkItems?.Return(ref compressedItem); }
public void DecompressWorkItem(CompressedWorkItem compressedWorkItem) { Debug.Assert(!compressedWorkItem.WasDecompressed); AllocateUncompressedBuffer(compressedWorkItem); var decompressedLength = 0; using (var memory = new MemoryStream(compressedWorkItem.CompressedBuffer)) { using var inflater = new InflaterInputStream(memory); decompressedLength = inflater.Read(compressedWorkItem.UncompressedBuffer, 0, compressedWorkItem.UncompressedSize); } compressedWorkItem.WasDecompressed = true; if (decompressedLength != compressedWorkItem.UncompressedSize) { throw new InvalidDataException("incorrect decompressed data size"); } // after this function, compressedWorkItem.CompressedBuffer is no longer needed. // but, leave it allocated so future runs can re-use that buffer. }