data_source.cpp

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

CPP
1,528
字号
/* * =========================================================================== * PRODUCTION $Log: data_source.cpp,v $ * PRODUCTION Revision 1000.4  2004/06/01 19:23:11  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.133 * PRODUCTION * =========================================================================== *//*  $Id: data_source.cpp,v 1000.4 2004/06/01 19:23:11 gouriano Exp $* ===========================================================================**                            PUBLIC DOMAIN NOTICE*               National Center for Biotechnology Information**  This software/database is a "United States Government Work" under the*  terms of the United States Copyright Act.  It was written as part of*  the author's official duties as a United States Government employee and*  thus cannot be copyrighted.  This software/database is freely available*  to the public for use. The National Library of Medicine and the U.S.*  Government have not placed any restriction on its use or reproduction.**  Although all reasonable efforts have been taken to ensure the accuracy*  and reliability of the software and data, the NLM and the U.S.*  Government do not and cannot warrant the performance or results that*  may be obtained by using this software or data. The NLM and the U.S.*  Government disclaim all warranties, express or implied, including*  warranties of performance, merchantability or fitness for any particular*  purpose.**  Please cite the author in any work or product based on this material.** ===========================================================================** Author: Aleksey Grichenko, Eugene Vasilchenko** File Description:*   DataSource for object manager**/#include <ncbi_pch.hpp>#include <objmgr/impl/data_source.hpp>#include <objmgr/impl/annot_object.hpp>#include <objmgr/impl/handle_range_map.hpp>#include <objmgr/impl/seq_entry_info.hpp>#include <objmgr/impl/seq_annot_info.hpp>#include <objmgr/impl/bioseq_info.hpp>#include <objmgr/impl/bioseq_set_info.hpp>#include <objmgr/impl/tse_info.hpp>#include <objmgr/seqmatch_info.hpp>#include <objmgr/data_loader.hpp>#include <objmgr/seq_map.hpp>#include <objmgr/objmgr_exception.hpp>#include <objmgr/bioseq_ci.hpp> // for CBioseq_CI_Base#include <objects/seqloc/Seq_loc.hpp>#include <objects/seqloc/Seq_interval.hpp>#include <objects/seqloc/Seq_point.hpp>#include <objects/seqloc/Seq_loc_equiv.hpp>#include <objects/seq/Bioseq.hpp>#include <objects/seq/seqport_util.hpp>#include <objects/seqset/Seq_entry.hpp>#include <objects/seqset/Bioseq_set.hpp>#include <objects/seqalign/Seq_align.hpp>#include <objects/seqfeat/Seq_feat.hpp>#include <objects/seqres/Seq_graph.hpp>#include <objmgr/impl/prefetch_impl.hpp>#include <corelib/ncbimtx.hpp>BEGIN_NCBI_SCOPEBEGIN_SCOPE(objects)CTSE_LockingSet::CTSE_LockingSet(void)    : m_LockCount(0){}CTSE_LockingSet::CTSE_LockingSet(const CTSE_LockingSet& tse_set)    : m_LockCount(0), m_TSE_set(tse_set.m_TSE_set){}CTSE_LockingSet::~CTSE_LockingSet(void){    _ASSERT(!x_Locked());}DEFINE_CLASS_STATIC_FAST_MUTEX(CTSE_LockingSet::sm_Mutex);CTSE_LockingSet& CTSE_LockingSet::operator=(const CTSE_LockingSet& tse_set){    CFastMutexGuard guard(sm_Mutex);    _ASSERT(!x_Locked());    m_TSE_set = tse_set.m_TSE_set;    return *this;}bool CTSE_LockingSet::insert(CTSE_Info* tse){    CFastMutexGuard guard(sm_Mutex);    bool ins = m_TSE_set.insert(tse).second;    if ( ins && x_Locked() ) {        tse->AddReference();    }    return ins;}bool CTSE_LockingSet::erase(CTSE_Info* tse){    CFastMutexGuard guard(sm_Mutex);    if ( m_TSE_set.erase(tse) ) {        if ( x_Locked() ) {            tse->RemoveReference();        }        return true;    }    return false;}void CTSE_LockingSet::x_Lock(void){    CFastMutexGuard guard(sm_Mutex);    if ( m_LockCount++ == 0 ) {        NON_CONST_ITERATE( TTSESet, it, m_TSE_set ) {            (*it)->AddReference();        }    }    _ASSERT(m_LockCount > 0);}void CTSE_LockingSet::x_Unlock(void){    CFastMutexGuard guard(sm_Mutex);    _ASSERT(m_LockCount > 0);    if ( --m_LockCount == 0 ) {        NON_CONST_ITERATE( TTSESet, it, m_TSE_set ) {            (*it)->RemoveReference();        }    }}CDataSource::CDataSource(CDataLoader& loader, CObjectManager& objmgr)    : m_Loader(&loader),      m_ObjMgr(&objmgr),      m_DefaultPriority(99){    m_Loader->SetTargetDataSource(*this);}CDataSource::CDataSource(CSeq_entry& entry, CObjectManager& objmgr)    : m_Loader(0),      m_pTopEntry(&entry),      m_ObjMgr(&objmgr),      m_DefaultPriority(9){    AddTSE(entry, false);}CDataSource::~CDataSource(void){    if (m_PrefetchThread) {        // Wait for the prefetch thread to stop        m_PrefetchThread->Terminate();        m_PrefetchThread->Join();    }    DropAllTSEs();    m_Loader.Reset();}CConstRef<CTSE_Info> CDataSource::GetTopEntry_Info(void){    CConstRef<CTSE_Info> ret;    {{        TMainReadLockGuard guard(m_DSMainLock);            ITERATE ( TTSE_Set, it, m_TSE_Set ) {            if ( (*it)->GetSeq_entryCore() == m_pTopEntry ) {                ret = *it;                break;            }        }    }}    return ret;}void CDataSource::DropAllTSEs(void){    // Lock indexes    TMainWriteLockGuard guard(m_DSMainLock);        ITERATE ( TTSE_Set, it, m_TSE_Set ) {        if ( (*it)->Locked() ) {            ERR_POST("CDataSource::DropAllTSEs: tse is locked");            NCBI_THROW(CObjMgrException, eOtherError,                       "CDataSource::DropAllTSEs: tse is locked");        }    }    if ( m_Loader ) {        NON_CONST_ITERATE ( TTSE_Set, it, m_TSE_Set ) {            m_Loader->DropTSE(**it);        }    }    //m_Bioseq_InfoMap.clear();    //m_Seq_annot_InfoMap.clear();    //m_Seq_entry_InfoMap.clear();    //m_TSE_InfoMap.clear();    m_TSE_Set.clear();    m_pTopEntry.Reset();    m_TSE_seq.clear();    {{        TAnnotWriteLockGuard guard2(m_DSAnnotLock);        m_TSE_annot.clear();        m_DirtyAnnot_TSEs.clear();    }}}TTSE_Lock CDataSource::x_FindBestTSE(const CSeq_id_Handle& handle) const{    TTSE_LockSet all_tse;    size_t all_count = 0;    {{        TMainReadLockGuard guard(m_DSMainLock);        TTSEMap::const_iterator tse_set = m_TSE_seq.find(handle);        if ( tse_set == m_TSE_seq.end() ) {            return TTSE_Lock();        }        ITERATE ( CTSE_LockingSet, it, tse_set->second ) {            if ( all_tse.insert(TTSE_Lock(*it)).second )                ++all_count;        }        if ( all_count == 0 ) {            return TTSE_Lock();        }    }}    if ( all_count == 1 ) {        // There is only one TSE, no matter live or dead        return TTSE_Lock(*all_tse.begin());    }    // The map should not contain empty entries    _ASSERT(!all_tse.empty());    TTSE_LockSet live_tse;    size_t live_count = 0;    ITERATE ( TTSE_LockSet, tse, all_tse ) {        // Find live TSEs        if ( !(*tse)->IsDead() ) {            live_tse.insert(*tse);            ++live_count;        }    }    // Check live    if ( live_count == 1 ) {        // There is only one live TSE -- ok to use it        return *live_tse.begin();    }    else if ( live_count == 0 ) {        if ( m_Loader ) {            TTSE_Lock best(GetDataLoader()->ResolveConflict(handle, all_tse));            if ( best ) {                return best;            }        }        // No live TSEs -- try to select the best dead TSE        NCBI_THROW(CObjMgrException, eFindConflict,                   "Multiple seq-id matches found");    }    if ( m_Loader ) {        // Multiple live TSEs - try to resolve the conflict (the status of some        // TSEs may change)        TTSE_Lock best(GetDataLoader()->ResolveConflict(handle, live_tse));        if ( best ) {            return best;        }    }    NCBI_THROW(CObjMgrException, eFindConflict,               "Multiple live entries found");}TTSE_Lock CDataSource::GetBlobById(const CSeq_id_Handle& idh){    TMainReadLockGuard guard(m_DSMainLock);    TTSEMap::iterator tse_set = m_TSE_seq.find(idh);    if (tse_set == m_TSE_seq.end()) {        // Request TSE-info from loader if any        if ( m_Loader ) {            //        }        else {            // No such blob, no loader to call            return TTSE_Lock();        }//###    }//###    return TTSE_Lock();}CConstRef<CBioseq_Info> CDataSource::GetBioseq_Info(const CSeqMatch_Info& info){    CRef<CBioseq_Info> ret;    // The TSE is locked by the scope, so, it can not be deleted.    CTSE_Info::TBioseqs::const_iterator found =        info.GetTSE_Info().m_Bioseqs.find(info.GetIdHandle());    if ( found != info.GetTSE_Info().m_Bioseqs.end() ) {        ret = found->second;    }    return ret;}CRef<CTSE_Info> CDataSource::AddTSE(CSeq_entry& tse,                                    bool dead,                                    const CObject* blob_id){    CRef<CTSE_Info> info(new CTSE_Info(tse, dead, blob_id));    AddTSE(info);    return info;}void CDataSource::AddTSE(CRef<CTSE_Info> info){    TMainWriteLockGuard guard(m_DSMainLock);    _VERIFY(m_TSE_Set.insert(info).second);    info->x_DSAttach(*this);}bool CDataSource::DropTSE(CTSE_Info& info){    TMainWriteLockGuard guard(m_DSMainLock);    if ( info.Locked() ) {        _TRACE("DropTSE: DS="<<this<<" TSE_Info="<<&info<<" - locked");        return false; // Not really dropped, although found    }    CRef<CTSE_Info> info_lock(&info);    x_DropTSE(info);    return true;}void CDataSource::x_DropTSE(CTSE_Info& info){    if ( m_Loader ) {        m_Loader->DropTSE(info);    }    info.x_DSDetach(*this);    _VERIFY(m_TSE_Set.erase(Ref(&info)));    {{        TAnnotWriteLockGuard guard2(m_DSAnnotLock);        m_DirtyAnnot_TSEs.erase(&info);    }}}template<class Map, class Ref, class Info>inlinevoid x_MapObject(Map& info_map, const Ref& ref, const Info& info){    typedef typename Map::value_type value_type;    if ( !info_map.insert(value_type(ref, info)).second ) {        NCBI_THROW(CObjMgrException, eOtherError,                   "CDataSource::x_Map(): object already mapped");    }}template<class Map, class Ref, class Info>inlinevoid x_UnmapObject(Map& info_map, const Ref& ref, const Info& _DEBUG_ARG(info)){    typename Map::iterator iter = info_map.lower_bound(ref);    if ( iter != info_map.end() && iter->first == ref ) {        _ASSERT(iter->second == info);        info_map.erase(iter);    }}void CDataSource::x_Map(CConstRef<CSeq_entry> obj, CTSE_Info* info){    x_MapObject(m_TSE_InfoMap, obj, info);}void CDataSource::x_Unmap(CConstRef<CSeq_entry> obj, CTSE_Info* info){    x_UnmapObject(m_TSE_InfoMap, obj, info);}void CDataSource::x_Map(CConstRef<CSeq_entry> obj, CSeq_entry_Info* info){    x_MapObject(m_Seq_entry_InfoMap, obj, info);}void CDataSource::x_Unmap(CConstRef<CSeq_entry> obj, CSeq_entry_Info* info){    x_UnmapObject(m_Seq_entry_InfoMap, obj, info);}void CDataSource::x_Map(CConstRef<CSeq_annot> obj, CSeq_annot_Info* info){    x_MapObject(m_Seq_annot_InfoMap, obj, info);}void CDataSource::x_Unmap(CConstRef<CSeq_annot> obj, CSeq_annot_Info* info){    x_UnmapObject(m_Seq_annot_InfoMap, obj, info);}void CDataSource::x_Map(CConstRef<CBioseq> obj, CBioseq_Info* info){    x_MapObject(m_Bioseq_InfoMap, obj, info);}void CDataSource::x_Unmap(CConstRef<CBioseq> obj, CBioseq_Info* info){    x_UnmapObject(m_Bioseq_InfoMap, obj, info);}///////////////////////////////////////////////////////////////////////////////   mapping of various XXX_Info// CDataSource must be guarded by mutex/////////////////////////////////////////////////////////////////////////////CConstRef<CTSE_Info>CDataSource::FindTSEInfo(const CSeq_entry& tse){    TMainReadLockGuard guard(m_DSMainLock);    return x_FindTSE_Info(tse);}CConstRef<CSeq_entry_Info>CDataSource::FindSeq_entry_Info(const CSeq_entry& entry){    TMainReadLockGuard guard(m_DSMainLock);    return x_FindSeq_entry_Info(entry);}CConstRef<CSeq_annot_Info>CDataSource::FindSeq_annot_Info(const CSeq_annot& annot){    TMainReadLockGuard guard(m_DSMainLock);    return x_FindSeq_annot_Info(annot);}CConstRef<CBioseq_Info>CDataSource::FindBioseq_Info(const CBioseq& bioseq){    TMainReadLockGuard guard(m_DSMainLock);    return x_FindBioseq_Info(bioseq);}CConstRef<CTSE_Info>CDataSource::x_FindTSE_Info(const CSeq_entry& obj){    CConstRef<CTSE_Info> ret;    TTSE_InfoMap::iterator found = m_TSE_InfoMap.find(ConstRef(&obj));    if ( found != m_TSE_InfoMap.end() ) {        ret.Reset(found->second);    }    return ret;}CConstRef<CSeq_entry_Info>CDataSource::x_FindSeq_entry_Info(const CSeq_entry& obj){    CConstRef<CSeq_entry_Info> ret;    TSeq_entry_InfoMap::iterator found =        m_Seq_entry_InfoMap.find(ConstRef(&obj));    if ( found != m_Seq_entry_InfoMap.end() ) {

⌨️ 快捷键说明

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