| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #ifndef moses_TargetPhraseCollectionCache_h |
| #define moses_TargetPhraseCollectionCache_h |
|
|
| #include <map> |
| #include <set> |
| #include <vector> |
|
|
| #include <boost/thread/tss.hpp> |
| #include <boost/shared_ptr.hpp> |
|
|
| #include "moses/Phrase.h" |
| #include "moses/TargetPhraseCollection.h" |
|
|
| namespace Moses |
| { |
|
|
| |
| typedef std::vector<TargetPhrase> TargetPhraseVector; |
| typedef boost::shared_ptr<TargetPhraseVector> TargetPhraseVectorPtr; |
|
|
| |
| class TargetPhraseCollectionCache |
| { |
| private: |
| size_t m_max; |
| float m_tolerance; |
|
|
| struct LastUsed { |
| clock_t m_clock; |
| TargetPhraseVectorPtr m_tpv; |
| size_t m_bitsLeft; |
|
|
| LastUsed() : m_clock(0), m_bitsLeft(0) {} |
|
|
| LastUsed(clock_t clock, TargetPhraseVectorPtr tpv, size_t bitsLeft = 0) |
| : m_clock(clock), m_tpv(tpv), m_bitsLeft(bitsLeft) {} |
| }; |
|
|
| typedef std::map<Phrase, LastUsed> CacheMap; |
| static boost::thread_specific_ptr<CacheMap> m_phraseCache; |
|
|
| public: |
|
|
| typedef CacheMap::iterator iterator; |
| typedef CacheMap::const_iterator const_iterator; |
|
|
| TargetPhraseCollectionCache(size_t max = 5000, float tolerance = 0.2) |
| : m_max(max), m_tolerance(tolerance) { |
| } |
|
|
| iterator Begin() { |
| if(!m_phraseCache.get()) |
| m_phraseCache.reset(new CacheMap()); |
| return m_phraseCache->begin(); |
| } |
|
|
| const_iterator Begin() const { |
| if(!m_phraseCache.get()) |
| m_phraseCache.reset(new CacheMap()); |
| return m_phraseCache->begin(); |
| } |
|
|
| iterator End() { |
| if(!m_phraseCache.get()) |
| m_phraseCache.reset(new CacheMap()); |
| return m_phraseCache->end(); |
| } |
|
|
| const_iterator End() const { |
| if(!m_phraseCache.get()) |
| m_phraseCache.reset(new CacheMap()); |
| return m_phraseCache->end(); |
| } |
|
|
| |
| void Cache(const Phrase &sourcePhrase, TargetPhraseVectorPtr tpv, |
| size_t bitsLeft = 0, size_t maxRank = 0) { |
| if(!m_phraseCache.get()) |
| m_phraseCache.reset(new CacheMap()); |
| |
| iterator it = m_phraseCache->find(sourcePhrase); |
| if(it != m_phraseCache->end()) |
| |
| it->second.m_clock = clock(); |
| else { |
| |
| if(maxRank && tpv->size() > maxRank) { |
| TargetPhraseVectorPtr tpv_temp(new TargetPhraseVector()); |
| tpv_temp->resize(maxRank); |
| std::copy(tpv->begin(), tpv->begin() + maxRank, tpv_temp->begin()); |
| (*m_phraseCache)[sourcePhrase] = LastUsed(clock(), tpv_temp, bitsLeft); |
| } else |
| (*m_phraseCache)[sourcePhrase] = LastUsed(clock(), tpv, bitsLeft); |
| } |
| } |
|
|
| std::pair<TargetPhraseVectorPtr, size_t> Retrieve(const Phrase &sourcePhrase) { |
| if(!m_phraseCache.get()) |
| m_phraseCache.reset(new CacheMap()); |
| iterator it = m_phraseCache->find(sourcePhrase); |
| if(it != m_phraseCache->end()) { |
| LastUsed &lu = it->second; |
| lu.m_clock = clock(); |
| return std::make_pair(lu.m_tpv, lu.m_bitsLeft); |
| } else |
| return std::make_pair(TargetPhraseVectorPtr(), 0); |
| } |
|
|
| |
| void Prune() { |
| if(!m_phraseCache.get()) |
| m_phraseCache.reset(new CacheMap()); |
| if(m_phraseCache->size() > m_max * (1 + m_tolerance)) { |
| typedef std::set<std::pair<clock_t, Phrase> > Cands; |
| Cands cands; |
| for(CacheMap::iterator it = m_phraseCache->begin(); |
| it != m_phraseCache->end(); it++) { |
| LastUsed &lu = it->second; |
| cands.insert(std::make_pair(lu.m_clock, it->first)); |
| } |
|
|
| for(Cands::iterator it = cands.begin(); it != cands.end(); it++) { |
| const Phrase& p = it->second; |
| m_phraseCache->erase(p); |
|
|
| if(m_phraseCache->size() < (m_max * (1 - m_tolerance))) |
| break; |
| } |
| } |
| } |
|
|
| void CleanUp() { |
| if(!m_phraseCache.get()) |
| m_phraseCache.reset(new CacheMap()); |
| m_phraseCache->clear(); |
| } |
|
|
| }; |
|
|
| } |
|
|
| #endif |
|
|