cvsimport
[beagle.git] / beagled / Lucene.Net / Util / PriorityQueue.cs
blob7c32aa72e215f350810449f78b58ca896085b926
1 /*
2 * Copyright 2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 using System;
19 namespace Lucene.Net.Util
22 /// <summary>A PriorityQueue maintains a partial ordering of its elements such that the
23 /// least element can always be found in constant time. Put()'s and pop()'s
24 /// require log(size) time.
25 /// </summary>
26 public abstract class PriorityQueue
28 private System.Object[] heap;
29 private int size;
30 private int maxSize;
32 /// <summary>Determines the ordering of objects in this priority queue. Subclasses
33 /// must define this one method.
34 /// </summary>
35 public abstract bool LessThan(System.Object a, System.Object b);
37 /// <summary>Subclass constructors must call this. </summary>
38 protected internal void Initialize(int maxSize)
40 size = 0;
41 int heapSize = maxSize + 1;
42 heap = new System.Object[heapSize];
43 this.maxSize = maxSize;
46 /// <summary> Adds an Object to a PriorityQueue in log(size) time.
47 /// If one tries to add more objects than maxSize from initialize
48 /// a RuntimeException (ArrayIndexOutOfBound) is thrown.
49 /// </summary>
50 public void Put(System.Object element)
52 size++;
53 heap[size] = element;
54 UpHeap();
57 /// <summary> Adds element to the PriorityQueue in log(size) time if either
58 /// the PriorityQueue is not full, or not lessThan(element, top()).
59 /// </summary>
60 /// <param name="element">
61 /// </param>
62 /// <returns> true if element is added, false otherwise.
63 /// </returns>
64 public virtual bool Insert(System.Object element)
66 if (size < maxSize)
68 Put(element);
69 return true;
71 else if (size > 0 && !LessThan(element, Top()))
73 heap[1] = element;
74 AdjustTop();
75 return true;
77 else
78 return false;
81 /// <summary>Returns the least element of the PriorityQueue in constant time. </summary>
82 public System.Object Top()
84 if (size > 0)
85 return heap[1];
86 else
87 return null;
90 /// <summary>Removes and returns the least element of the PriorityQueue in log(size)
91 /// time.
92 /// </summary>
93 public System.Object Pop()
95 if (size > 0)
97 System.Object result = heap[1]; // save first value
98 heap[1] = heap[size]; // move last to first
99 heap[size] = null; // permit GC of objects
100 size--;
101 DownHeap(); // adjust heap
102 return result;
104 else
105 return null;
108 /// <summary>Should be called when the Object at top changes values. Still log(n)
109 /// worst case, but it's at least twice as fast to <pre>
110 /// { pq.top().change(); pq.adjustTop(); }
111 /// </pre> instead of <pre>
112 /// { o = pq.pop(); o.change(); pq.push(o); }
113 /// </pre>
114 /// </summary>
115 public void AdjustTop()
117 DownHeap();
121 /// <summary>Returns the number of elements currently stored in the PriorityQueue. </summary>
122 public int Size()
124 return size;
127 /// <summary>Removes all entries from the PriorityQueue. </summary>
128 public void Clear()
130 for (int i = 0; i <= size; i++)
131 heap[i] = null;
132 size = 0;
135 private void UpHeap()
137 int i = size;
138 System.Object node = heap[i]; // save bottom node
139 int j = SupportClass.Number.URShift(i, 1);
140 while (j > 0 && LessThan(node, heap[j]))
142 heap[i] = heap[j]; // shift parents down
143 i = j;
144 j = SupportClass.Number.URShift(j, 1);
146 heap[i] = node; // install saved node
149 private void DownHeap()
151 int i = 1;
152 System.Object node = heap[i]; // save top node
153 int j = i << 1; // find smaller child
154 int k = j + 1;
155 if (k <= size && LessThan(heap[k], heap[j]))
157 j = k;
159 while (j <= size && LessThan(heap[j], node))
161 heap[i] = heap[j]; // shift up child
162 i = j;
163 j = i << 1;
164 k = j + 1;
165 if (k <= size && LessThan(heap[k], heap[j]))
167 j = k;
170 heap[i] = node; // install saved node