|
|
#pragma once |
|
|
|
|
|
#include <queue> |
|
|
#include <vector> |
|
|
|
|
|
namespace Moses |
|
|
{ |
|
|
namespace Syntax |
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template<typename T> |
|
|
class BoundedPriorityContainer |
|
|
{ |
|
|
public: |
|
|
typedef typename std::vector<T>::iterator Iterator; |
|
|
typedef typename std::vector<T>::const_iterator ConstIterator; |
|
|
|
|
|
BoundedPriorityContainer(std::size_t); |
|
|
|
|
|
Iterator Begin() { |
|
|
return m_elements.begin(); |
|
|
} |
|
|
Iterator End() { |
|
|
return m_elements.begin()+m_size; |
|
|
} |
|
|
|
|
|
ConstIterator Begin() const { |
|
|
return m_elements.begin(); |
|
|
} |
|
|
ConstIterator End() const { |
|
|
return m_elements.begin()+m_size; |
|
|
} |
|
|
|
|
|
|
|
|
std::size_t Size() const { |
|
|
return m_size; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void LazyClear() { |
|
|
m_size = 0; |
|
|
while (!m_queue.empty()) { |
|
|
m_queue.pop(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Insert(const T &, float); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool SwapIn(T &, float); |
|
|
|
|
|
|
|
|
|
|
|
bool WouldAccept(float priority) { |
|
|
return m_size < m_limit || priority > m_queue.top().first; |
|
|
} |
|
|
|
|
|
private: |
|
|
typedef std::pair<float, int> PriorityIndexPair; |
|
|
|
|
|
class PriorityIndexPairOrderer |
|
|
{ |
|
|
public: |
|
|
bool operator()(const PriorityIndexPair &p, |
|
|
const PriorityIndexPair &q) const { |
|
|
return p.first > q.first; |
|
|
} |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
typedef std::priority_queue<PriorityIndexPair, |
|
|
std::vector<PriorityIndexPair>, |
|
|
PriorityIndexPairOrderer> Queue; |
|
|
|
|
|
|
|
|
|
|
|
std::vector<T> m_elements; |
|
|
|
|
|
|
|
|
std::size_t m_size; |
|
|
|
|
|
|
|
|
const std::size_t m_limit; |
|
|
|
|
|
|
|
|
Queue m_queue; |
|
|
}; |
|
|
|
|
|
template<typename T> |
|
|
BoundedPriorityContainer<T>::BoundedPriorityContainer(std::size_t limit) |
|
|
: m_size(0) |
|
|
, m_limit(limit) |
|
|
{ |
|
|
m_elements.reserve(m_limit); |
|
|
} |
|
|
|
|
|
template<typename T> |
|
|
bool BoundedPriorityContainer<T>::Insert(const T &t, float priority) |
|
|
{ |
|
|
if (m_size < m_limit) { |
|
|
PriorityIndexPair pair(priority, m_size); |
|
|
m_queue.push(pair); |
|
|
if (m_size < m_elements.size()) { |
|
|
m_elements[m_size] = t; |
|
|
} else { |
|
|
m_elements.push_back(t); |
|
|
} |
|
|
++m_size; |
|
|
return true; |
|
|
} else if (priority > m_queue.top().first) { |
|
|
PriorityIndexPair pair = m_queue.top(); |
|
|
m_queue.pop(); |
|
|
pair.first = priority; |
|
|
m_elements[pair.second] = t; |
|
|
m_queue.push(pair); |
|
|
return true; |
|
|
} |
|
|
return false; |
|
|
} |
|
|
|
|
|
template<typename T> |
|
|
bool BoundedPriorityContainer<T>::SwapIn(T &t, float priority) |
|
|
{ |
|
|
if (m_size < m_limit) { |
|
|
PriorityIndexPair pair(priority, m_size); |
|
|
m_queue.push(pair); |
|
|
if (m_size < m_elements.size()) { |
|
|
swap(m_elements[m_size], t); |
|
|
} else { |
|
|
m_elements.push_back(t); |
|
|
} |
|
|
++m_size; |
|
|
return true; |
|
|
} else if (priority > m_queue.top().first) { |
|
|
PriorityIndexPair pair = m_queue.top(); |
|
|
m_queue.pop(); |
|
|
pair.first = priority; |
|
|
swap(m_elements[pair.second], t); |
|
|
m_queue.push(pair); |
|
|
return true; |
|
|
} |
|
|
return false; |
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
|