COMBINATORIAL_BLAS 1.6
 
Loading...
Searching...
No Matches
heap4.h
Go to the documentation of this file.
1// 4ary heap data structure
2#ifndef HEAP4
3#define HEAP4
4#include "util.h"
5
6const unsigned long LineSize = 64; // cache line size (or multiple)
7
8template <class Key, class Value>
9struct KNElement {Key key; Value value;};
10
11// align an address
12// require: sz is a power of two
13inline char *knAlign(void *p, unsigned long sz)
14{
15 return (char*)(((unsigned long)p + (sz - 1)) & ~(sz - 1));
16}
17// fixed size 4-ary heap
18template <class Key, class Value>
19class Heap4 {
20 // static const Key infimum = 4;
21 //static const Key supremum = numeric_limits<Key>.max();
22 typedef KNElement<Key, Value> Element;
23 int capacity;
24 Element * rawData;
25 Element * const data; // aligned version of rawData
26 int size; // index of last used element
27 int finalLayerSize; // size of first layer with free space
28 int finalLayerDist; // distance to end of layer
29public:
30 Heap4(Key sup, Key infimum, int cap) :
31 capacity(cap),
32 rawData(new Element[capacity + 4 + (LineSize-1)/sizeof(Element) + 1]),
33 data((Element*)knAlign(rawData, LineSize))
34 {
35 data[0].key = infimum; // sentinel
36 data[capacity + 1].key = sup;
37 data[capacity + 2].key = sup;
38 data[capacity + 3].key = sup;
39 reset();
40 }
41
42 ~Heap4() { delete [] rawData; }
43 Key getSupremum() { return data[capacity + 1].key; }
44 void reset();
45 int getSize() const { return size; }
46 Key getMinKey() const { return data[1].key; }
47 Value getMinValue() const { return data[1].value; }
49 void deleteMin(Key *key, Value *value);
50 void insert(Key k, Value v);
51 void print();
52 //void sortTo(Element *to); // sort in increasing order and empty
53 //void sortInPlace(); // in decreasing order
54};
55
56
57// reset size to 0 and fill data array with sentinels
58template <class Key, class Value>
59inline void Heap4<Key, Value>::
60reset() {
61 size = 0;
62 finalLayerSize = 1;
63 finalLayerDist = 0;
64 Key sup = getSupremum();
65 for (int i = 1; i <= capacity; i++) {
66 data[i].key = sup;
67 }
68}
69
70template <class Key, class Value>
71inline void Heap4<Key, Value>::
72deleteMin(Key *key, Value *value)
73{
74 *key = getMinKey();
75 *value = getMinValue();
76 deleteMinBasic();
77}
78
79template <class Key, class Value>
80inline void Heap4<Key, Value>::
82{
83 Assert2(size > 0);
84 Key minKey, otherKey;
85 int delta;
86
87 // first move up elements on a min-path
88 int hole = 1;
89 int succ = 2;
90 int layerSize = 4; // size of succ's layer
91 int layerPos = 0; // pos of succ within its layer
92 int sz = size;
93 size = sz - 1;
94 finalLayerDist++;
95 if (finalLayerDist == finalLayerSize) { // layer empty now
96 finalLayerSize >>= 2;
97 finalLayerDist = 0;
98 }
99 while (succ < sz) {
100 minKey = data[succ].key;
101 delta = 0;
102
103 // I could save a few assignments using
104 // a complete case distincition but
105 // this costs in terms of instruction cache load
106 otherKey = data[succ + 1].key;
107 if (otherKey < minKey) { minKey = otherKey; delta = 1; }
108 otherKey = data[succ + 2].key;
109 if (otherKey < minKey) { minKey = otherKey; delta = 2; }
110 otherKey = data[succ + 3].key;
111 if (otherKey < minKey) { minKey = otherKey; delta = 3; }
112 succ += delta;
113 layerPos += delta;
114
115 // move min successor up
116 data[hole].key = minKey;
117 data[hole].value = data[succ].value;
118
119 // step to next layer
120 hole = succ;
121 succ = succ - layerPos + layerSize; // beginning of next layer
122 layerPos <<= 2;
123 succ += layerPos; // now correct value
124 layerSize <<= 2;
125 }
126
127 // bubble up rightmost element
128 Key bubble = data[sz].key;
129 layerSize >>= 2; // now size of hole's layer
130 layerPos >>= 2; // now pos of hole within its layer
131 // Assert2(finalLayerSize == layerSize);
132 int layerDist = layerSize - layerPos - 1; // hole's dist to end of lay.
133 int pred = hole + layerDist - layerSize; // end of pred's layer for now
134 layerSize >>= 2; // now size of pred's layer
135 layerDist >>= 2; // now pred's pos in layer
136 pred = pred - layerDist; // finally preds index
137 while (data[pred].key > bubble) { // must terminate since inf at root
138 data[hole] = data[pred];
139 hole = pred;
140 pred = hole + layerDist - layerSize; // end of hole's layer for now
141 layerSize >>= 2; // now size of pred's layer
142 layerDist >>= 2;
143 pred = pred - layerDist; // finally preds index
144 }
145
146 // finally move data to hole
147 data[hole].key = bubble;
148 data[hole].value = data[sz].value;
149
150 data[sz].key = getSupremum(); // mark as deleted
151}
152
153
154template <class Key, class Value>
156insert(Key k, Value v)
157{
158 Assert2(size < capacity);
159 Debug4(cout << "insert(" << k << ", " << v << ")" << endl);
160
161 int layerSize = finalLayerSize;
162 int layerDist = finalLayerDist;
163 finalLayerDist--;
164 if (finalLayerDist == -1) { // layer full
165 // start next layer
166 finalLayerSize <<= 2;
167 finalLayerDist = finalLayerSize - 1;
168 }
169 size++;
170 int hole = size;
171 int pred = hole + layerDist - layerSize; // end of preds's layer for now
172 layerSize >>= 2; // now size of pred's layer
173 layerDist >>= 2;
174 pred = pred - layerDist; // finally preds index
175 Key predKey = data[pred].key;
176 while (predKey > k) { // must terminate due to sentinel at 0
177 data[hole].key = predKey;
178 data[hole].value = data[pred].value;
179 hole = pred;
180 pred = hole + layerDist - layerSize; // end of preds's layer for now
181 layerSize >>= 2; // now size of pred's layer
182 layerDist >>= 2;
183 pred = pred - layerDist; // finally preds index
184 predKey = data[pred].key;
185 }
186
187 // finally move data to hole
188 data[hole].key = k;
189 data[hole].value = v;
190}
191
192template <class Key, class Value>
193inline void Heap4<Key, Value>::
194print()
195{
196 int pos = 1;
197 for (int layerSize = 1; pos < size; layerSize <<= 2) {
198 for (int i = 0; i < layerSize && pos + i <= size; i++) {
199 cout << data[pos + i].key << " ";
200 }
201 pos += layerSize;
202 cout << endl;
203 }
204}
205
206#endif
Definition heap4.h:19
int getSize() const
Definition heap4.h:45
Value getMinValue() const
Definition heap4.h:47
Heap4(Key sup, Key infimum, int cap)
Definition heap4.h:30
void print()
~Heap4()
Definition heap4.h:42
void deleteMin(Key *key, Value *value)
void deleteMinBasic()
void reset()
Definition heap4.h:60
Key getMinKey() const
Definition heap4.h:46
void insert(Key k, Value v)
Key getSupremum()
Definition heap4.h:43
int size
Definition common.h:20
char * knAlign(void *p, unsigned long sz)
Definition heap4.h:13
const unsigned long LineSize
Definition heap4.h:6
#define Debug4(A)
Definition util.h:44
#define Assert2(C)
Definition util.h:61
char * knAlign(void *p, unsigned long sz)
Definition heap4.h:13
const unsigned long LineSize
Definition heap4.h:6
Value value
Definition heap-CLR.h:7
Key key
Definition heap-CLR.h:7