protected virtual void Dispose(bool disposing) { if (!_disposed) { if (disposing) { HuffmanPool.Return(PrefixOverflowTree); PrefixOverflowTree = null; for (int i = 0; i < PrefixList.Length; i++) { HuffmanPool.Return(PrefixList[i]); } Array.Clear(PrefixList, 0, PrefixList.Length); PrefixList = null; Lengths = null; LookupTable = null; } _disposed = true; } }
static internal HuffmanNode[] BuildPrefixedLinkedList( Span <int> values, Span <int> lengthList, Span <int> codeList, out int tableBits, out HuffmanNode firstOverflowNode) { var list = new HuffmanNode[lengthList.Length]; int maxLen = 0; for (int i = 0; i < lengthList.Length; i++) { int nodeLength = lengthList[i] <= 0 ? 99999 : lengthList[i]; int mask = (1 << lengthList[i]) - 1; list[i] = HuffmanPool.Rent(values[i], nodeLength, codeList[i], mask); if (lengthList[i] > 0 && maxLen < lengthList[i]) { maxLen = lengthList[i]; } } tableBits = maxLen > MAX_TABLE_BITS ? MAX_TABLE_BITS : maxLen; var prefixList = new HuffmanNode[1 << tableBits]; Array.Sort(list, 0, lengthList.Length); firstOverflowNode = null; for (int i = 0; i < lengthList.Length && list[i].Length < 99999; i++) { if (firstOverflowNode == null) { HuffmanNode node = list[i]; node.IsLinked = true; if (node.Length > tableBits) { firstOverflowNode = node; } else { int maxVal = 1 << (tableBits - node.Length); for (int j = 0; j < maxVal; j++) { int idx = (j << node.Length) | node.Bits; prefixList[idx] = node; } } } else { list[i - 1].Next = list[i]; list[i].IsLinked = true; } } foreach (var node in list) { if (node != null && !node.IsLinked) { HuffmanPool.Return(node); } } return(prefixList); }