FST  openfst-1.8.3
OpenFst Library
heap.h
Go to the documentation of this file.
1 // Copyright 2005-2024 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the 'License');
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an 'AS IS' BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // See www.openfst.org for extensive documentation on this weighted
16 // finite-state transducer library.
17 //
18 // Implementation of a heap as in STL, but allows tracking positions in heap
19 // using a key. The key can be used to do an in-place update of values in the
20 // heap.
21 
22 #ifndef FST_HEAP_H_
23 #define FST_HEAP_H_
24 
25 #include <utility>
26 #include <vector>
27 
28 #include <fst/compat.h>
29 #include <fst/log.h>
30 
31 namespace fst {
32 
33 // A templated heap implementation that supports in-place update of values.
34 //
35 // The templated heap implementation is a little different from the STL
36 // priority_queue and the *_heap operations in STL. This heap supports
37 // indexing of values in the heap via an associated key.
38 //
39 // Each value is internally associated with a key which is returned to the
40 // calling functions on heap insert. This key can be used to later update
41 // the specific value in the heap.
42 //
43 // T: the element type of the hash. It can be POD, Data or a pointer to Data.
44 // Compare: comparison functor for determining min-heapness.
45 template <class T, class Compare>
46 class Heap {
47  public:
48  using Value = T;
49 
50  static constexpr int kNoKey = -1;
51 
52  // Initializes with a specific comparator.
53  explicit Heap(Compare comp = Compare()) : comp_(comp), size_(0) {}
54 
55  // Inserts a value into the heap.
56  int Insert(const Value &value) {
57  if (size_ < values_.size()) {
58  values_[size_] = value;
59  pos_[key_[size_]] = size_;
60  } else {
61  values_.push_back(value);
62  pos_.push_back(size_);
63  key_.push_back(size_);
64  }
65  ++size_;
66  return Insert(value, size_ - 1);
67  }
68 
69  // Updates a value at position given by the key. The pos_ array is first
70  // indexed by the key. The position gives the position in the heap array.
71  // Once we have the position we can then use the standard heap operations
72  // to calculate the parent and child positions.
73  void Update(int key, const Value &value) {
74  const auto i = pos_[key];
75  const bool is_better = comp_(value, values_[Parent(i)]);
76  values_[i] = value;
77  if (is_better) {
78  Insert(value, i);
79  } else {
80  Heapify(i);
81  }
82  }
83 
84  // Returns the least value.
85  Value Pop() {
86  DCHECK(!Empty());
87  Value top = values_.front();
88  Swap(0, size_ - 1);
89  size_--;
90  Heapify(0);
91  return top;
92  }
93 
94  // Returns the least value w.r.t. the comparison function from the
95  // heap.
96  const Value &Top() const {
97  DCHECK(!Empty());
98  return values_.front();
99  }
100 
101  // Returns the element for the given key.
102  const Value &Get(int key) const {
103  DCHECK_LT(key, pos_.size());
104  return values_[pos_[key]];
105  }
106 
107  // Checks if the heap is empty.
108  bool Empty() const { return size_ == 0; }
109 
110  void Clear() { size_ = 0; }
111 
112  int Size() const { return size_; }
113 
114  void Reserve(int size) {
115  values_.reserve(size);
116  pos_.reserve(size);
117  key_.reserve(size);
118  }
119 
120  const Compare &GetCompare() const { return comp_; }
121 
122  private:
123  // The following private routines are used in a supportive role
124  // for managing the heap and keeping the heap properties.
125 
126  // Computes left child of parent.
127  static int Left(int i) {
128  return 2 * (i + 1) - 1; // 0 -> 1, 1 -> 3
129  }
130 
131  // Computes right child of parent.
132  static int Right(int i) {
133  return 2 * (i + 1); // 0 -> 2, 1 -> 4
134  }
135 
136  // Given a child computes parent.
137  static int Parent(int i) {
138  return (i - 1) / 2; // 0 -> 0, 1 -> 0, 2 -> 0, 3 -> 1, 4 -> 1, ...
139  }
140 
141  // Swaps a child and parent. Use to move element up/down tree. Note the use of
142  // a little trick here. When we swap we need to swap:
143  //
144  // - the value
145  // - the associated keys
146  // - the position of the value in the heap
147  void Swap(int j, int k) {
148  const auto tkey = key_[j];
149  pos_[key_[j] = key_[k]] = j;
150  pos_[key_[k] = tkey] = k;
151  using std::swap;
152  swap(values_[j], values_[k]);
153  }
154 
155  // Heapifies the subtree rooted at index i.
156  void Heapify(int i) {
157  const auto l = Left(i);
158  const auto r = Right(i);
159  auto largest = (l < size_ && comp_(values_[l], values_[i])) ? l : i;
160  if (r < size_ && comp_(values_[r], values_[largest])) largest = r;
161  if (largest != i) {
162  Swap(i, largest);
163  Heapify(largest);
164  }
165  }
166 
167  // Inserts (updates) element at subtree rooted at index i.
168  int Insert(const Value &value, int i) {
169  int p;
170  while (i > 0 && !comp_(values_[p = Parent(i)], value)) {
171  Swap(i, p);
172  i = p;
173  }
174  return key_[i];
175  }
176 
177  private:
178  const Compare comp_;
179 
180  std::vector<int> pos_;
181  std::vector<int> key_;
182  std::vector<Value> values_;
183  int size_;
184 };
185 
186 } // namespace fst
187 
188 #endif // FST_HEAP_H_
#define DCHECK_LT(x, y)
Definition: log.h:76
const Compare & GetCompare() const
Definition: heap.h:120
Heap(Compare comp=Compare())
Definition: heap.h:53
void Clear()
Definition: heap.h:110
bool Empty() const
Definition: heap.h:108
const Value & Get(int key) const
Definition: heap.h:102
static constexpr int kNoKey
Definition: heap.h:50
const Value & Top() const
Definition: heap.h:96
int Size() const
Definition: heap.h:112
Value Pop()
Definition: heap.h:85
#define DCHECK(x)
Definition: log.h:74
int Insert(const Value &value)
Definition: heap.h:56
void Reserve(int size)
Definition: heap.h:114
void Update(int key, const Value &value)
Definition: heap.h:73