Scores LexicalReorderingTableTree:: GetScore(const Phrase& f, const Phrase& e, const Phrase& c) { if((!m_FactorsF.empty() && 0 == f.GetSize()) || (!m_FactorsE.empty() && 0 == e.GetSize())) { //NOTE: no check for c as c might be empty, e.g. start of sentence //not a proper key // phi: commented out, since e may be empty (drop-unknown) //std::cerr << "Not a proper key!\n"; return Scores(); } CacheType::iterator i; if(m_UseCache) { std::pair<CacheType::iterator, bool> r; r = m_Cache.insert(std::make_pair(MakeCacheKey(f,e),Candidates())); if(!r.second) return auxFindScoreForContext((r.first)->second, c); i = r.first; } else if((i = m_Cache.find(MakeCacheKey(f,e))) != m_Cache.end()) // although we might not be caching now, cache might be none empty! return auxFindScoreForContext(i->second, c); // not in cache => go to file... Candidates cands; m_Table->GetCandidates(MakeTableKey(f,e), &cands); if(cands.empty()) return Scores(); if(m_UseCache) i->second = cands; if(m_FactorsC.empty()) { UTIL_THROW_IF2(1 != cands.size(), "Error"); return cands[0].GetScore(0); } else return auxFindScoreForContext(cands, c); };
void LexicalReorderingTableTree::auxCacheForSrcPhrase(const Phrase& f) { if(m_FactorsE.empty()) { //f is all of key... Candidates cands; m_Table->GetCandidates(MakeTableKey(f,Phrase(ARRAY_SIZE_INCR)),&cands); m_Cache[MakeCacheKey(f,Phrase(ARRAY_SIZE_INCR))] = cands; } else { ObjectPool<PPimp> pool; PPimp* pPos = m_Table->GetRoot(); //1) goto subtree for f for(size_t i = 0; i < f.GetSize() && 0 != pPos && pPos->isValid(); ++i) { /* old code pPos = m_Table.Extend(pPos, auxClearString(f.GetWord(i).ToString(m_FactorsF)), SourceVocId); */ pPos = m_Table->Extend(pPos, f.GetWord(i).GetString(m_FactorsF, false), SourceVocId); } if(0 != pPos && pPos->isValid()) { pPos = m_Table->Extend(pPos, PrefixTreeMap::MagicWord); } if(0 == pPos || !pPos->isValid()) { return; } //2) explore whole subtree depth first & cache std::string cache_key = auxClearString(f.GetStringRep(m_FactorsF)) + "|||"; std::vector<State> stack; stack.push_back(State(pool.get(PPimp(pPos->ptr()->getPtr(pPos->idx),0,0)),"")); Candidates cands; while(!stack.empty()) { if(stack.back().pos->isValid()) { LabelId w = stack.back().pos->ptr()->getKey(stack.back().pos->idx); std::string next_path = stack.back().path + " " + m_Table->ConvertWord(w,TargetVocId); //cache this m_Table->GetCandidates(*stack.back().pos,&cands); if(!cands.empty()) { m_Cache[cache_key + auxClearString(next_path)] = cands; } cands.clear(); PPimp* next_pos = pool.get(PPimp(stack.back().pos->ptr()->getPtr(stack.back().pos->idx),0,0)); ++stack.back().pos->idx; stack.push_back(State(next_pos,next_path)); } else { stack.pop_back(); } } } }
inline ImageBufferImplPtr retrieve(ImageBufferType type, ValueType valType, i32 width, i32 height, i32 xAlign, i32 yAlign) { i32 paddedWidth, paddedHeight; CalcAlignedSizes(width, height, xAlign, yAlign, &paddedWidth, &paddedHeight); BufferCacheKey key = MakeCacheKey(type, valType, paddedWidth, paddedHeight); ImageBufferImplPtr p = retrieve(key); if (!p.get()) return p; // We're a friend, so we can perform (necessary) surgery... The ImplPtrs // are cached only based on actual width/height of the allocated memory, so // here the correct padding/alignment information is added p->width_ = width; p->height_ = height; p->xAlign_ = xAlign; p->yAlign_ = yAlign; p->paddedWidth_ = paddedWidth; p->paddedHeight_ = paddedHeight; return p; }
inline void release(ImageBufferImplPtr& ptr) { release(MakeCacheKey(ptr.get()), ptr); }
inline ImageBufferImplPtr retrieve(ImageBufferImpl *impl) { return retrieve(MakeCacheKey(impl)); }
inline BufferCacheKey MakeCacheKey(ImageBufferImpl *impl) { return MakeCacheKey(impl->type(), impl->valType(), impl->paddedWidth(), impl->paddedHeight()); }
const QImage& GetEmoji(const uint32_t main, const uint32_t ext, const EmojiSizePx size) { assert(main > 0); assert(size >= EmojiSizePx::Min); assert(size <= EmojiSizePx::Max); static QImage empty; Loading_.waitForFinished(); if (!Loading_.result()) { return empty; } const auto sizeToSearch = ((size == EmojiSizePx::Auto) ? GetEmojiSizeForCurrentUiScale() : (int32_t)size); const auto info = GetEmojiInfoByCodepoint(main, ext); if (!info) { return empty; } assert(info->Index_ >= 0); const auto key = MakeCacheKey(info->Index_, sizeToSearch); auto cacheIter = EmojiCache_.find(key); if (cacheIter != EmojiCache_.end()) { assert(!cacheIter->second.isNull()); return cacheIter->second; } QImage image; if (platform::is_apple()) { QImage imageOut(QSize(sizeToSearch, sizeToSearch), QImage::Format_ARGB32); imageOut.fill(Qt::transparent); QPainter painter(&imageOut); painter.setRenderHint(QPainter::Antialiasing); painter.setRenderHint(QPainter::TextAntialiasing); painter.setRenderHint(QPainter::SmoothPixmapTransform); painter.setPen(Qt::SolidLine); painter.setPen(QColor::fromRgb(0, 0, 0)); QRect r(0, Utils::is_mac_retina()?-6:-2, sizeToSearch, sizeToSearch+20); Utils::SChar ch(main, ext); QFont f = QFont(QStringLiteral("AppleColorEmoji"), sizeToSearch); painter.setFont(f); painter.drawText(r, Qt::AlignHCenter, ch.ToQString()); painter.end(); image = imageOut; } else { const auto &meta = GetMetaBySize(sizeToSearch); auto emojiSetIter = LoadEmojiSetForSizeIfNeeded(meta); QRect r(0, 0, meta.SizePx_, meta.SizePx_); const auto offsetX = (info->Index_ * meta.SizePx_); r.translate(offsetX, 0); image = emojiSetIter->second.copy(r); } const auto result = EmojiCache_.emplace(key, std::move(image)); assert(result.second); return result.first->second; }