Remove debug statements from KCal backends.
[beagle.git] / Util / TopScores.cs
blobe110770bd28d35517dc0d4d6e8626a7e7a03db7f
1 //
2 // TopScores.cs
3 //
4 // Copyright (C) 2004 Novell, Inc.
5 //
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a
9 // copy of this software and associated documentation files (the "Software"),
10 // to deal in the Software without restriction, including without limitation
11 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 // and/or sell copies of the Software, and to permit persons to whom the
13 // Software is furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 // DEALINGS IN THE SOFTWARE.
27 using System;
28 using System.Collections;
30 namespace Beagle.Util {
32 public class TopScores {
34 private bool Debug = false;
36 private struct Node {
37 public long Score;
38 public object Obj;
39 public int LtEq;
40 public int Gt;
42 public void Clear ()
44 LtEq = -1;
45 Gt = -1;
49 int count;
50 bool at_capacity = false;
51 int free_node = 0;
52 int root_node = -1;
53 Node [] nodes;
54 long cutoff_score;
56 public TopScores (int count)
58 this.count = count;
59 this.nodes = new Node [count];
60 for (int i = 0; i < count; ++i)
61 this.nodes [i].Clear ();
64 public int Count {
65 get { return count; }
68 public long MinimumScore {
69 get {
70 if (at_capacity)
71 return cutoff_score;
73 long score = 0;
74 int i = root_node;
75 while (i != -1) {
76 score = nodes [i].Score;
77 i = nodes [i].LtEq;
79 return score;
83 public bool WillAccept (long score)
85 return (! at_capacity) || score > cutoff_score;
88 public void Add (long score, object obj)
90 if (at_capacity && score <= cutoff_score) {
91 if (Debug)
92 Console.WriteLine ("Skipping {0} ({1}), since threshold is {2}",
93 obj, score, cutoff_score);
94 return;
97 int node, next_node, prev_node;
99 // If this is the first thing we are adding,
100 // make it the root node.
101 if (root_node == -1) {
102 if (Debug)
103 Console.WriteLine ("Added {0} ({1}) as root node {2}", obj, score, free_node);
104 root_node = free_node;
105 nodes [free_node].Score = score;
106 nodes [free_node].Obj = obj;
107 ++free_node;
108 return;
111 // If we are at capacity, find the leftmost node
112 // and detatch it.
113 if (at_capacity) {
114 prev_node = -1;
115 node = root_node;
117 // Find the leftmost node
118 while (true) {
119 next_node = nodes [node].LtEq;
120 if (next_node == -1)
121 break;
122 prev_node = node;
123 node = next_node;
126 // Detatch the node, and store its index
127 // in free_node so we can re-use it immediately.
128 if (prev_node != -1) {
129 // Detatching a non-root node
130 if (Debug)
131 Console.WriteLine ("Detatching {0} ({1}) from node {2}",
132 nodes [node].Obj, nodes [node].Score, node);
133 nodes [prev_node].LtEq = nodes [node].Gt;
134 free_node = node;
136 node = prev_node; // where to start looking for the new cut-off
137 } else {
138 // Detatching the root node
139 if (Debug)
140 Console.WriteLine ("Detatching {0} ({1}) from root node {2}",
141 nodes [root_node].Obj, nodes [root_node].Score, root_node);
142 free_node = root_node;
143 root_node = nodes [root_node].Gt;
145 node = root_node; // where to start looking for the new cut-off
148 // Find the new cut-off
149 while (node != -1) {
150 cutoff_score = nodes [node].Score;
151 node = nodes [node].LtEq;
154 nodes [free_node].Clear ();
156 if (Debug)
157 Console.WriteLine ("New cutoff is {0}", cutoff_score);
161 // Find where we want to attach this node
162 bool is_lteq = false;
163 node = -1;
164 next_node = root_node;
165 while (next_node != -1) {
166 node = next_node;
167 if (score <= nodes [node].Score) {
168 next_node = nodes [node].LtEq;
169 is_lteq = true;
170 } else {
171 next_node = nodes [node].Gt;
172 is_lteq = false;
176 nodes [free_node].Score = score;
177 nodes [free_node].Obj = obj;
178 if (Debug)
179 Console.WriteLine ("Added {0} ({1}) as node {2}, under and {3} of {4}",
180 obj, score, free_node, is_lteq ? "left" : "right", node);
182 if (at_capacity && score < cutoff_score) {
183 cutoff_score = score;
184 if (Debug)
185 Console.WriteLine ("New cutoff is {0}", cutoff_score);
189 if (is_lteq)
190 nodes [node].LtEq = free_node;
191 else
192 nodes [node].Gt = free_node;
194 if (! at_capacity) {
195 ++free_node;
196 if (free_node >= count) {
197 cutoff_score = MinimumScore;
198 at_capacity = true;
199 if (Debug)
200 Console.WriteLine ("Hit capacity: set cutoff to {0}", cutoff_score);
206 private int ComputeMaxDepth (int i)
208 if (i == -1)
209 return 0;
210 int a = 1 + ComputeMaxDepth (nodes [i].LtEq);
211 int b = 1 + ComputeMaxDepth (nodes [i].Gt);
212 return Math.Max (a, b);
215 public int MaxDepth {
216 get { return ComputeMaxDepth (root_node); }
219 private void BuildArray (ArrayList array, int i)
221 if (i != -1) {
222 BuildArray (array, nodes [i].Gt);
223 array.Add (nodes [i].Obj);
224 BuildArray (array, nodes [i].LtEq);
228 // Returns objects sorted from high to low scores
229 public ICollection TopScoringObjects {
230 get {
231 ArrayList array = new ArrayList ();
232 BuildArray (array, root_node);
233 return array;
237 #if false
238 static void Main ()
240 int trial = 0;
241 Random rng = new Random ();
243 for (int j = 0; j < 1000; ++j) {
244 ++trial;
245 Console.WriteLine ("Trial #{0}", trial);
247 TopScores top;
248 top = new TopScores (6 + rng.Next (100));
250 ArrayList all = new ArrayList ();
251 int i;
252 int N = 100 + rng.Next (100);
253 for (i = 0; i < N; ++i) {
254 int n = rng.Next (200);
255 all.Add (n);
256 top.Add (n, n);
259 all.Sort ();
260 i = all.Count - 1;
261 foreach (object obj in top.TopScoringObjects) {
262 if (! obj.Equals (all [i])) {
263 Console.WriteLine ("Mismatch!");
264 i = all.Count - 1;
265 foreach (object x in top.TopScoringObjects) {
266 Console.WriteLine ("{0} {1} {2}",
267 x, all [i],
268 x.Equals (all [i]) ? "" : "***");
269 --i;
271 return;
273 --i;
277 #endif