internal int DecodeScalar(DataPacket packet) { int bits = (int)packet.TryPeekU64Bits(PrefixBitLength, out int bitCnt); if (bitCnt == 0) { return(-1); } // try to get the value from the prefix list... HuffmanNode node = PrefixList[bits]; if (node != null) { packet.SkipBits(node.Length); return(node.Value); } // nope, not possible... run the tree bits = (int)packet.TryPeekU64Bits(MaxBits, out _); node = PrefixOverflowTree; do { if (node.Bits == (bits & node.Mask)) { packet.SkipBits(node.Length); return(node.Value); } } while ((node = node.Next) != null); return(-1); }
public static void Return(HuffmanNode node) { if (node == null) { return; } if (node.IsInUse) { node.IsInUse = false; lock (_mutex) { Return(node.Next); node.Next = null; if (_pool.Count < MAX_NODES) { _pool.Push(node); } } } }
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); }