2 // System.Web.Caching.CacheItem
5 // Marek Habersack <mhabersack@novell.com>
7 // (C) 2009 Novell, Inc (http://novell.com)
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 namespace System.Web.Caching
34 sealed class CacheItemPriorityQueue
38 public CacheItem Data;
46 public CacheItem SwapData (CacheItem newData)
54 public Node (CacheItem data)
65 public void Enqueue (CacheItem item)
70 Node node = new Node (item);
72 root = lastAdded = lastParent = firstParent = node;
76 if (lastParent.Left != null && lastParent.Right != null) {
77 lastParent = lastParent.Next;
78 if (lastParent == null) {
79 lastParent = firstParent = firstParent.Left;
84 node.Parent = lastParent;
85 if (lastParent.Left == null)
86 lastParent.Left = node;
88 lastParent.Right = node;
90 if (lastAdded != null) {
91 lastAdded.Next = node;
92 node.Prev = lastAdded;
99 public CacheItem Dequeue ()
101 Console.WriteLine ("{0}.Dequeue ()", this);
106 if (root.Left == null && root.Right == null) {
110 Console.WriteLine ("\troot disabled, returning null");
119 Node last = lastAdded;
123 if (last.Prev == null) {
124 Node parent = last.Parent;
126 if (parent.Next == null)
128 parent = parent.Next;
132 lastAdded = last.Prev;
133 lastAdded.Next = null;
136 if (last.Parent.Left == last)
137 last.Parent.Left = null;
139 last.Parent.Right = null;
141 root.Data = last.Data;
145 Console.WriteLine ("\titem {0} disabled, ignoring", ret.ExpiresAt);
146 } while (ret.Disabled);
151 public CacheItem Peek ()
159 void BubbleDown (Node item)
161 if (item == null || (item.Left == null && item.Right == null))
164 if (item.Left == null)
165 SwapBubbleDown (item, item.Right);
166 else if (item.Right == null)
167 SwapBubbleDown (item, item.Left);
169 if (item.Left.Data.ExpiresAt < item.Right.Data.ExpiresAt)
170 SwapBubbleDown (item, item.Left);
172 SwapBubbleDown (item, item.Right);
176 void SwapBubbleDown (Node item, Node otherItem)
178 if (otherItem.Data.ExpiresAt < item.Data.ExpiresAt) {
179 item.Data = otherItem.SwapData (item.Data);
180 BubbleDown (otherItem);
184 void BubbleUp (Node item)
186 if (item == null || item.Data == null)
189 Node parent = item.Parent;
193 if (item.Data.ExpiresAt > parent.Data.ExpiresAt)
196 item.Data = parent.SwapData (item.Data);
201 public string GetDotScript ()
203 StringBuilder sb = new StringBuilder ();
205 sb.Append ("graph CacheItemPriorityQueue {\n");
206 sb.Append ("\tnode [color=lightblue, style=filled];\n");
208 if (root.Left == null && root.Right == null)
209 sb.AppendFormat ("\t{0};", root.Data.ExpiresAt);
211 TraverseTree (sb, root);
215 return sb.ToString ();
218 void TraverseTree (StringBuilder sb, Node root)
220 if (root.Left != null) {
221 sb.AppendFormat ("\t{0} -- {1};\n", root.Data.ExpiresAt, root.Left.Data.ExpiresAt);
222 TraverseTree (sb, root.Left);
225 if (root.Right != null) {
226 sb.AppendFormat ("\t{0} -- {1};\n", root.Data.ExpiresAt, root.Right.Data.ExpiresAt);
227 TraverseTree (sb, root.Right);