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 + -
显示快捷键?