using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cosmos.Kernel.MM { /// /// Basically a Linked list but we save nodes so the GC is called as few times as possible. /// We want to avoid the situation that the Kernel GC is out of memory ( for even a LinkedListNode) and we get a page request /// From any GC. /// /// Be carefull here as not all methods reuse nodes /// /// internal class LinkedListWithNodeMemoryReuse : LinkedList { private List> reusedNodeList; internal LinkedListWithNodeMemoryReuse() : this(10) { } internal LinkedListWithNodeMemoryReuse(uint reservedCount) { reusedNodeList = new List>((int) reservedCount); AllocateMemoryForNodes(reservedCount); } //TODO if there is an allocation fail the GC must collect and we rerun this. private void AllocateMemoryForNodes(uint reservedCount) { for (int i = 0; i < reservedCount; i++) { T op = default(T); reusedNodeList.Add(new LinkedListNode(op)); } } private LinkedListNode GetFreeNode(T entry) { if (reusedNodeList.Count == 0) { // increase count by 20% AllocateMemoryForNodes((uint) base.Count / 5); return GetFreeNode(entry); } var result = reusedNodeList[0]; reusedNodeList.RemoveAt(0); result.Value = entry; return result; } internal new LinkedListNode AddFirst(T entry) { var node = GetFreeNode(entry); base.AddFirst(node); return node; } internal new void AddFirst(LinkedListNode node) { base.AddFirst(node); } internal new void AddLast(LinkedListNode node) { base.AddFirst(node); } internal new LinkedListNode AddBefore(LinkedListNode beforeNode, T region) { var node = GetFreeNode(region); base.AddBefore(beforeNode, node); return node; } internal new LinkedListNode AddLast(T region) { var node = GetFreeNode(region); base.AddLast(node); return node; } /// /// Note the Node belongs to the list and will be reused ! /// /// /// internal bool RemoveWithReuse(T val) { // get node var node = base.Find(val); if (node == null) return false; RemoveWithReuse(node); return true; } //internal new void RemoveLast() //{ // Remove //} //internal new void RemoveFirst() //{ //} //note node is added to available list .. // if it were public we could reuse the node in the list as well as the caller. private new void RemoveWithReuse(LinkedListNode node) { base.Remove(node); reusedNodeList.Add(node); } } //LinkedListWIthNodeMemoryReuse }