using System; using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; using Unity.Collections; namespace Convention.Collections { namespace Generic { /// /// 附带有缓存机制的链表类 /// /// 指定链表的元素类型 public sealed class LinkedCacheList : ICollection, IEnumerable, ICollection, IEnumerable { private readonly LinkedList m_LinkedList; /// /// 之所以需要这套缓存机制,主要有三点好处: /// 减少 GC 压力:大量频繁的插入/删除会产生很多短生命周期的节点对象,通过复用可以显著降低托管堆的分配与回收次数 /// 提升性能:避免频繁 new 和 GC,能减少停顿时间,提高链表在高频操作场景下的吞吐 /// 便于观察与管理:类中还提供了 CachedNodeCount 方便调试统计缓存规模,必要时可通过 ClearCachedNodes 主动释放 /// 适用场景是节点使用模式“高频增删但总量有限”,此时缓存能稳定性能;若链表规模始终在增长且很少释放,缓存收益会较低。 /// private readonly Queue> m_CachedNodes; /// /// 初始化游戏框架链表类的新实例 /// public LinkedCacheList() { m_LinkedList = new LinkedList(); m_CachedNodes = new Queue>(); } /// /// 获取链表中实际包含的结点数量 /// public int Count { get { return m_LinkedList.Count; } } /// /// 获取链表结点缓存数量 /// public int CachedNodeCount { get { return m_CachedNodes.Count; } } /// /// 获取链表的第一个结点 /// public LinkedListNode First { get { return m_LinkedList.First; } } /// /// 获取链表的最后一个结点 /// public LinkedListNode Last { get { return m_LinkedList.Last; } } /// /// 获取一个值,该值指示 是否为只读 /// public bool IsReadOnly { get { return ((ICollection)m_LinkedList).IsReadOnly; } } /// /// 获取可用于同步对 的访问的对象。 /// public object SyncRoot { get { return ((ICollection)m_LinkedList).SyncRoot; } } /// /// 获取一个值,该值指示是否同步对 的访问(线程安全)。 /// public bool IsSynchronized { get { return ((ICollection)m_LinkedList).IsSynchronized; } } /// /// 在链表中指定的现有结点后添加包含指定值的新结点 /// /// 指定的现有结点 /// 指定值 /// 包含指定值的新结点 public LinkedListNode AddAfter(LinkedListNode node, T value) { LinkedListNode newNode = AcquireNode(value); m_LinkedList.AddAfter(node, newNode); return newNode; } /// /// 在链表中指定的现有结点后添加指定的新结点 /// /// 指定的现有结点 /// 指定的新结点 public void AddAfter(LinkedListNode node, LinkedListNode newNode) { m_LinkedList.AddAfter(node, newNode); } /// /// 在链表中指定的现有结点前添加包含指定值的新结点 /// /// 指定的现有结点 /// 指定值 /// 包含指定值的新结点 public LinkedListNode AddBefore(LinkedListNode node, T value) { LinkedListNode newNode = AcquireNode(value); m_LinkedList.AddBefore(node, newNode); return newNode; } /// /// 在链表中指定的现有结点前添加指定的新结点 /// /// 指定的现有结点 /// 指定的新结点 public void AddBefore(LinkedListNode node, LinkedListNode newNode) { m_LinkedList.AddBefore(node, newNode); } /// /// 在链表的开头处添加包含指定值的新结点 /// /// 指定值 /// 包含指定值的新结点 public LinkedListNode AddFirst(T value) { LinkedListNode node = AcquireNode(value); m_LinkedList.AddFirst(node); return node; } /// /// 在链表的开头处添加指定的新结点 /// /// 指定的新结点 public void AddFirst(LinkedListNode node) { m_LinkedList.AddFirst(node); } /// /// 在链表的结尾处添加包含指定值的新结点 /// /// 指定值 /// 包含指定值的新结点 public LinkedListNode AddLast(T value) { LinkedListNode node = AcquireNode(value); m_LinkedList.AddLast(node); return node; } /// /// 在链表的结尾处添加指定的新结点 /// /// 指定的新结点 public void AddLast(LinkedListNode node) { m_LinkedList.AddLast(node); } /// /// 从链表中移除所有结点 /// public void Clear() { LinkedListNode current = m_LinkedList.First; while (current != null) { ReleaseNode(current); current = current.Next; } m_LinkedList.Clear(); } /// /// 清除链表结点缓存 /// public void ClearCachedNodes() { m_CachedNodes.Clear(); } /// /// 确定某值是否在链表中 /// /// 指定值 /// 某值是否在链表中 public bool Contains(T value) { return m_LinkedList.Contains(value); } /// /// 从目标数组的指定索引处开始将整个链表复制到兼容的一维数组 /// /// 一维数组,它是从链表复制的元素的目标。数组必须具有从零开始的索引 /// array 中从零开始的索引,从此处开始复制 public void CopyTo(T[] array, int index) { m_LinkedList.CopyTo(array, index); } /// /// 从特定的 ICollection 索引开始,将数组的元素复制到一个数组中 /// /// 一维数组,它是从 ICollection 复制的元素的目标。数组必须具有从零开始的索引 /// array 中从零开始的索引,从此处开始复制 public void CopyTo(Array array, int index) { ((ICollection)m_LinkedList).CopyTo(array, index); } /// /// 查找包含指定值的第一个结点 /// /// 要查找的指定值 /// 包含指定值的第一个结点 public LinkedListNode Find(T value) { return m_LinkedList.Find(value); } /// /// 查找包含指定值的最后一个结点 /// /// 要查找的指定值 /// 包含指定值的最后一个结点 public LinkedListNode FindLast(T value) { return m_LinkedList.FindLast(value); } /// /// 从链表中移除指定值的第一个匹配项 /// /// 指定值 /// 是否移除成功 public bool Remove(T value) { LinkedListNode node = m_LinkedList.Find(value); if (node != null) { m_LinkedList.Remove(node); ReleaseNode(node); return true; } return false; } /// /// 从链表中移除指定的结点 /// /// 指定的结点 public void Remove(LinkedListNode node) { m_LinkedList.Remove(node); ReleaseNode(node); } /// /// 移除位于链表开头处的结点 /// public void RemoveFirst() { LinkedListNode first = m_LinkedList.First; if (first == null) { throw new InvalidOperationException("Rmove first is invalid."); } m_LinkedList.RemoveFirst(); ReleaseNode(first); } /// /// 移除位于链表结尾处的结点。 /// public void RemoveLast() { LinkedListNode last = m_LinkedList.Last; if (last == null) { throw new InvalidOperationException("Remove last is invalid."); } m_LinkedList.RemoveLast(); ReleaseNode(last); } /// /// 返回循环访问集合的枚举数 /// /// 循环访问集合的枚举数 public Enumerator GetEnumerator() { return new Enumerator(m_LinkedList); } private LinkedListNode AcquireNode(T value) { LinkedListNode node = null; if (m_CachedNodes.Count > 0) { node = m_CachedNodes.Dequeue(); node.Value = value; } else { node = new LinkedListNode(value); } return node; } private void ReleaseNode(LinkedListNode node) { node.Value = default(T); m_CachedNodes.Enqueue(node); } /// /// 将值添加到 ICollection`1 的结尾处 /// /// 要添加的值 void ICollection.Add(T value) { AddLast(value); } /// /// 返回循环访问集合的枚举数 /// /// 循环访问集合的枚举数 IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// /// 返回循环访问集合的枚举数 /// /// 循环访问集合的枚举数 IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// /// 循环访问集合的枚举数 /// [StructLayout(LayoutKind.Auto)] public struct Enumerator : IEnumerator, IEnumerator { private LinkedList.Enumerator m_Enumerator; internal Enumerator(LinkedList linkedList) { if (linkedList == null) { throw new InvalidOperationException("Linked list is invalid."); } m_Enumerator = linkedList.GetEnumerator(); } /// /// 获取当前结点 /// public T Current { get { return m_Enumerator.Current; } } /// /// 获取当前的枚举数 /// object IEnumerator.Current { get { return m_Enumerator.Current; } } /// /// 清理枚举数 /// public void Dispose() { m_Enumerator.Dispose(); } /// /// 获取下一个结点 /// /// 返回下一个结点 public bool MoveNext() { return m_Enumerator.MoveNext(); } /// /// 重置枚举数 /// void IEnumerator.Reset() { ((IEnumerator)m_Enumerator).Reset(); } } } } namespace Cache { /// /// Native LRUCache - 基于Unity.Collections的高性能最近最少使用缓存 /// Burst兼容,需要手动Dispose /// /// 键类型(必须是unmanaged类型) /// 值类型(必须是unmanaged类型) public struct NativeLRUCache : IDisposable where TKey : unmanaged, IEquatable where TValue : unmanaged { // 链表节点 private struct Node { public TKey key; public TValue value; public int prevIndex; // 前一个节点索引 public int nextIndex; // 后一个节点索引 } private NativeList nodes; // 节点池 private readonly NativeHashMap hashMap; // key -> 节点索引 private readonly NativeList freeList; // 空闲节点索引池 private readonly int capacity; private int headIndex; // 链表头(最久未使用) private int tailIndex; // 链表尾(最近使用) private int count; // 是否为有效节点索引 private readonly bool IsValidIndex(int index) => index >= 0; public NativeLRUCache(int capacity, Allocator allocator) { this.capacity = capacity; this.count = 0; this.headIndex = -1; this.tailIndex = -1; hashMap = new NativeHashMap(capacity, allocator); nodes = new NativeList(capacity, allocator); freeList = new NativeList(capacity, allocator); // 预分配节点池 nodes.Length = capacity; for (int i = capacity - 1; i >= 0; i--) { freeList.Add(i); } } /// /// 获取缓存值 /// public bool TryGetValue(TKey key, out TValue value) { if (hashMap.TryGetValue(key, out int nodeIndex)) { MoveToTail(nodeIndex); // 移动到尾部(最近使用) value = nodes[nodeIndex].value; return true; } value = default; return false; } /// /// 添加或更新缓存 /// public void Put(TKey key, TValue value) { // 已存在则更新并移动到尾部 if (hashMap.TryGetValue(key, out int nodeIndex)) { Node node = nodes[nodeIndex]; node.value = value; nodes[nodeIndex] = node; MoveToTail(nodeIndex); return; } // 容量已满,淘汰头部节点 if (count >= capacity) { EvictHead(); } // 创建新节点 nodeIndex = AllocateNode(); nodes[nodeIndex] = new Node { key = key, value = value, prevIndex = tailIndex, nextIndex = -1 }; hashMap.Add(key, nodeIndex); AddToTail(nodeIndex); count++; } /// /// 删除缓存项 /// public bool Remove(TKey key) { if (!hashMap.TryGetValue(key, out int nodeIndex)) return false; hashMap.Remove(key); RemoveFromList(nodeIndex); FreeNode(nodeIndex); count--; return true; } /// /// 清空缓存 /// public void Clear() { hashMap.Clear(); // 重置所有节点到空闲列表 freeList.Clear(); for (int i = 0; i < capacity; i++) { freeList.Add(i); } headIndex = -1; tailIndex = -1; count = 0; } // 分配节点索引 private readonly int AllocateNode() { int index = freeList[^1]; freeList.RemoveAtSwapBack(freeList.Length - 1); return index; } // 释放节点索引 private readonly void FreeNode(int index) { freeList.Add(index); } // 将节点移动到链表尾部(标记为最近使用) private void MoveToTail(int nodeIndex) { if (nodeIndex == tailIndex) return; RemoveFromList(nodeIndex); AddToTail(nodeIndex); } // 将节点添加到尾部 private void AddToTail(int nodeIndex) { Node node = nodes[nodeIndex]; node.prevIndex = tailIndex; node.nextIndex = -1; nodes[nodeIndex] = node; if (IsValidIndex(tailIndex)) { Node tail = nodes[tailIndex]; tail.nextIndex = nodeIndex; nodes[tailIndex] = tail; } tailIndex = nodeIndex; // 如果链表为空,头尾指向同一节点 if (!IsValidIndex(headIndex)) { headIndex = nodeIndex; } } // 从链表中移除节点 private void RemoveFromList(int nodeIndex) { Node node = nodes[nodeIndex]; // 更新前一个节点的next指针 if (IsValidIndex(node.prevIndex)) { Node prev = nodes[node.prevIndex]; prev.nextIndex = node.nextIndex; nodes[node.prevIndex] = prev; } else { // 没有前一个节点,说明是头节点 headIndex = node.nextIndex; } // 更新后一个节点的prev指针 if (IsValidIndex(node.nextIndex)) { Node next = nodes[node.nextIndex]; next.prevIndex = node.prevIndex; nodes[node.nextIndex] = next; } else { // 没有后一个节点,说明是尾节点 tailIndex = node.prevIndex; } } // 淘汰头部节点(最久未使用) private void EvictHead() { if (!IsValidIndex(headIndex)) return; int oldHead = headIndex; Node headNode = nodes[oldHead]; hashMap.Remove(headNode.key); headIndex = headNode.nextIndex; if (IsValidIndex(headIndex)) { Node newHead = nodes[headIndex]; newHead.prevIndex = -1; nodes[headIndex] = newHead; } else { tailIndex = -1; // 链表为空 } FreeNode(oldHead); count--; } public void Dispose() { if (hashMap.IsCreated) hashMap.Dispose(); if (nodes.IsCreated) nodes.Dispose(); if (freeList.IsCreated) freeList.Dispose(); headIndex = -1; tailIndex = -1; count = 0; } // 属性访问器 public readonly int Count => count; public readonly int Capacity => capacity; public readonly bool IsCreated => hashMap.IsCreated; } /// /// Native LFUCache - 基于Unity.Collections的高性能最不频繁使用缓存 /// Burst兼容,需要手动Dispose /// /// 键类型(必须是unmanaged类型) /// 值类型(必须是unmanaged类型) public struct NativeLFUCache : IDisposable where TKey : unmanaged, IEquatable where TValue : unmanaged { // 缓存节点 private struct Node { public TKey key; public TValue value; public int frequency; // 访问频率 public int prevIndex; // 同频率链表中的前一个节点 public int nextIndex; // 同频率链表中的后一个节点 } // 频率链表头尾 private struct FrequencyList { public int headIndex; // 该频率链表的头节点(最久未使用) public int tailIndex; // 该频率链表的尾节点(最近使用) public readonly bool IsEmpty => headIndex == -1; } private readonly NativeHashMap keyToNodeIndex; // key -> nodeIndex private NativeList nodes; // 节点池 private readonly NativeList freeList; // 空闲节点索引 private NativeHashMap freqToList; // frequency -> FrequencyList private readonly int capacity; private int count; private int minFrequency; // 当前最小频率 public NativeLFUCache(int capacity, Allocator allocator) { this.capacity = capacity; this.count = 0; this.minFrequency = 0; keyToNodeIndex = new NativeHashMap(capacity, allocator); nodes = new NativeList(capacity, allocator); freeList = new NativeList(capacity, allocator); freqToList = new NativeHashMap(capacity, allocator); // 预分配节点池 nodes.Length = capacity; for (int i = capacity - 1; i >= 0; i--) { freeList.Add(i); } } /// /// 获取缓存值并增加频率 /// public bool TryGetValue(TKey key, out TValue value) { if (keyToNodeIndex.TryGetValue(key, out int nodeIndex)) { // 增加访问频率 IncreaseFrequency(nodeIndex); value = nodes[nodeIndex].value; return true; } value = default; return false; } /// /// 添加或更新缓存 /// public void Put(TKey key, TValue value) { // 更新现有值 if (keyToNodeIndex.TryGetValue(key, out int nodeIndex)) { Node node = nodes[nodeIndex]; node.value = value; nodes[nodeIndex] = node; IncreaseFrequency(nodeIndex); return; } // 容量已满,淘汰最小频率的节点 if (count >= capacity) { EvictMinFrequencyNode(); } // 创建新节点,初始频率为1 nodeIndex = AllocateNode(); nodes[nodeIndex] = new Node { key = key, value = value, frequency = 1, prevIndex = -1, nextIndex = -1 }; keyToNodeIndex.Add(key, nodeIndex); AddToFrequencyList(nodeIndex, 1); // 更新最小频率 if (minFrequency == 0) { minFrequency = 1; } count++; } /// /// 删除缓存项 /// public bool Remove(TKey key) { if (!keyToNodeIndex.TryGetValue(key, out int nodeIndex)) return false; RemoveNode(nodeIndex); return true; } /// /// 清空缓存 /// public void Clear() { keyToNodeIndex.Clear(); freqToList.Clear(); // 重置所有节点到空闲列表 freeList.Clear(); for (int i = 0; i < capacity; i++) { freeList.Add(i); } minFrequency = 0; count = 0; } /// /// 释放所有内存 /// public void Dispose() { if (keyToNodeIndex.IsCreated) keyToNodeIndex.Dispose(); if (nodes.IsCreated) nodes.Dispose(); if (freeList.IsCreated) freeList.Dispose(); if (freqToList.IsCreated) freqToList.Dispose(); minFrequency = 0; count = 0; } #region 内部辅助方法 private int AllocateNode() { int index = freeList[^1]; freeList.RemoveAtSwapBack(freeList.Length - 1); return index; } private void FreeNode(int index) { freeList.Add(index); } /// /// 增加节点的访问频率 /// private void IncreaseFrequency(int nodeIndex) { Node node = nodes[nodeIndex]; int oldFreq = node.frequency; int newFreq = oldFreq + 1; // 从旧频率链表移除 RemoveFromFrequencyList(nodeIndex, oldFreq); // 检查是否需要更新最小频率 if (oldFreq == minFrequency && GetFrequencyListHead(oldFreq) == -1) { minFrequency = newFreq; } // 更新节点频率 node.frequency = newFreq; nodes[nodeIndex] = node; // 添加到新频率链表 AddToFrequencyList(nodeIndex, newFreq); } /// /// 从频率链表中移除节点 /// private void RemoveFromFrequencyList(int nodeIndex, int frequency) { if (!freqToList.TryGetValue(frequency, out var list)) return; Node node = nodes[nodeIndex]; // 如果是头节点 if (node.prevIndex == -1) { list.headIndex = node.nextIndex; } else { // 更新前一个节点的next指针 Node prevNode = nodes[node.prevIndex]; prevNode.nextIndex = node.nextIndex; nodes[node.prevIndex] = prevNode; } // 如果是尾节点 if (node.nextIndex == -1) { list.tailIndex = node.prevIndex; } else { // 更新后一个节点的prev指针 Node nextNode = nodes[node.nextIndex]; nextNode.prevIndex = node.prevIndex; nodes[node.nextIndex] = nextNode; } // 如果链表变空,移除该频率 if (list.headIndex == -1) { freqToList.Remove(frequency); } else { freqToList[frequency] = list; } } /// /// 将节点添加到频率链表尾部 /// private void AddToFrequencyList(int nodeIndex, int frequency) { if (!freqToList.TryGetValue(frequency, out var list)) { // 创建新的频率链表 list = new FrequencyList { headIndex = nodeIndex, tailIndex = nodeIndex }; freqToList.Add(frequency, list); // 设置节点指针 Node node = nodes[nodeIndex]; node.prevIndex = -1; node.nextIndex = -1; nodes[nodeIndex] = node; } else { // 添加到链表尾部 int oldTail = list.tailIndex; // 更新原尾节点 Node oldTailNode = nodes[oldTail]; oldTailNode.nextIndex = nodeIndex; nodes[oldTail] = oldTailNode; // 设置新节点 Node newNode = nodes[nodeIndex]; newNode.prevIndex = oldTail; newNode.nextIndex = -1; nodes[nodeIndex] = newNode; // 更新链表尾 list.tailIndex = nodeIndex; freqToList[frequency] = list; } } /// /// 获取频率链表的头节点 /// private int GetFrequencyListHead(int frequency) { if (freqToList.TryGetValue(frequency, out var list)) { return list.headIndex; } return -1; } /// /// 淘汰最小频率的节点(淘汰该频率链表的头节点) /// private void EvictMinFrequencyNode() { // 找到有节点的最小频率 while (minFrequency <= capacity && GetFrequencyListHead(minFrequency) == -1) { minFrequency++; } if (minFrequency > capacity) return; int headIndex = GetFrequencyListHead(minFrequency); if (headIndex == -1) return; RemoveNode(headIndex); } /// /// 移除完整节点(从所有数据结构中删除) /// private void RemoveNode(int nodeIndex) { Node node = nodes[nodeIndex]; // 从频率链表移除 RemoveFromFrequencyList(nodeIndex, node.frequency); // 从主HashMap移除 keyToNodeIndex.Remove(node.key); // 回收节点 FreeNode(nodeIndex); count--; } #endregion // 属性访问器 public readonly int Count => count; public readonly int Capacity => capacity; public readonly bool IsCreated => keyToNodeIndex.IsCreated; } public struct NativeARCCache : IDisposable where TKey : unmanaged, IEquatable where TValue : unmanaged { private const int LIST_T1 = 0, LIST_T2 = 1, LIST_B1 = 2, LIST_B2 = 3; private struct Node { public TKey key; public TValue value; public byte listType; public int prevIndex; public int nextIndex; } private NativeHashMap keyToNode; private NativeList nodes; private NativeList freeList; // 四个链表头尾指针 private int t1Head, t1Tail, t2Head, t2Tail, b1Head, b1Tail, b2Head, b2Tail; private int capacity, t1Count, t2Count, b1Count, b2Count, p; public NativeARCCache(int capacity, Allocator allocator) { this.capacity = capacity; this.t1Count = this.t2Count = this.b1Count = this.b2Count = 0; this.p = 0; t1Head = t1Tail = t2Head = t2Tail = -1; b1Head = b1Tail = b2Head = b2Tail = -1; int totalNodes = capacity * 2; keyToNode = new NativeHashMap(totalNodes, allocator); nodes = new NativeList(totalNodes, allocator); freeList = new NativeList(totalNodes, allocator); nodes.Length = totalNodes; for (int i = totalNodes - 1; i >= 0; i--) { freeList.Add(i); } } public bool TryGetValue(TKey key, out TValue value) { if (keyToNode.TryGetValue(key, out int nodeIndex)) { Node node = nodes[nodeIndex]; // 先读取 if (node.listType == LIST_T1 || node.listType == LIST_T2) { MoveToMRU(nodeIndex, LIST_T2); value = node.value; return true; } if (node.listType == LIST_B1) { node = ComputeNewPAndReplace(node, b2Count, b1Count, true); b1Count--; t2Count++; value = node.value; return true; } if (node.listType == LIST_B2) { node = ComputeNewPAndReplace(node, b1Count, b2Count, false); b2Count--; t2Count++; value = node.value; return true; } } value = default; return false; } public void Put(TKey key, TValue value) { if (keyToNode.TryGetValue(key, out int nodeIndex)) { Node node = nodes[nodeIndex]; node.value = value; if (node.listType == LIST_T1 || node.listType == LIST_T2) { MoveToMRU(nodeIndex, LIST_T2); } else if (node.listType == LIST_B1) { node = ComputeNewPAndReplace(node, b2Count, b1Count, true); b1Count--; t2Count++; } else if (node.listType == LIST_B2) { node = ComputeNewPAndReplace(node, b1Count, b2Count, false); b2Count--; t2Count++; } nodes[nodeIndex] = node; // 写回 return; } // 容量满,执行Replace int totalSize = t1Count + t2Count; if (totalSize >= capacity) { Replace(); } // 创建新节点到T1 nodeIndex = AllocateNode(); nodes[nodeIndex] = new Node { key = key, value = value, listType = LIST_T1, prevIndex = -1, nextIndex = -1 }; keyToNode.Add(key, nodeIndex); AddToHead(nodeIndex, LIST_T1); t1Count++; } private Node ComputeNewPAndReplace(Node node, int oppositeCount, int sameCount, bool isB1) { int delta = (oppositeCount >= sameCount) ? 1 : oppositeCount / sameCount + 1; // 先修改p值 if (isB1) p = Math.Min(p + delta, capacity); else p = Math.Max(p - delta, 0); // 执行替换 Replace(); // 移动节点 MoveBetweenLists(node.prevIndex, node.listType, LIST_T2); node.listType = LIST_T2; return node; } private void Replace() { if (t1Count > 0 && (t1Count > p || (b2Count > 0 && t1Count == p))) { MoveBetweenLists(t1Head, LIST_T1, LIST_B1); t1Count--; b1Count++; if (b1Count > capacity) { int old = b1Head; Node n = nodes[old]; RemoveFromList(old); keyToNode.Remove(n.key); FreeNode(old); b1Count--; } } else { MoveBetweenLists(t2Head, LIST_T2, LIST_B2); t2Count--; b2Count++; if (b2Count > capacity) { int old = b2Head; Node n = nodes[old]; RemoveFromList(old); keyToNode.Remove(n.key); FreeNode(old); b2Count--; } } } #region 链表操作 private void MoveToMRU(int nodeIndex, byte targetList) { RemoveFromList(nodeIndex); AddToHead(nodeIndex, targetList); } private void MoveBetweenLists(int nodeIndex, byte fromList, byte toList) { RemoveFromList(nodeIndex); AddToHead(nodeIndex, toList); } private void AddToHead(int nodeIndex, byte listType) { Node node = nodes[nodeIndex]; // 读取 node.listType = listType; node.prevIndex = -1; switch (listType) { case LIST_T1: node.nextIndex = t1Head; nodes[nodeIndex] = node; // 写回 if (t1Head != -1) { Node headNode = nodes[t1Head]; headNode.prevIndex = nodeIndex; nodes[t1Head] = headNode; // 写回 } t1Head = nodeIndex; if (t1Tail == -1) t1Tail = nodeIndex; break; case LIST_T2: node.nextIndex = t2Head; nodes[nodeIndex] = node; // 写回 if (t2Head != -1) { Node headNode = nodes[t2Head]; headNode.prevIndex = nodeIndex; nodes[t2Head] = headNode; // 写回 } t2Head = nodeIndex; if (t2Tail == -1) t2Tail = nodeIndex; break; case LIST_B1: node.nextIndex = b1Head; nodes[nodeIndex] = node; // 写回 if (b1Head != -1) { Node headNode = nodes[b1Head]; headNode.prevIndex = nodeIndex; nodes[b1Head] = headNode; // 写回 } b1Head = nodeIndex; if (b1Tail == -1) b1Tail = nodeIndex; break; case LIST_B2: node.nextIndex = b2Head; nodes[nodeIndex] = node; // 写回 if (b2Head != -1) { Node headNode = nodes[b2Head]; headNode.prevIndex = nodeIndex; nodes[b2Head] = headNode; // 写回 } b2Head = nodeIndex; if (b2Tail == -1) b2Tail = nodeIndex; break; } } private void RemoveFromList(int nodeIndex) { Node node = nodes[nodeIndex]; // 读取 int prev = node.prevIndex; int next = node.nextIndex; // 根据类型更新头尾指针 switch (node.listType) { case LIST_T1: if (nodeIndex == t1Head) t1Head = next; if (nodeIndex == t1Tail) t1Tail = prev; break; case LIST_T2: if (nodeIndex == t2Head) t2Head = next; if (nodeIndex == t2Tail) t2Tail = prev; break; case LIST_B1: if (nodeIndex == b1Head) b1Head = next; if (nodeIndex == b1Tail) b1Tail = prev; break; case LIST_B2: if (nodeIndex == b2Head) b2Head = next; if (nodeIndex == b2Tail) b2Tail = prev; break; } // 更新邻居 if (prev != -1) { Node prevNode = nodes[prev]; prevNode.nextIndex = next; nodes[prev] = prevNode; // 写回 } if (next != -1) { Node nextNode = nodes[next]; nextNode.prevIndex = prev; nodes[next] = nextNode; // 写回 } node.prevIndex = node.nextIndex = -1; nodes[nodeIndex] = node; // 写回 } #endregion private int AllocateNode() { int index = freeList[^1]; freeList.RemoveAtSwapBack(freeList.Length - 1); return index; } private void FreeNode(int index) { freeList.Add(index); } public bool Remove(TKey key) { if (!keyToNode.TryGetValue(key, out int nodeIndex)) return false; Node node = nodes[nodeIndex]; // 读取 // 更新计数 if (node.listType == LIST_T1) t1Count--; else if (node.listType == LIST_T2) t2Count--; else if (node.listType == LIST_B1) b1Count--; else if (node.listType == LIST_B2) b2Count--; RemoveFromList(nodeIndex); keyToNode.Remove(key); FreeNode(nodeIndex); return true; } public void Clear() { keyToNode.Clear(); freeList.Clear(); for (int i = 0; i < nodes.Length; i++) { freeList.Add(i); } t1Head = t1Tail = t2Head = t2Tail = -1; b1Head = b1Tail = b2Head = b2Tail = -1; t1Count = t2Count = b1Count = b2Count = 0; p = 0; } public void Dispose() { if (keyToNode.IsCreated) keyToNode.Dispose(); if (nodes.IsCreated) nodes.Dispose(); if (freeList.IsCreated) freeList.Dispose(); t1Head = t1Tail = t2Head = t2Tail = -1; b1Head = b1Tail = b2Head = b2Tail = -1; t1Count = t2Count = b1Count = b2Count = 0; p = 0; } public int Count => t1Count + t2Count; public int Capacity => capacity; public bool IsCreated => keyToNode.IsCreated; public int T1Count => t1Count; public int T2Count => t2Count; public int PValue => p; } } }