annotate trunk/aid/containers/heap.d @ 0:4b2e8e8a633e

Repository setup.
author revcompgeek
date Mon, 03 Mar 2008 19:28:10 -0700
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
1 /*++++++++++++++++++++++++++++++++++++++++++++
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
2 + Heap sorted array +
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
3 + By Matt Peterson +
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
4 ++++++++++++++++++++++++++++++++++++++++++++*/
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
5
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
6 /*class Heap(Value) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
7 Value[] array;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
8 int tail;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
9 public int capacity(){
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
10 // This returns the current capacity of the heap.
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
11 return array.length;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
12 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
13 public int size(){
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
14 // This returns the number of items in the heap.
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
15 return tail;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
16 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
17
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
18 void capacity(int c){
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
19 // This sets the capacity to c.
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
20 if(c < tail) c = tail;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
21 array.length = c;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
22 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
23 void insert(Value v){
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
24 // Inserts a value and sorts it to it's correct position.
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
25 if(tail >= size()) capacity(size()+10);
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
26 array[++tail] = v;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
27 int i = tail;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
28 while(i > 0 && array[i/2] > array[i]){
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
29 array[i] = array[i/2];
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
30 array[i/2] = v;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
31 i /= 2;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
32 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
33 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
34 Value removeHead(){
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
35 Value ret = array[0];
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
36 array[0] = array[tail];
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
37 tail--;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
38 i = 0;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
39 while(
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
40 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
41
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
42 }*/
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
43
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
44 struct Heap(Value, Alloc = GCAllocator) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
45
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
46 alias ArrayHeap ContainerType;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
47 alias Value ValueType;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
48 alias size_t IndexType;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
49
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
50 Value[] data; ///< backing array. null by default, grows as needed
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
51
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
52 invariant {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
53 assert( tail <= data.length );
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
54 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
55
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
56 /** signature for a custom comparison function */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
57 alias int delegate(Value* a, Value* b) CompareFcn;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
58
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
59 /** Set custom comparison function. */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
60 void compareFcn(CompareFcn cmp) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
61 cmpFcn = cmp;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
62 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
63
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
64 /** Get heap contents as dynamic array slice of backing array. */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
65 Value[] values() {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
66 return data[0..tail];
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
67 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
68
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
69 /** Adds an item to the heap. Increases capacity if needed. */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
70 void addTail(Value v) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
71 capacity(tail+1);
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
72 data[tail++] = v;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
73 fixupTail();
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
74 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
75
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
76 /** Removes and returns the head item of the heap. If the target
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
77 * heap is empty an IndexOutOfBoundsException is thrown unless
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
78 * version=MinTLNoIndexChecking is set.
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
79 */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
80 Value takeHead() {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
81 version (MinTLNoIndexChecking) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
82 // no error checking
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
83 } else {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
84 if (tail == 0)
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
85 throw new IndexOutOfBoundsException();
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
86 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
87 Value val = data[0];
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
88 data[0] = data[--tail];
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
89 data[tail] = Value.init;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
90 fixupHead();
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
91 return val;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
92 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
93
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
94 /** Removes the head item of the heap. */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
95 void removeHead() {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
96 version (MinTLNoIndexChecking) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
97 // no error checking
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
98 } else {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
99 if (tail == 0)
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
100 throw new IndexOutOfBoundsException();
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
101 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
102 data[0] = data[--tail];
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
103 data[tail] = Value.init;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
104 fixupHead();
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
105 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
106
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
107 /** Get the length of heap. */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
108 size_t length() {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
109 return tail;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
110 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
111
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
112 /** Test if container is empty. */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
113 bool isEmpty() {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
114 return tail == 0;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
115 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
116
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
117 /** Clear all contents. */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
118 void clear() {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
119 static if (is(Alloc == GCAllocator)) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
120 } else {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
121 if (data.ptr)
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
122 Alloc.gcFree(data.ptr);
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
123 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
124 *this = ArrayHeap.init;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
125 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
126
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
127 /** Get the nth item in the heap from head. */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
128 Value opIndex(size_t n) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
129 return data[n];
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
130 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
131
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
132 /** Get a pointer to the nth item in the heap */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
133 Value* lookup(size_t n) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
134 return &data[n];
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
135 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
136
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
137 /** Set the nth item in the heap. */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
138 void opIndexAssign(Value val, size_t n) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
139 data[n] = val;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
140 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
141
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
142 /** Duplicates a heap. */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
143 ArrayHeap dup() {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
144 ArrayHeap res;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
145 static if (is(Alloc == GCAllocator)) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
146 res.data = data.dup;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
147 } else {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
148 Value* p = cast(Value*)Alloc.malloc(data.length * Value.sizeof);
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
149 res.data = p[0 .. data.length];
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
150 res.data[] = data[];
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
151 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
152 res.tail = tail;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
153 res.cmpFcn = cmpFcn;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
154 return res;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
155 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
156
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
157 /** Test for equality of two heaps. */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
158 int opEquals(ArrayHeap c) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
159 size_t len = length;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
160 if (len !is c.length)
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
161 return 0;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
162 size_t a,b;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
163 a = 0;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
164 b = 0;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
165 TypeInfo ti = typeid(Value);
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
166 for (size_t k = 0; k < len; k++) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
167 if (!ti.equals(&data[a],&c.data[b]))
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
168 return 0;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
169 a++;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
170 b++;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
171 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
172 return 1;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
173 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
174
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
175 /** Compare two heaps. */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
176 int opCmp(ArrayHeap c) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
177 size_t len = length;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
178 if (len > c.length)
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
179 len = c.length;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
180 size_t a,b;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
181 a = 0;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
182 b = 0;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
183 TypeInfo ti = typeid(Value);
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
184 for (size_t k = 0; k < len; k++) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
185 int cmp = ti.compare(&data[a],&c.data[b]);
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
186 if (cmp)
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
187 return cmp;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
188 a++;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
189 b++;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
190 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
191 return cast(int)length - cast(int)c.length;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
192 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
193
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
194 /** Returns a short string representation of the heap. */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
195 char[] toString() {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
196 return "[ArrayHeap length " ~ std.string.toString(tail) ~ "]";
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
197 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
198
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
199 /** Iterates over the heap from head to tail calling delegate to
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
200 * perform an action. The value is passed to the delegate.
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
201 */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
202 int opApplyNoKey(int delegate(inout Value x) dg){
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
203 int res = 0;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
204 for (size_t k=0; k < tail; k++) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
205 res = dg(data[k]);
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
206 if (res) break;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
207 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
208 return res;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
209 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
210
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
211 /** Iterates over the heap from head to tail calling delegate to
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
212 * perform an action. The index from 0 and the value are passed
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
213 * to the delegate.
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
214 */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
215 int opApplyWithKey(int delegate(inout size_t n, inout Value x) dg){
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
216 int res = 0;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
217 for (size_t k=0; k < tail; k++) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
218 res = dg(k,data[k]);
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
219 if (res) break;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
220 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
221 return res;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
222 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
223
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
224 alias opApplyNoKey opApply;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
225 alias opApplyWithKey opApply;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
226
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
227 /** Ensure the minimum capacity of heap. */
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
228 void capacity(size_t cap) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
229 if (cap > data.length) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
230 cap = (cap+1)*2;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
231 static if (is(Alloc == GCAllocator)) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
232 data.length = cap;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
233 } else {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
234 Value* p = data.ptr;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
235 p = cast(Value*)Alloc.gcRealloc(p,cap*Value.sizeof);
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
236 p[data.length .. cap] = Value.init;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
237 data = p[0 .. cap];
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
238 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
239 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
240 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
241
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
242 // Helper functions
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
243
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
244 // enforce heap invariant after a new head
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
245 private void fixupHead() {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
246 size_t n = 0;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
247 TypeInfo ti = typeid(Value);
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
248 if (cmpFcn is null) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
249 cmpFcn = cast(CompareFcn)&ti.compare;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
250 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
251 for (;;) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
252 size_t n1 = 2*n+1;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
253 if (n1 >= tail) break;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
254 if ((n1 != tail-1) && (cmpFcn(&data[n1],&data[n1+1]) < 0))
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
255 n1++;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
256 if (cmpFcn(&data[n],&data[n1]) < 0) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
257 ti.swap(&data[n],&data[n1]);
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
258 n = n1;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
259 } else {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
260 break;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
261 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
262 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
263 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
264
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
265 // enforce heap invariant after a new tail
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
266 private void fixupTail() {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
267 size_t n = tail-1;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
268 TypeInfo ti = typeid(Value);
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
269 if (cmpFcn is null) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
270 cmpFcn = cast(CompareFcn)&ti.compare;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
271 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
272 size_t n1 = (n-1)>>1;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
273 while ((n > 0) && (cmpFcn(&data[n],&data[n1]) > 0)) {
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
274 ti.swap(&data[n],&data[n1]);
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
275 n = n1;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
276 n1 = (n-1)>>1;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
277 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
278 }
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
279
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
280 private CompareFcn cmpFcn;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
281 private size_t tail;
4b2e8e8a633e Repository setup.
revcompgeek
parents:
diff changeset
282 }