using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Xml; using System.Xml.Linq; namespace StgSharp.Data { public class HuffmanTree where T : struct { HuffmanNodeList leaves; public TreeNode Root { get => leaves.Last; } public HuffmanNodeList LeafList { get => leaves; } internal HuffmanTree(HuffmanNodeList nodeList) { leaves = nodeList; } public static HuffmanTree BuildHuffmanTree(List<(T, ulong)> metaData) { if (metaData.Count<=3) { throw new Exception("Data is too little, no need to compress"); } HuffmanNodeList leaves = new HuffmanNodeList(); HuffmanNodeList all = new HuffmanNodeList(); foreach (var item in metaData) { leaves.Add(new TreeNode(item)); } int count = 0; while (leaves.Count >2) { TreeNode node, toMove; if (leaves.Last._frequency < leaves.BeforeLast._frequency) { if (leaves.BeforeLast._frequency < leaves.OverLast._frequency) { //第三节点最大 node = new TreeNode(leaves.BeforeLast, leaves.Last); toMove = leaves.RemoveAndGetLast; all.Add(toMove); toMove = leaves.RemoveAndGetLast; all.Add(toMove); leaves.Add(node); } else { //第二节点最大 node = leaves.Last._frequency < leaves.OverLast._frequency ? new TreeNode(leaves.OverLast, leaves.Last) : new TreeNode(leaves.Last, leaves.OverLast); toMove = leaves.RemoveAndGetLast; all.Add(toMove); toMove = leaves.RemoveAndGetBeforeLast; all.Add(toMove); leaves.Add(node); } } else { if (leaves.Last._frequency < leaves.OverLast._frequency) { //第三节点最大 node = new TreeNode(leaves.Last, leaves.BeforeLast); toMove = leaves.RemoveAndGetLast; all.Add(toMove); toMove = leaves.RemoveAndGetLast; all.Add(toMove); leaves.Add(node); } else { //第一节点最大 node = leaves.BeforeLast._frequency < leaves.OverLast._frequency? new TreeNode(leaves.OverLast, leaves.BeforeLast): new TreeNode(leaves.BeforeLast, leaves.OverLast); toMove = leaves.RemoveAndGetBeforeLast; all.Add(toMove); toMove = leaves.RemoveAndGetBeforeLast; all.Add(toMove); leaves.Add(node); } } leaves = new HuffmanNodeList( leaves.OrderByDescending(pair => pair.frequency) .Select(pair => pair).ToList()); } TreeNode lastOne = leaves[0]; TreeNode lastTwo = leaves[1]; TreeNode root = lastOne.frequency>lastTwo.frequency? new TreeNode(lastOne,lastTwo): new TreeNode(lastTwo, lastOne); all.Add(lastOne); all.Add(lastTwo); all.Add(root); leaves = all; return new HuffmanTree(all); } public Dictionary> BuildHuffmanDictionary() { Dictionary> ret = new Dictionary>(); TreeNode root = Root; HuffmanKey key = new HuffmanKey(); key = key.SetSide(KeySide.Right); InternalBuildDictionary(ret, root, key); return ret; } public void InternalBuildDictionary( Dictionary> dict, TreeNode node, HuffmanKey valueTemp ) { valueTemp.AddIndexLevel(); //检查左节点 if (node._left.Value==null) { //左节点不是叶子节点,继续搜索 InternalBuildDictionary( dict, node._left, valueTemp.SetSide(KeySide.Left)); } else { //左节点是叶子节点,添加值 dict.Add(node._left.Value.Value,valueTemp.SetSide(KeySide.Left)); } //检查右节点 if (node._right.Value == null) { //右节点不是叶子节点,继续搜索 InternalBuildDictionary( dict, node._right, valueTemp.SetSide(KeySide.Left)); } else { //右节点是叶子节点,添加值 dict.TryAdd(node._right.Value.Value, valueTemp.SetSide(KeySide.Right)); } //这里检查自己是不是叶子节点 //但是上面已经检查过了,不需要被检查 } } public struct HuffmanKeywhere T : struct { internal T value; public T Value { get { return value; } } internal HuffmanKey(T value) { this.value= value; } public unsafe HuffmanKey SetSide(KeySide side) { HuffmanKey ret = new HuffmanKey(value); T* p = &ret.value; switch (side) { case KeySide.Left: byte* ptrLeft = (byte*)p; *ptrLeft &= 0xfe; break; case KeySide.Right: byte* ptrRight = (byte*)p; *ptrRight |= 1; break; default: break; } Console.WriteLine(*(byte*)p); return ret; } public unsafe void AddIndexLevel() { fixed (T* p = &value) { switch (Marshal.SizeOf()) { case 1: *(byte*)p <<= 1; break; case 2: *(ushort*)p <<= 1; break; case 4: *(uint*)p <<= 1; break; case 8: *(ulong*)p <<= 1; break; case 16: #if NET7_0_OR_GREATER *(UInt128*)p <<= 1; #else ulong* hp = (ulong*)p; if (*hp != 0) { *hp <<= 1; } *hp += ((*(ulong*)p) & 0x80_00_00_00_00_00_00_00) == 0 ? (ulong)0 : 1; *(ulong*)p <<= 1; #endif break; default: break; } } } public bool IsSupported { get { return typeof(T) == typeof(byte) || typeof(T) == typeof(uint) || typeof(T) == typeof(ushort) || typeof(T) == typeof(ulong) || #if NET7_0_OR_GREATER typeof(T) == typeof(UInt128) || #endif typeof(T) == typeof(M128); } } } public enum KeySide { Left, Right } public class HuffmanNodeList : List> where T : struct { public HuffmanNodeList():base() { } public HuffmanNodeList(IEnumerable> values):base(values) {} public void Add(T element, ulong f) { base.Add(new TreeNode(element,f)); } public TreeNode Last { get => this[Count-1 ]; } public TreeNode RemoveAndGetLast { get { TreeNode ret = this[Count-1]; RemoveAt(Count-1); return ret; } } public TreeNode BeforeLast { get => this[Count - 2]; } public TreeNode RemoveAndGetBeforeLast { get { TreeNode ret = this[Count - 2]; RemoveAt(Count - 2); return ret; } } public TreeNode OverLast { get => this[Count - 3]; } public TreeNode RemoveAndGetOverLast { get { TreeNode ret = this[Count - 3]; RemoveAt(Count - 3); return ret; } } } public class TreeNode where T: struct { internal TreeNode _left; internal TreeNode _right; internal T? _value; internal ulong _frequency; public ulong frequency => _frequency; public T? Value => _value; public TreeNode Left => _left; public TreeNode Right => _right; public TreeNode( T? value, ulong frequncy) { _value = value; _frequency = frequncy; } internal TreeNode(TreeNode left, TreeNode right) { _left = left; _right = right; _value = null; _frequency = left._frequency + right._frequency; } public TreeNode((T, ulong) data) { _value = data.Item1; _frequency = data.Item2; } } }