data_source.cpp

来自「ncbi源码」· C++ 代码 · 共 1,528 行 · 第 1/3 页

CPP
1,528
字号
        ret.Reset(found->second);    }    return ret;}CConstRef<CSeq_annot_Info>CDataSource::x_FindSeq_annot_Info(const CSeq_annot& obj){    CConstRef<CSeq_annot_Info> ret;    TSeq_annot_InfoMap::iterator found =        m_Seq_annot_InfoMap.find(ConstRef(&obj));    if ( found != m_Seq_annot_InfoMap.end() ) {        ret.Reset(found->second);    }    return ret;}CConstRef<CBioseq_Info>CDataSource::x_FindBioseq_Info(const CBioseq& obj){    CConstRef<CBioseq_Info> ret;    TBioseq_InfoMap::iterator found =        m_Bioseq_InfoMap.find(ConstRef(&obj));    if ( found != m_Bioseq_InfoMap.end() ) {        ret.Reset(found->second);    }    return ret;}/////////////////////////////////////////////////////////////////////////////CRef<CSeq_entry_Info> CDataSource::AttachEntry(CBioseq_set_Info& parent,                                               CSeq_entry& entry,                                               int index){    if ( m_Loader ) {        NCBI_THROW(CObjMgrException, eModifyDataError,                   "Can not remove a loaded entry");    }    TMainWriteLockGuard guard(m_DSMainLock);    return parent.AddEntry(entry, index);}void CDataSource::RemoveEntry(CSeq_entry_Info& entry){    if ( m_Loader ) {        NCBI_THROW(CObjMgrException, eModifyDataError,                   "Can not remove a loaded entry");    }    if ( !entry.HasParent_Info() ) {        // Top level entry        NCBI_THROW(CObjMgrException, eModifyDataError,                   "Can not remove top level seq-entry from a data source");    }    TMainWriteLockGuard guard(m_DSMainLock);    CBioseq_set_Info& parent = entry.GetParentBioseq_set_Info();    parent.RemoveEntry(Ref(&entry));}CRef<CSeq_annot_Info> CDataSource::AttachAnnot(CSeq_entry_Info& entry_info,                                               const CSeq_annot& annot){    if ( m_Loader ) {        NCBI_THROW(CObjMgrException, eModifyDataError,                   "Can not modify a loaded entry");    }    TMainWriteLockGuard guard(m_DSMainLock);    return entry_info.AddAnnot(annot);}CRef<CSeq_annot_Info> CDataSource::AttachAnnot(CBioseq_Base_Info& parent,                                               const CSeq_annot& annot){    if ( m_Loader ) {        NCBI_THROW(CObjMgrException, eModifyDataError,                   "Can not modify a loaded entry");    }    TMainWriteLockGuard guard(m_DSMainLock);    return parent.AddAnnot(annot);}void CDataSource::RemoveAnnot(CSeq_annot_Info& annot){    if ( m_Loader ) {        NCBI_THROW(CObjMgrException, eModifyDataError,                   "Can not modify a loaded entry");    }    TMainWriteLockGuard guard(m_DSMainLock);    CBioseq_Base_Info& parent = annot.GetParentBioseq_Base_Info();    parent.RemoveAnnot(Ref(&annot));}CRef<CSeq_annot_Info> CDataSource::ReplaceAnnot(CSeq_annot_Info& old_annot,                                                const CSeq_annot& new_annot){    if ( m_Loader ) {        NCBI_THROW(CObjMgrException, eModifyDataError,                   "Can not modify a loaded entry");    }    TMainWriteLockGuard guard(m_DSMainLock);    CBioseq_Base_Info& parent = old_annot.GetParentBioseq_Base_Info();    parent.RemoveAnnot(Ref(&old_annot));    return parent.AddAnnot(new_annot);}void PrintSeqMap(const string& /*id*/, const CSeqMap& /*smap*/){#if _DEBUG && 0    _TRACE("CSeqMap("<<id<<"):");    ITERATE ( CSeqMap, it, smap ) {        switch ( it.GetType() ) {        case CSeqMap::eSeqGap:            _TRACE("    gap: "<<it.GetLength());            break;        case CSeqMap::eSeqData:            _TRACE("    data: "<<it.GetLength());            break;        case CSeqMap::eSeqRef:            _TRACE("    ref: "<<it.GetRefSeqid().AsString()<<' '<<                   it.GetRefPosition()<<' '<<it.GetLength()<<' '<<                   it.GetRefMinusStrand());            break;        default:            _TRACE("    bad: "<<it.GetType()<<' '<<it.GetLength());            break;        }    }    _TRACE("end of CSeqMap "<<id);#endif}void CDataSource::x_SetDirtyAnnotIndex(CTSE_Info& tse){    _ASSERT(tse.x_DirtyAnnotIndex());    TAnnotWriteLockGuard guard(m_DSAnnotLock);    _VERIFY(m_DirtyAnnot_TSEs.insert(&tse).second);}void CDataSource::x_ResetDirtyAnnotIndex(CTSE_Info& tse){    _ASSERT(!tse.x_DirtyAnnotIndex());    _VERIFY(m_DirtyAnnot_TSEs.erase(&tse));}void CDataSource::UpdateAnnotIndex(void){    TMainWriteLockGuard guard(m_DSMainLock);    while ( !m_DirtyAnnot_TSEs.empty() ) {        CTSE_Info* tse_info = *m_DirtyAnnot_TSEs.begin();        tse_info->UpdateAnnotIndex();        _ASSERT(m_DirtyAnnot_TSEs.empty() ||                *m_DirtyAnnot_TSEs.begin() != tse_info);    }}void CDataSource::UpdateAnnotIndex(const CSeq_entry_Info& entry_info){    TMainWriteLockGuard guard(m_DSMainLock);    entry_info.UpdateAnnotIndex();}void CDataSource::UpdateAnnotIndex(const CSeq_annot_Info& annot_info){    TMainWriteLockGuard guard(m_DSMainLock);    annot_info.UpdateAnnotIndex();}void CDataSource::GetTSESetWithAnnots(const CSeq_id_Handle& idh,                                      TTSE_LockSet& with_ref){    // load all relevant TSEs    if ( m_Loader ) {        m_Loader->GetRecords(idh, CDataLoader::eAnnot);    }    UpdateAnnotIndex();    // collect all relevant TSEs    TTSEMap::const_iterator rtse_it = m_TSE_annot.find(idh);    if ( rtse_it != m_TSE_annot.end() ) {        ITERATE(CTSE_LockingSet::TTSESet, tse, rtse_it->second) {            if ( (*tse)->ContainsSeqid(idh) ) {                // skip TSE containing sequence                continue;            }            with_ref.insert(TTSE_Lock(*tse));        }    }}void CDataSource::GetSynonyms(const CSeq_id_Handle& main_idh,                              set<CSeq_id_Handle>& syns){    //### The TSE returns locked, unlock it    CSeq_id_Handle idh = main_idh;    TTSE_Lock tse_info(x_FindBestTSE(main_idh));    if ( !tse_info ) {        // Try to find the best matching id (not exactly equal)        CSeq_id_Mapper& mapper = CSeq_id_Mapper::GetSeq_id_Mapper();        if ( mapper.HaveMatchingHandles(idh) ) {            TSeq_id_HandleSet hset;            mapper.GetMatchingHandles(idh, hset);            ITERATE(TSeq_id_HandleSet, hit, hset) {                if ( *hit == main_idh ) // already checked                    continue;                if ( bool(tse_info)  &&  idh.IsBetter(*hit) ) // worse hit                    continue;                TTSE_Lock tmp_tse(x_FindBestTSE(*hit));                if ( tmp_tse ) {                    tse_info = tmp_tse;                    idh = *hit;                }            }        }    }    // At this point the tse_info (if not null) should be locked    if ( tse_info ) {        CTSE_Info::TBioseqs::const_iterator info =            tse_info->m_Bioseqs.find(idh);        if (info == tse_info->m_Bioseqs.end()) {            // Just copy the existing id            syns.insert(main_idh);        }        else {            // Create range list for each synonym of a seq_id            const CBioseq_Info::TId& syn = info->second->GetId();            ITERATE ( CBioseq_Info::TId, syn_it, syn ) {                syns.insert(*syn_it);            }        }    }    else {        // Just copy the existing range map        syns.insert(main_idh);    }}void CDataSource::x_IndexTSE(TTSEMap& tse_map,                             const CSeq_id_Handle& id,                             CTSE_Info* tse_info){    TTSEMap::iterator it = tse_map.lower_bound(id);    if ( it == tse_map.end() || it->first != id ) {        it = tse_map.insert(it, TTSEMap::value_type(id, CTSE_LockingSet()));    }    _ASSERT(it != tse_map.end() && it->first == id);    it->second.insert(tse_info);}void CDataSource::x_UnindexTSE(TTSEMap& tse_map,                               const CSeq_id_Handle& id,                               CTSE_Info* tse_info){    TTSEMap::iterator it = tse_map.find(id);    _ASSERT(it != tse_map.end() && it->first == id);    it->second.erase(tse_info);    if ( it->second.empty() ) {        tse_map.erase(it);    }}void CDataSource::x_IndexSeqTSE(const CSeq_id_Handle& id,                                CTSE_Info* tse_info){    // no need to lock as it's locked by callers    x_IndexTSE(m_TSE_seq, id, tse_info);}void CDataSource::x_UnindexSeqTSE(const CSeq_id_Handle& id,                                  CTSE_Info* tse_info){    // no need to lock as it's locked by callers    x_UnindexTSE(m_TSE_seq, id, tse_info);}void CDataSource::x_IndexAnnotTSE(const CSeq_id_Handle& id,                                  CTSE_Info* tse_info){    TAnnotWriteLockGuard guard(m_DSAnnotLock);    x_IndexTSE(m_TSE_annot, id, tse_info);}void CDataSource::x_UnindexAnnotTSE(const CSeq_id_Handle& id,                                    CTSE_Info* tse_info){    TAnnotWriteLockGuard guard(m_DSAnnotLock);    x_UnindexTSE(m_TSE_annot, id, tse_info);}void CDataSource::x_IndexAnnotTSEs(CTSE_Info* tse_info){    TAnnotWriteLockGuard guard(m_DSAnnotLock);    ITERATE ( CTSE_Info::TSeqIdToNames, it, tse_info->m_SeqIdToNames ) {        x_IndexTSE(m_TSE_annot, it->first, tse_info);    }    if ( tse_info->x_DirtyAnnotIndex() ) {        _VERIFY(m_DirtyAnnot_TSEs.insert(tse_info).second);    }}void CDataSource::x_UnindexAnnotTSEs(CTSE_Info* tse_info){    TAnnotWriteLockGuard guard(m_DSAnnotLock);    ITERATE ( CTSE_Info::TSeqIdToNames, it, tse_info->m_SeqIdToNames ) {        x_UnindexTSE(m_TSE_annot, it->first, tse_info);    }}void CDataSource::x_CleanupUnusedEntries(void){    // Lock indexes    TMainWriteLockGuard guard(m_DSMainLock);        bool broken = true;    while ( broken ) {        broken = false;        NON_CONST_ITERATE( TTSE_Set, it, m_TSE_Set ) {            if ( !(*it)->Locked() ) {                //### Lock the entry and check again                x_DropTSE(const_cast<CTSE_Info&>(**it));                broken = true;                break;            }        }    }}void CDataSource::x_UpdateTSEStatus(CTSE_Info& tse, bool dead){    tse.m_Dead = dead;}CSeqMatch_Info CDataSource::BestResolve(CSeq_id_Handle idh){    //### Lock all TSEs found, unlock all filtered out in the end.    CTSE_LockingSetLock lock;    {{        TMainWriteLockGuard guard(m_DSMainLock);        lock.Lock(m_TSE_seq[idh]);    }}    if ( m_Loader ) {        // Send request to the loader        m_Loader->GetRecords(idh, CDataLoader::eBioseqCore);    }    CSeqMatch_Info match;    TTSE_Lock tse(x_FindBestTSE(idh));    if ( !tse ) {        // Try to find the best matching id (not exactly equal)        CSeq_id_Mapper& mapper = CSeq_id_Mapper::GetSeq_id_Mapper();        if ( mapper.HaveMatchingHandles(idh) ) {            TSeq_id_HandleSet hset;            mapper.GetMatchingHandles(idh, hset);            ITERATE(TSeq_id_HandleSet, hit, hset) {                if ( *hit == idh ) // already checked                    continue;                if ( bool(tse)  &&  idh.IsBetter(*hit) ) // worse hit                    continue;                TTSE_Lock tmp_tse(x_FindBestTSE(*hit));                if ( tmp_tse ) {                    tse = tmp_tse;                    idh = *hit;                }            }        }    }    if ( tse ) {        match = CSeqMatch_Info(idh, *tse);    }    return match;}CSeqMatch_Info CDataSource::HistoryResolve(CSeq_id_Handle idh,                                           const TTSE_LockSet& history){    CSeqMatch_Info match;    {{        TMainReadLockGuard guard(m_DSMainLock);        TTSEMap::const_iterator tse_set = m_TSE_seq.find(idh);        if ( tse_set != m_TSE_seq.end() ) {            ITERATE ( CTSE_LockingSet, it, tse_set->second ) {                if ( history.find(TTSE_Lock(*it)) == history.end() ) {                    continue;                }                                CSeqMatch_Info new_match(idh, **it);                _ASSERT(new_match.GetBioseq_Info());                if ( !match ) {                    match = new_match;                    continue;                }                CNcbiOstrstream s;                s << "CDataSource("<<GetName()<<"): "                    "multiple history matches: Seq-id="<<idh.AsString()<<                    ": seq1=["<<match.GetBioseq_Info()->IdString()<<                    "] seq2=["<<new_match.GetBioseq_Info()->IdString()<<"]";                string msg = CNcbiOstrstreamToString(s);                NCBI_THROW(CObjMgrException, eFindConflict, msg);            }        }    }}    return match;}CSeqMatch_Info* CDataSource::ResolveConflict(const CSeq_id_Handle& id,                                             CSeqMatch_Info& info1,                                             CSeqMatch_Info& info2){    if (&info1.GetDataSource() != this  ||        &info2.GetDataSource() != this) {        // Can not compare TSEs from different data sources or        // without a loader.        return 0;    }    if (!m_Loader) {        if ( info1.GetIdHandle().IsBetter(info2.GetIdHandle()) ) {            return &info1;        }        if ( info2.GetIdHandle().IsBetter(info1.GetIdHandle()) ) {            return &info2;        }        return 0;    }    TTSE_LockSet tse_set;    tse_set.insert(TTSE_Lock(&info1.GetTSE_Info()));    tse_set.insert(TTSE_Lock(&info2.GetTSE_Info()));    CConstRef<CTSE_Info> tse = m_Loader->ResolveConflict(id, tse_set);    if (tse == &info1.GetTSE_Info()) {        return &info1;    }    if (tse == &info2.GetTSE_Info()) {        return &info2;    }    return 0;}string CDataSource::GetName(void) const{    if ( m_Loader )        return m_Loader->GetName();    else        return kEmptyStr;}void CDataSource::GetBioseqs(const CSeq_entry_Info& entry,                             TBioseq_InfoSet& bioseqs,                             CSeq_inst::EMol filter,                             TBioseqLevelFlag level){    // Find TSE_Info    x_CollectBioseqs(entry, bioseqs, filter, level);}void CDataSource::x_CollectBioseqs(const CSeq_entry_Info& info,                                   TBioseq_InfoSet& bioseqs,                                   CSeq_inst::EMol filter,                                   TBioseqLevelFlag level){    // parts should be changed to all before adding bioseqs to the list    if ( info.IsSeq() ) {        const CBioseq_Info& seq = info.GetSeq();        if ( level != CBioseq_CI_Base::eLevel_Parts &&             (filter == CSeq_inst::eMol_not_set ||              seq.GetInst_Mol() == filter) ) {            bioseqs.push_back(ConstRef(&seq));        }    }    else {        const CBioseq_set_Info& set = info.GetSet();        ITERATE( CBioseq_set_Info::TSeq_set, it, set.GetSeq_set() ) {            const CSeq_entry_Info& sub_info = **it;            TBioseqLevelFlag local_level = level;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?