scope_impl.cpp
来自「ncbi源码」· C++ 代码 · 共 1,802 行 · 第 1/4 页
CPP
1,802 行
CBioseq_HandleCScope_Impl::GetBioseqHandleFromTSE(const CSeq_id& id, const CSeq_entry_Handle& seh){ return GetBioseqHandleFromTSE(CSeq_id_Handle::GetHandle(id), seh);}CBioseq_Handle CScope_Impl::GetBioseqHandle(const CSeq_loc& loc, int get_flag){ CBioseq_Handle bh; for (CSeq_loc_CI citer (loc); citer; ++citer) { bh = GetBioseqHandle(citer.GetSeq_id(), get_flag); if ( bh ) { break; } } return bh;}CBioseq_Handle CScope_Impl::GetBioseqHandle(const CBioseq_Info& seq){ CBioseq_Handle ret; {{ TReadLockGuard guard(m_Scope_Conf_RWLock); ret = x_GetBioseqHandle(seq); }} return ret;}CBioseq_Handle CScope_Impl::x_GetBioseqHandle(const CBioseq_Info& seq){ CBioseq_Handle ret; ITERATE ( CBioseq_Info::TId, id, seq.GetId() ) { CBioseq_Handle bh = x_GetBioseqHandleFromTSE(*id, seq.GetTSE_Info()); if ( bh && &bh.x_GetInfo() == &seq ) { ret = bh; break; } } return ret;}CDataSource_ScopeInfo*CScope_Impl::x_FindBioseqInfo(const CPriorityTree& tree, const CSeq_id_Handle& idh, const TSeq_id_HandleSet* hset, CSeqMatch_Info& match_info, int get_flag){ CDataSource_ScopeInfo* ret = 0; // Process sub-tree TPriority last_priority = 0; ITERATE( CPriorityTree::TPriorityMap, mit, tree.GetTree() ) { // Search in all nodes of the same priority regardless // of previous results TPriority new_priority = mit->first; if ( new_priority != last_priority ) { // Don't process lower priority nodes if something // was found if ( ret ) { break; } last_priority = new_priority; } CDataSource_ScopeInfo* new_ret = x_FindBioseqInfo(mit->second, idh, hset, match_info, get_flag); if ( new_ret ) { _ASSERT(!ret); // should be checked by match_info already ret = new_ret; } } return ret;}CDataSource_ScopeInfo*CScope_Impl::x_FindBioseqInfo(CDataSource_ScopeInfo& ds_info, const CSeq_id_Handle& main_idh, const TSeq_id_HandleSet* hset, CSeqMatch_Info& match_info, int get_flag){ // skip already matched CDataSource CDataSource& ds = ds_info.GetDataSource(); if ( match_info && &match_info.GetDataSource() == &ds ) { return 0; } CSeqMatch_Info info; {{ CFastMutexGuard guard(ds_info.GetMutex()); info = ds.HistoryResolve(main_idh, ds_info.GetTSESet()); if ( !info && hset ) { ITERATE(TSeq_id_HandleSet, hit, *hset) { if ( *hit == main_idh ) // already checked continue; if ( info && info.GetIdHandle().IsBetter(*hit) ) // worse hit continue; CSeqMatch_Info new_info = ds.HistoryResolve(*hit, ds_info.GetTSESet()); if ( !new_info ) continue; _ASSERT(&new_info.GetDataSource() == &ds); if ( !info ) { info = new_info; continue; } CSeqMatch_Info* best_info = ds.ResolveConflict(main_idh, info, new_info); if (best_info) { info = *best_info; continue; } x_ThrowConflict(eConflict_History, info, new_info); } } }} if ( !info && get_flag == CScope::eGetBioseq_All ) { // Try to load the sequence from the data source info = ds_info.GetDataSource().BestResolve(main_idh); } if ( info ) { if ( match_info ) { x_ThrowConflict(eConflict_Live, match_info, info); } match_info = info; return &ds_info; } return 0;}CDataSource_ScopeInfo*CScope_Impl::x_FindBioseqInfo(const CPriorityNode& node, const CSeq_id_Handle& idh, const TSeq_id_HandleSet* hset, CSeqMatch_Info& match_info, int get_flag){ if ( node.IsTree() ) { // Process sub-tree return x_FindBioseqInfo(node.GetTree(), idh, hset, match_info, get_flag); } else if ( node.IsLeaf() ) { return x_FindBioseqInfo(const_cast<CDataSource_ScopeInfo&>(node.GetLeaf()), idh, hset, match_info, get_flag); } return 0;}void CScope_Impl::x_ResolveSeq_id(TSeq_idMapValue& id_info, int get_flag){ // Use priority, do not scan all DSs - find the first one. // Protected by m_Scope_Conf_RWLock in upper-level functions CSeqMatch_Info match_info; auto_ptr<TSeq_id_HandleSet> hset; CSeq_id_Mapper& mapper = CSeq_id_Mapper::GetSeq_id_Mapper(); if ( mapper.HaveMatchingHandles(id_info.first) ) { hset.reset(new TSeq_id_HandleSet); mapper.GetMatchingHandles(id_info.first, *hset); hset->erase(id_info.first); if ( hset->empty() ) hset.reset(); } CDataSource_ScopeInfo* ds_info = x_FindBioseqInfo(m_setDataSrc, id_info.first, hset.get(), match_info, get_flag); if ( !ds_info ) { // Map unresoved ids only if loading was requested if (get_flag == CScope::eGetBioseq_All) { _ASSERT(m_HeapScope); id_info.second.m_Bioseq_Info.Reset(new CBioseq_ScopeInfo(&id_info)); } } else { {{ CFastMutexGuard guard(ds_info->GetMutex()); ds_info->AddTSE(match_info.GetTSE_Info()); }} CConstRef<CBioseq_Info> info = match_info.GetBioseq_Info(); {{ TReadLockGuard guard(m_BioseqMapLock); TBioseqMap::const_iterator bm_it = m_BioseqMap.find(&*info); if ( bm_it != m_BioseqMap.end() ) { id_info.second.m_Bioseq_Info = bm_it->second; return; } }} {{ TWriteLockGuard guard(m_BioseqMapLock); pair<TBioseqMap::iterator, bool> ins = m_BioseqMap .insert(TBioseqMap::value_type(&*info, CRef<CBioseq_ScopeInfo>())); if ( ins.second ) { // new _ASSERT(m_HeapScope); ins.first->second.Reset(new CBioseq_ScopeInfo(&id_info, info)); } id_info.second.m_Bioseq_Info = ins.first->second; }} }}void CScope_Impl::UpdateAnnotIndex(const CSeq_annot& annot){ UpdateAnnotIndex(GetSeq_annotHandle(annot));}void CScope_Impl::UpdateAnnotIndex(const CSeq_annot_Handle& annot){ TReadLockGuard rguard(m_Scope_Conf_RWLock); const CSeq_annot_Info& info = annot.x_GetInfo(); info.GetDataSource().UpdateAnnotIndex(info);}CConstRef<CScope_Impl::TAnnotRefSet>CScope_Impl::GetTSESetWithAnnots(const CSeq_id_Handle& idh){ TReadLockGuard rguard(m_Scope_Conf_RWLock); TSeq_idMapValue& info = x_GetSeq_id_Info(idh); CRef<CBioseq_ScopeInfo> binfo = x_InitBioseq_Info(info, CScope::eGetBioseq_All); {{ CInitGuard init(info.second.m_AllAnnotRef_Info, m_MutexPool); if ( init ) { CRef<TAnnotRefSet> ref_set(new TAnnotRefSet); TTSE_LockSet& tse_set = *ref_set; if ( binfo->HasBioseq() ) { TTSE_Lock tse(&binfo->GetTSE_Info()); tse_set.insert(tse); } TTSE_LockSet with_ref; for (CPriority_I it(m_setDataSrc); it; ++it) { it->GetDataSource().GetTSESetWithAnnots(idh, with_ref); CFastMutexGuard guard(it->GetMutex()); const TTSE_LockSet& tse_cache = it->GetTSESet(); ITERATE(TTSE_LockSet, ref_it, with_ref) { if ( (*ref_it)->IsDead() && tse_cache.find(*ref_it) == tse_cache.end() ) { continue; } tse_set.insert(*ref_it); } with_ref.clear(); } info.second.m_AllAnnotRef_Info = ref_set; } }} return info.second.m_AllAnnotRef_Info;}CConstRef<CScope_Impl::TAnnotRefSet>CScope_Impl::GetTSESetWithAnnots(const CBioseq_Handle& bh){ TReadLockGuard rguard(m_Scope_Conf_RWLock); TSeq_idMapValue& info = x_GetSeq_id_Info(bh); _ASSERT(info.second.m_Bioseq_Info); CRef<CBioseq_ScopeInfo> binfo = info.second.m_Bioseq_Info; {{ CInitGuard init(info.second.m_AllAnnotRef_Info, m_MutexPool); if ( init ) { CRef<TAnnotRefSet> ref_set(new TAnnotRefSet); TTSE_LockSet& tse_set = *ref_set; if ( binfo->HasBioseq() ) { TTSE_Lock tse(&binfo->GetTSE_Info()); tse_set.insert(tse); } TTSE_LockSet with_ref; for (CPriority_I it(m_setDataSrc); it; ++it) { it->GetDataSource().GetTSESetWithAnnots(info.first, with_ref); CFastMutexGuard guard(it->GetMutex()); const TTSE_LockSet& tse_cache = it->GetTSESet(); ITERATE(TTSE_LockSet, ref_it, with_ref) { if ( (*ref_it)->IsDead() && tse_cache.find(*ref_it) == tse_cache.end() ) { continue; } tse_set.insert(*ref_it); } with_ref.clear(); } info.second.m_AllAnnotRef_Info = ref_set; } }} return info.second.m_AllAnnotRef_Info;}void CScope_Impl::x_ThrowConflict(EConflict conflict_type, const CSeqMatch_Info& info1, const CSeqMatch_Info& info2) const{ const char* msg_type = conflict_type == eConflict_History? "history": "live TSE"; CNcbiOstrstream s; s << "CScope_Impl -- multiple " << msg_type << " matches: " << info1.GetDataSource().GetName() << "::" << info1.GetIdHandle().AsString() << " vs " << info2.GetDataSource().GetName() << "::" << info2.GetIdHandle().AsString(); string msg = CNcbiOstrstreamToString(s); NCBI_THROW(CObjMgrException, eFindConflict, msg);}void CScope_Impl::ResetHistory(void){ TWriteLockGuard guard(m_Scope_Conf_RWLock); x_ResetHistory();}void CScope_Impl::x_ResetHistory(void){ // 1. detach all CBbioseq_Handle objects from scope, and // 2. break circular link: // CBioseq_ScopeInfo-> CSynonymsSet-> SSeq_id_ScopeInfo-> CBioseq_ScopeInfo NON_CONST_ITERATE ( TSeq_idMap, it, m_Seq_idMap ) { if ( it->second.m_Bioseq_Info ) { it->second.m_Bioseq_Info->m_ScopeInfo = 0; // detaching from scope it->second.m_Bioseq_Info->m_SynCache.Reset(); // breaking the link } } m_Seq_idMap.clear(); m_BioseqMap.clear(); for (CPriority_I it(m_setDataSrc); it; ++it) { it->m_TSE_LockSet.clear(); }}void CScope_Impl::x_PopulateBioseq_HandleSet(const CSeq_entry_Handle& seh, TBioseq_HandleSet& handles, CSeq_inst::EMol filter, TBioseqLevelFlag level){ if ( seh ) { TReadLockGuard rguard(m_Scope_Conf_RWLock); const CSeq_entry_Info& info = seh.x_GetInfo(); CDataSource::TBioseq_InfoSet info_set; info.GetDataSource().GetBioseqs(info, info_set, filter, level); // Convert each bioseq info into bioseq handle ITERATE (CDataSource::TBioseq_InfoSet, iit, info_set) { CBioseq_Handle bh = x_GetBioseqHandle(**iit); if ( bh ) { handles.push_back(bh); } } }}CConstRef<CSynonymsSet> CScope_Impl::GetSynonyms(const CSeq_id& id){ return GetSynonyms(CSeq_id_Handle::GetHandle(id));}CConstRef<CSynonymsSet> CScope_Impl::GetSynonyms(const CSeq_id_Handle& id){ _ASSERT(id); TReadLockGuard rguard(m_Scope_Conf_RWLock); return x_GetSynonyms(*x_GetBioseq_Info(id, CScope::eGetBioseq_All));}CConstRef<CSynonymsSet> CScope_Impl::GetSynonyms(const CBioseq_Handle& bh){ if ( !bh ) { return CConstRef<CSynonymsSet>(); } TReadLockGuard rguard(m_Scope_Conf_RWLock); return x_GetSynonyms(const_cast<CBioseq_ScopeInfo&>(bh.x_GetScopeInfo()));}void CScope_Impl::x_AddSynonym(const CSeq_id_Handle& idh, CSynonymsSet& syn_set, CBioseq_ScopeInfo& info){ // Check current ID for conflicts, add to the set. TSeq_idMapValue& seq_id_info = x_GetSeq_id_Info(idh); if ( x_InitBioseq_Info(seq_id_info, info) ) { // the same bioseq - add synonym if ( !syn_set.ContainsSynonym(seq_id_info.first) ) { syn_set.AddSynonym(&seq_id_info); } } else { CRef<CBioseq_ScopeInfo> info2 = seq_id_info.second.m_Bioseq_Info; _ASSERT(info2 != &info); LOG_POST(Warning << "CScope::GetSynonyms: Bioseq["<< info.GetBioseq_Info().IdString()<<"]: id "<< idh.AsString()<<" is resolved to another Bioseq["<< info2->GetBioseq_Info().IdString()<<"]"); }}CConstRef<CSynonymsSet>CScope_Impl::x_GetSynonyms(CBioseq_ScopeInfo& info){ {{ CInitGuard init(info.m_SynCache, m_MutexPool); if ( init ) { // It's OK to use CRef, at least one copy should be kept // alive by the id cache (for the ID requested). CRef<CSynonymsSet> syn_set(new CSynonymsSet); //syn_set->AddSynonym(id); if ( info.HasBioseq() ) { ITERATE(CBioseq_Info::TId, it, info.GetBioseq_Info().GetId()) { CSeq_id_Mapper& mapper=CSeq_id_Mapper::GetSeq_id_Mapper(); if ( mapper.HaveReverseMatch(*it) ) { TSeq_id_HandleSet hset; mapper.GetReverseMatchingHandles(*it, hset); ITERATE(TSeq_id_HandleSet, mit, hset) { x_AddSynonym(*mit, *syn_set, info); } } else { x_AddSynonym(*it, *syn_set, info); } } } info.m_SynCache = syn_set; } }} return info.m_SynCache;}void CScope_Impl::GetAllTSEs(TTSE_Handles& tses, int kind){ TReadLockGuard rguard(m_Scope_Conf_RWLock); for (CPriority_I it(m_setDataSrc); it; ++it) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?