为什么使用双向链表
如果一个资源被频繁调用,我们希望它在链表的顶部,而不频繁调用的资源会慢慢地沉向底部,当我们想要释放资源时,位于底部的资源会被优先释放。
当然我们也可以在代码中指定当前资源是否常用,指定当前资源被卸载时是否是完全卸载。
双向链表类
我们的双向链表类配合对象池进行优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
| public class DoubleLinkedListNode<T> where T : class,new() { public DoubleLinkedListNode<T> prev, next; public T item = null; } public class DoubleLinkedList<T> where T : class, new() { public DoubleLinkedListNode<T> Head,Tail = null; protected ClassObjectPool<DoubleLinkedListNode<T>> m_DoubleLinkedNodePool = ObjectPoolManager.Instance.GetOrCreatClassPool<DoubleLinkedListNode<T>>(500);
protected int m_Count = 0; public int Count { get { return m_Count; } } public DoubleLinkedListNode<T> AddToHeader(T item) { DoubleLinkedListNode<T> pList = m_DoubleLinkedNodePool.Spawn(true); pList.next = null; pList.prev = null; pList.item = item; return AddToHeader(pList); } public DoubleLinkedListNode<T> AddToHeader(DoubleLinkedListNode<T> pNode) { if (pNode == null) return null; pNode.prev = null; if (Head == null) { Head = Tail = pNode; } else { pNode.next = Head; Head.prev = pNode; Head = pNode; } m_Count++; return Head; } public DoubleLinkedListNode<T> AddToTail(T item) { DoubleLinkedListNode<T> pList = m_DoubleLinkedNodePool.Spawn(true); pList.next = null; pList.prev = null; pList.item = item; return AddToTail(pList); } public DoubleLinkedListNode<T> AddToTail(DoubleLinkedListNode<T> pNode) { if(pNode == null) return null; pNode.next = null; if(Tail == null) { Head= Tail = pNode; } else { pNode.prev = Tail; Tail.next = pNode; Tail= pNode; } m_Count++; return Tail; } public void RemoveNode(DoubleLinkedListNode<T> pNode) { if(pNode == null) return; if(pNode == Head) { Head = pNode.next; } if (pNode == Tail) { Tail = pNode.prev; } if(pNode.prev != null) { pNode.prev.next = pNode.next; } if(pNode.next != null) { pNode.next.prev = pNode.prev; } pNode.next = null; pNode.prev= null; pNode.item = null; m_DoubleLinkedNodePool.Recycle(pNode); m_Count--; } public void MoveToHead(DoubleLinkedListNode<T> pNode) { if(pNode == null || pNode == Head) return; if(pNode.prev == null && pNode.next == null) { return; } if(pNode == Tail) { Tail = pNode.prev; } if(pNode.prev != null) { pNode.prev.next = pNode.next; } if(pNode.next != null) { pNode.next.prev = pNode.prev; } pNode.prev = null; pNode.next = Head; Head.prev = pNode; Head = pNode; if (Tail == null) { Tail = Head; } } }
|
封装双向链表
我们再把双向链表进行一次封装,引入一个字典,用于更方便快速地查找双向链表里面的元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| public class CMapList<T> where T : class, new() { DoubleLinkedList<T> m_DLink = new DoubleLinkedList<T>(); Dictionary<T,DoubleLinkedListNode<T>> m_FindMap = new Dictionary<T, DoubleLinkedListNode<T>>(); ~CMapList() { Clear(); } public void Clear() { while (m_DLink.Tail != null) { Remove(m_DLink.Tail.item); } } public void InsertToHead(T t) { DoubleLinkedListNode<T> node = null; if (m_FindMap.TryGetValue(t, out node) && node != null) { m_DLink.AddToHeader(node); return; } m_DLink.AddToHeader(t); m_FindMap.Add(t, m_DLink.Head); } public void Pop() { if (m_DLink.Tail != null) { Remove(m_DLink.Tail.item); } } public void Remove(T t) { DoubleLinkedListNode<T> node = null; if(!m_FindMap.TryGetValue(t,out node) || node == null) { return; } m_DLink.RemoveNode(node); m_FindMap.Remove(t); } public T Back() { return m_DLink.Tail == null? null: m_DLink.Tail.item; } public int Size() { return m_FindMap.Count; } public bool Find(T t) { DoubleLinkedListNode<T> node = null; if (!m_FindMap.TryGetValue(t, out node) || node == null) { return false; } return true; } public bool Refresh(T t) { DoubleLinkedListNode<T> node = null; if (!m_FindMap.TryGetValue(t, out node) || node == null) { return false; } m_DLink.MoveToHead(node); return true; } }
|