scope_impl.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:55k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: scope_impl.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 19:23:39  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.15
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: scope_impl.cpp,v 1000.3 2004/06/01 19:23:39 gouriano Exp $
  10. * ===========================================================================
  11. *
  12. *                            PUBLIC DOMAIN NOTICE
  13. *               National Center for Biotechnology Information
  14. *
  15. *  This software/database is a "United States Government Work" under the
  16. *  terms of the United States Copyright Act.  It was written as part of
  17. *  the author's official duties as a United States Government employee and
  18. *  thus cannot be copyrighted.  This software/database is freely available
  19. *  to the public for use. The National Library of Medicine and the U.S.
  20. *  Government have not placed any restriction on its use or reproduction.
  21. *
  22. *  Although all reasonable efforts have been taken to ensure the accuracy
  23. *  and reliability of the software and data, the NLM and the U.S.
  24. *  Government do not and cannot warrant the performance or results that
  25. *  may be obtained by using this software or data. The NLM and the U.S.
  26. *  Government disclaim all warranties, express or implied, including
  27. *  warranties of performance, merchantability or fitness for any particular
  28. *  purpose.
  29. *
  30. *  Please cite the author in any work or product based on this material.
  31. *
  32. * ===========================================================================
  33. *
  34. * Authors:
  35. *           Andrei Gourianov
  36. *           Aleksey Grichenko
  37. *           Michael Kimelman
  38. *           Denis Vakatov
  39. *           Eugene Vasilchenko
  40. *
  41. * File Description:
  42. *           Scope is top-level object available to a client.
  43. *           Its purpose is to define a scope of visibility and reference
  44. *           resolution and provide access to the bio sequence data
  45. *
  46. */
  47. #include <ncbi_pch.hpp>
  48. #include <objmgr/scope.hpp>
  49. #include <objmgr/bioseq_handle.hpp>
  50. #include <objmgr/seq_entry_handle.hpp>
  51. #include <objmgr/seq_annot_handle.hpp>
  52. #include <objmgr/bioseq_set_handle.hpp>
  53. #include <objmgr/object_manager.hpp>
  54. #include <objmgr/seqmatch_info.hpp>
  55. #include <objmgr/objmgr_exception.hpp>
  56. #include <objmgr/impl/data_source.hpp>
  57. #include <objmgr/impl/tse_info.hpp>
  58. #include <objmgr/impl/scope_info.hpp>
  59. #include <objmgr/impl/bioseq_info.hpp>
  60. #include <objmgr/impl/bioseq_set_info.hpp>
  61. #include <objmgr/impl/seq_annot_info.hpp>
  62. #include <objmgr/impl/priority.hpp>
  63. #include <objmgr/impl/synonyms.hpp>
  64. #include <objects/seq/Bioseq.hpp>
  65. #include <objects/seq/Delta_seq.hpp>
  66. #include <objects/seq/Seq_literal.hpp>
  67. #include <objects/seqloc/Seq_loc.hpp>
  68. #include <objects/seqloc/Textseq_id.hpp>
  69. #include <objects/seqset/Seq_entry.hpp>
  70. #include <objmgr/impl/scope_impl.hpp>
  71. BEGIN_NCBI_SCOPE
  72. BEGIN_SCOPE(objects)
  73. /////////////////////////////////////////////////////////////////////////////
  74. //
  75. //  CScope_Impl
  76. //
  77. /////////////////////////////////////////////////////////////////////////////
  78. CScope_Impl::CScope_Impl(CObjectManager& objmgr)
  79.     : m_HeapScope(0), m_pObjMgr(0)
  80. {
  81.     TWriteLockGuard guard(m_Scope_Conf_RWLock);
  82.     x_AttachToOM(objmgr);
  83. }
  84. CScope_Impl::~CScope_Impl(void)
  85. {
  86.     TWriteLockGuard guard(m_Scope_Conf_RWLock);
  87.     x_DetachFromOM();
  88. }
  89. void CScope_Impl::x_AttachToOM(CObjectManager& objmgr)
  90. {
  91.     if ( m_pObjMgr != &objmgr ) {
  92.         x_DetachFromOM();
  93.         
  94.         m_pObjMgr = &objmgr;
  95.         m_pObjMgr->RegisterScope(*this);
  96.     }
  97. }
  98. void CScope_Impl::x_DetachFromOM(void)
  99. {
  100.     if ( m_pObjMgr ) {
  101.         // Drop and release all TSEs
  102.         x_ResetHistory();
  103.         m_pObjMgr->RevokeScope(*this);
  104.         for (CPriority_I it(m_setDataSrc); it; ++it) {
  105.             _ASSERT(it->m_DataSource);
  106.             m_pObjMgr->ReleaseDataSource(it->m_DataSource);
  107.             _ASSERT(!it->m_DataSource);
  108.         }
  109.         m_pObjMgr = 0;
  110.     }
  111. }
  112. void CScope_Impl::AddDefaults(TPriority priority)
  113. {
  114.     CObjectManager::TDataSourcesLock ds_set;
  115.     m_pObjMgr->AcquireDefaultDataSources(ds_set);
  116.     TWriteLockGuard guard(m_Scope_Conf_RWLock);
  117.     NON_CONST_ITERATE( CObjectManager::TDataSourcesLock, it, ds_set ) {
  118.         m_setDataSrc.Insert(const_cast<CDataSource&>(**it),
  119.             (priority == kPriority_NotSet) ?
  120.             (*it)->GetDefaultPriority() : priority);
  121.     }
  122.     x_ClearCacheOnNewData();
  123. }
  124. void CScope_Impl::AddDataLoader (const string& loader_name,
  125.                                  TPriority priority)
  126. {
  127.     CRef<CDataSource> ds = m_pObjMgr->AcquireDataLoader(loader_name);
  128.     TWriteLockGuard guard(m_Scope_Conf_RWLock);
  129.     m_setDataSrc.Insert(*ds, (priority == kPriority_NotSet) ?
  130.         ds->GetDefaultPriority() : priority);
  131.     x_ClearCacheOnNewData();
  132. }
  133. CSeq_entry_Handle CScope_Impl::AddTopLevelSeqEntry(CSeq_entry& top_entry,
  134.                                                    TPriority priority)
  135. {
  136.     CRef<CDataSource> ds = m_pObjMgr->AcquireTopLevelSeqEntry(top_entry);
  137.     TWriteLockGuard guard(m_Scope_Conf_RWLock);
  138.     m_setDataSrc.Insert(*ds, (priority == kPriority_NotSet) ?
  139.         ds->GetDefaultPriority() : priority);
  140.     x_ClearCacheOnNewData();
  141.     return CSeq_entry_Handle(*m_HeapScope, *x_GetSeq_entry_Info(top_entry));
  142. }
  143. void CScope_Impl::AddScope(CScope_Impl& scope,
  144.                            TPriority priority)
  145. {
  146.     TReadLockGuard src_guard(scope.m_Scope_Conf_RWLock);
  147.     CPriorityTree tree(scope.m_setDataSrc);
  148.     src_guard.Release();
  149.     
  150.     TWriteLockGuard guard(m_Scope_Conf_RWLock);
  151.     m_setDataSrc.Insert(tree, priority);
  152.     x_ClearCacheOnNewData();
  153. }
  154. CBioseq_Handle CScope_Impl::AddBioseq(CBioseq& bioseq,
  155.                                       TPriority priority)
  156. {
  157.     CRef<CSeq_entry> entry(new CSeq_entry);
  158.     entry->SetSeq(bioseq);
  159.     return AddTopLevelSeqEntry(*entry, priority).GetSeq();
  160. }
  161. CSeq_entry_EditHandle
  162. CScope_Impl::x_AttachEntry(const CBioseq_set_EditHandle& seqset,
  163.                            CRef<CSeq_entry_Info> entry,
  164.                            int index)
  165. {
  166.     _ASSERT(seqset && bool(entry));
  167.     TWriteLockGuard guard(m_Scope_Conf_RWLock);
  168.     //seqset.GetDataSource().AttachEntry(seqset, entry, index);
  169.     seqset.x_GetInfo().AddEntry(entry, index);
  170.     x_ClearCacheOnNewData();
  171.     return CSeq_entry_EditHandle(*m_HeapScope, *entry);
  172. }
  173. CBioseq_EditHandle
  174. CScope_Impl::x_SelectSeq(const CSeq_entry_EditHandle& entry,
  175.                          CRef<CBioseq_Info> bioseq)
  176. {
  177.     _ASSERT(entry && bool(bioseq));
  178.     _ASSERT(entry.Which() == CSeq_entry::e_not_set);
  179.     TWriteLockGuard guard(m_Scope_Conf_RWLock);
  180.     // duplicate bioseq info
  181.     entry.x_GetInfo().SelectSeq(*bioseq);
  182.     x_ClearCacheOnNewData();
  183.     return GetBioseqHandle(*bioseq).GetEditHandle();
  184. }
  185. CBioseq_set_EditHandle
  186. CScope_Impl::x_SelectSet(const CSeq_entry_EditHandle& entry,
  187.                          CRef<CBioseq_set_Info> seqset)
  188. {
  189.     _ASSERT(entry && bool(seqset));
  190.     _ASSERT(entry.Which() == CSeq_entry::e_not_set);
  191.     TWriteLockGuard guard(m_Scope_Conf_RWLock);
  192.     // duplicate bioseq info
  193.     entry.x_GetInfo().SelectSet(*seqset);
  194.     x_ClearCacheOnNewData();
  195.     return CBioseq_set_EditHandle(*m_HeapScope, *seqset);
  196. }
  197. CSeq_annot_EditHandle
  198. CScope_Impl::x_AttachAnnot(const CSeq_entry_EditHandle& entry,
  199.                            CRef<CSeq_annot_Info> annot)
  200. {
  201.     _ASSERT(entry && bool(annot));
  202.     TWriteLockGuard guard(m_Scope_Conf_RWLock);
  203.     entry.x_GetInfo().AddAnnot(annot);
  204.     x_ClearAnnotCache();
  205.     return CSeq_annot_EditHandle(*m_HeapScope, *annot);
  206. }
  207. CSeq_entry_EditHandle
  208. CScope_Impl::AttachEntry(const CBioseq_set_EditHandle& seqset,
  209.                          CSeq_entry& entry,
  210.                          int index)
  211. {
  212.     return x_AttachEntry(seqset, Ref(new CSeq_entry_Info(entry)), index);
  213. }
  214. CSeq_entry_EditHandle
  215. CScope_Impl::CopyEntry(const CBioseq_set_EditHandle& seqset,
  216.                        const CSeq_entry_Handle& entry,
  217.                        int index)
  218. {
  219.     return x_AttachEntry(seqset, Ref(new CSeq_entry_Info(entry.x_GetInfo())),
  220.                          index);
  221. }
  222. CSeq_entry_EditHandle
  223. CScope_Impl::TakeEntry(const CBioseq_set_EditHandle& seqset,
  224.                        const CSeq_entry_EditHandle& entry,
  225.                        int index)
  226. {
  227.     CRef<CSeq_entry_Info> info(&entry.x_GetInfo());
  228.     entry.Remove();
  229.     return x_AttachEntry(seqset, info, index);
  230. }
  231. CBioseq_EditHandle CScope_Impl::SelectSeq(const CSeq_entry_EditHandle& entry,
  232.                                           CBioseq& seq)
  233. {
  234.     return x_SelectSeq(entry, Ref(new CBioseq_Info(seq)));
  235. }
  236. CBioseq_EditHandle CScope_Impl::CopySeq(const CSeq_entry_EditHandle& entry,
  237.                                         const CBioseq_Handle& seq)
  238. {
  239.     return x_SelectSeq(entry, Ref(new CBioseq_Info(seq.x_GetInfo())));
  240. }
  241. CBioseq_EditHandle CScope_Impl::TakeSeq(const CSeq_entry_EditHandle& entry,
  242.                                         const CBioseq_EditHandle& seq)
  243. {
  244.     CRef<CBioseq_Info> info(&seq.x_GetInfo());
  245.     seq.Remove();
  246.     return x_SelectSeq(entry, info);
  247. }
  248. CBioseq_set_EditHandle
  249. CScope_Impl::SelectSet(const CSeq_entry_EditHandle& entry,
  250.                        CBioseq_set& seqset)
  251. {
  252.     return x_SelectSet(entry, Ref(new CBioseq_set_Info(seqset)));
  253. }
  254. CBioseq_set_EditHandle
  255. CScope_Impl::CopySet(const CSeq_entry_EditHandle& entry,
  256.                      const CBioseq_set_Handle& seqset)
  257. {
  258.     return x_SelectSet(entry, Ref(new CBioseq_set_Info(seqset.x_GetInfo())));
  259. }
  260. CBioseq_set_EditHandle
  261. CScope_Impl::TakeSet(const CSeq_entry_EditHandle& entry,
  262.                      const CBioseq_set_EditHandle& seqset)
  263. {
  264.     CRef<CBioseq_set_Info> info(&seqset.x_GetInfo());
  265.     seqset.Remove();
  266.     return x_SelectSet(entry, info);
  267. }
  268. CSeq_annot_EditHandle
  269. CScope_Impl::AttachAnnot(const CSeq_entry_EditHandle& entry,
  270.                          const CSeq_annot& annot)
  271. {
  272.     return x_AttachAnnot(entry, Ref(new CSeq_annot_Info(annot)));
  273. }
  274. CSeq_annot_EditHandle
  275. CScope_Impl::CopyAnnot(const CSeq_entry_EditHandle& entry,
  276.                        const CSeq_annot_Handle& annot)
  277. {
  278.     return x_AttachAnnot(entry, Ref(new CSeq_annot_Info(annot.x_GetInfo())));
  279. }
  280. CSeq_annot_EditHandle
  281. CScope_Impl::TakeAnnot(const CSeq_entry_EditHandle& entry,
  282.                        const CSeq_annot_EditHandle& annot)
  283. {
  284.     CRef<CSeq_annot_Info> info(&annot.x_GetInfo());
  285.     annot.Remove();
  286.     return x_AttachAnnot(entry, info);
  287. }
  288. void CScope_Impl::x_ClearCacheOnNewData(void)
  289. {
  290.     // Clear unresolved bioseq handles
  291.     // Clear annot cache
  292.     if (!m_Seq_idMap.empty()) {
  293.         LOG_POST(Info <<
  294.             "CScope_Impl: -- "
  295.             "adding new data to a scope with non-empty cache "
  296.             "may cause the cached data to become inconsistent");
  297.     }
  298.     NON_CONST_ITERATE ( TSeq_idMap, it, m_Seq_idMap ) {
  299.         if ( it->second.m_Bioseq_Info &&
  300.              !it->second.m_Bioseq_Info->HasBioseq() ) {
  301.             it->second.m_Bioseq_Info->m_SynCache.Reset();
  302.             it->second.m_Bioseq_Info.Reset();
  303.         }
  304.         it->second.m_AllAnnotRef_Info.Reset();
  305.     }
  306. }
  307. void CScope_Impl::x_ClearAnnotCache(void)
  308. {
  309.     // Clear annot cache
  310.     NON_CONST_ITERATE ( TSeq_idMap, it, m_Seq_idMap ) {
  311.         it->second.m_AllAnnotRef_Info.Reset();
  312.     }
  313. }
  314. void CScope_Impl::x_ClearCacheOnRemoveData(const CSeq_entry_Info& info)
  315. {
  316.     if ( info.IsSeq() ) {
  317.         x_ClearCacheOnRemoveData(info.GetSeq());
  318.     }
  319.     else {
  320.         x_ClearCacheOnRemoveData(info.GetSet());
  321.     }
  322. }
  323. void CScope_Impl::x_ClearCacheOnRemoveData(const CBioseq_Info& seq)
  324. {
  325.     // Clear bioseq from the scope cache
  326.     ITERATE ( CBioseq_Info::TId, si, seq.GetId() ) {
  327.         TSeq_idMap::iterator bs_id = m_Seq_idMap.find(*si);
  328.         if (bs_id != m_Seq_idMap.end()) {
  329.             if ( bs_id->second.m_Bioseq_Info ) {
  330.                 // detaching from scope
  331.                 bs_id->second.m_Bioseq_Info->m_ScopeInfo = 0;
  332.                 // breaking the link
  333.                 bs_id->second.m_Bioseq_Info->m_SynCache.Reset();
  334.             }
  335.             m_Seq_idMap.erase(bs_id);
  336.         }
  337.         m_BioseqMap.erase(&seq);
  338.     }
  339. }
  340. void CScope_Impl::x_ClearCacheOnRemoveData(const CBioseq_set_Info& seqset)
  341. {
  342.     ITERATE( CBioseq_set_Info::TSeq_set, ei, seqset.GetSeq_set() ) {
  343.         x_ClearCacheOnRemoveData(**ei);
  344.     }
  345. }
  346. CSeq_entry_Handle CScope_Impl::GetSeq_entryHandle(const CSeq_entry& entry)
  347. {
  348.     TReadLockGuard guard(m_Scope_Conf_RWLock);
  349.     return CSeq_entry_Handle(*m_HeapScope, *x_GetSeq_entry_Info(entry));
  350. }
  351. CSeq_annot_Handle CScope_Impl::GetSeq_annotHandle(const CSeq_annot& annot)
  352. {
  353.     TReadLockGuard guard(m_Scope_Conf_RWLock);
  354.     return CSeq_annot_Handle(*m_HeapScope, *x_GetSeq_annot_Info(annot));
  355. }
  356. CBioseq_Handle CScope_Impl::GetBioseqHandle(const CBioseq& seq)
  357. {
  358.     CBioseq_Handle ret;
  359.     {{
  360.         TReadLockGuard guard(m_Scope_Conf_RWLock);
  361.         CConstRef<CBioseq_Info> info = x_GetBioseq_Info(seq);
  362.         ITERATE ( CBioseq_Info::TId, id, info->GetId() ) {
  363.             ret = x_GetBioseqHandleFromTSE(*id, info->GetTSE_Info());
  364.             if ( ret ) {
  365.                 _ASSERT(ret.GetBioseqCore() == &seq);
  366.                 break;
  367.             }
  368.         }
  369.     }}
  370.     return ret;
  371. }
  372. CConstRef<CTSE_Info>
  373. CScope_Impl::x_GetTSE_Info(const CSeq_entry& tse)
  374. {
  375.     for (CPriority_I it(m_setDataSrc); it; ++it) {
  376.         CConstRef<CTSE_Info> info = it->GetDataSource().FindTSEInfo(tse);
  377.         if ( info ) {
  378.             {{
  379.                 CFastMutexGuard guard(it->GetMutex());
  380.                 it->AddTSE(*info);
  381.             }}
  382.             return info;
  383.         }
  384.     }
  385.     NCBI_THROW(CObjMgrException, eFindFailed,
  386.                "CScope_Impl::x_GetTSE_Info: entry is not attached");
  387. }
  388. CConstRef<CSeq_entry_Info>
  389. CScope_Impl::x_GetSeq_entry_Info(const CSeq_entry& entry)
  390. {
  391.     for (CPriority_I it(m_setDataSrc); it; ++it) {
  392.         CConstRef<CSeq_entry_Info> info =
  393.             it->GetDataSource().FindSeq_entry_Info(entry);
  394.         if ( info ) {
  395.             {{
  396.                 CFastMutexGuard guard(it->GetMutex());
  397.                 it->AddTSE(info->GetTSE_Info());
  398.             }}
  399.             return info;
  400.         }
  401.     }
  402.     NCBI_THROW(CObjMgrException, eFindFailed,
  403.                "CScope_Impl::x_GetSeq_entry_Info: entry is not attached");
  404. }
  405. CConstRef<CSeq_annot_Info>
  406. CScope_Impl::x_GetSeq_annot_Info(const CSeq_annot& annot)
  407. {
  408.     for (CPriority_I it(m_setDataSrc); it; ++it) {
  409.         CConstRef<CSeq_annot_Info> info =
  410.             it->GetDataSource().FindSeq_annot_Info(annot);
  411.         if ( info ) {
  412.             {{
  413.                 CFastMutexGuard guard(it->GetMutex());
  414.                 it->AddTSE(info->GetTSE_Info());
  415.             }}
  416.             return info;
  417.         }
  418.     }
  419.     NCBI_THROW(CObjMgrException, eFindFailed,
  420.                "CScope_Impl::x_GetSeq_annot_Info: annot is not attached");
  421. }
  422. CConstRef<CBioseq_Info>
  423. CScope_Impl::x_GetBioseq_Info(const CBioseq& bioseq)
  424. {
  425.     for (CPriority_I it(m_setDataSrc); it; ++it) {
  426.         CConstRef<CBioseq_Info> info =
  427.             it->GetDataSource().FindBioseq_Info(bioseq);
  428.         if ( info ) {
  429.             {{
  430.                 CFastMutexGuard guard(it->GetMutex());
  431.                 it->AddTSE(info->GetTSE_Info());
  432.             }}
  433.             return info;
  434.         }
  435.     }
  436.     NCBI_THROW(CObjMgrException, eFindFailed,
  437.                "CScope_Impl::x_GetBioseq_Info: bioseq is not attached");
  438. }
  439. void CScope_Impl::RemoveAnnot(const CSeq_annot_EditHandle& annot)
  440. {
  441.     TWriteLockGuard guard(m_Scope_Conf_RWLock);
  442.     CSeq_annot_Info& info = annot.x_GetInfo();
  443.     info.GetDataSource().RemoveAnnot(info);
  444.     x_ClearAnnotCache();
  445. }
  446. void CScope_Impl::SelectNone(const CSeq_entry_EditHandle& entry)
  447. {
  448.     _ASSERT(entry);
  449.     TWriteLockGuard guard(m_Scope_Conf_RWLock);
  450.     CSeq_entry_Info& info = entry.x_GetInfo();
  451.     x_ClearAnnotCache();
  452.     switch ( info.Which() ) {
  453.     case CSeq_entry::e_Set:
  454.         x_ClearCacheOnRemoveData(info.GetSet());
  455.         break;
  456.     case CSeq_entry::e_Seq:
  457.         x_ClearCacheOnRemoveData(info.GetSeq());
  458.         break;
  459.     default:
  460.         break;
  461.     }
  462.     // duplicate bioseq info
  463.     info.Reset();
  464. }
  465. void CScope_Impl::RemoveEntry(const CSeq_entry_EditHandle& entry)
  466. {
  467.     TWriteLockGuard guard(m_Scope_Conf_RWLock);
  468.     CSeq_entry_Info& info = entry.x_GetInfo();
  469.     x_ClearAnnotCache();
  470.     x_ClearCacheOnRemoveData(info);
  471.     if ( entry.GetParentEntry() ) {
  472.         info.GetDataSource().RemoveEntry(info);
  473.     }
  474.     else {
  475.         // top level entry
  476.         CDataSource_ScopeInfo* ds_info = 0;
  477.         for (CPriority_I it(m_setDataSrc); it; ++it) {
  478.             if ( &it->GetDataSource() == &info.GetDataSource() ) {
  479.                 ds_info = &*it;
  480.                 break;
  481.             }
  482.         }
  483.         if ( ds_info ) {
  484.             m_setDataSrc.Erase(*ds_info);
  485.         }
  486.         else {
  487.             // not found...
  488.             NCBI_THROW(CObjMgrException, eModifyDataError,
  489.                        "CScope::RemoveEntry(): cannot find data source");
  490.         }
  491.     }
  492. }
  493. void CScope_Impl::RemoveBioseq(const CBioseq_EditHandle& seq)
  494. {
  495.     TWriteLockGuard guard(m_Scope_Conf_RWLock);
  496.     CBioseq_Info& info = seq.x_GetInfo();
  497.     x_ClearAnnotCache();
  498.     x_ClearCacheOnRemoveData(info);
  499.     info.GetParentSeq_entry_Info().Reset();
  500. }
  501. void CScope_Impl::RemoveBioseq_set(const CBioseq_set_EditHandle& seqset)
  502. {
  503.     TWriteLockGuard guard(m_Scope_Conf_RWLock);
  504.     CBioseq_set_Info& info = seqset.x_GetInfo();
  505.     x_ClearAnnotCache();
  506.     x_ClearCacheOnRemoveData(info);
  507.     info.GetParentSeq_entry_Info().Reset();
  508. }
  509. CScope_Impl::TSeq_idMapValue&
  510. CScope_Impl::x_GetSeq_id_Info(const CSeq_id_Handle& id)
  511. {
  512.     {{
  513.         TReadLockGuard guard(m_Seq_idMapLock);
  514.         TSeq_idMap::iterator it = m_Seq_idMap.lower_bound(id);
  515.         if ( it != m_Seq_idMap.end() && it->first == id )
  516.             return *it;
  517.     }}
  518.     {{
  519.         TWriteLockGuard guard(m_Seq_idMapLock);
  520.         return *m_Seq_idMap.insert(
  521.             TSeq_idMapValue(id, SSeq_id_ScopeInfo(m_HeapScope))).first;
  522.     }}
  523. }
  524. inline
  525. CScope_Impl::TSeq_idMapValue&
  526. CScope_Impl::x_GetSeq_id_Info(const CBioseq_Handle& bh)
  527. {
  528.     TSeq_idMapValue* info = bh.x_GetScopeInfo().m_ScopeInfo;
  529.     if ( info->first != bh.GetSeq_id_Handle() ) {
  530.         info = &x_GetSeq_id_Info(bh.GetSeq_id_Handle());
  531.     }
  532.     return *info;
  533. }
  534. CScope_Impl::TSeq_idMapValue*
  535. CScope_Impl::x_FindSeq_id_Info(const CSeq_id_Handle& id)
  536. {
  537.     TReadLockGuard guard(m_Seq_idMapLock);
  538.     TSeq_idMap::iterator it = m_Seq_idMap.lower_bound(id);
  539.     if ( it != m_Seq_idMap.end() && it->first == id )
  540.         return &*it;
  541.     return 0;
  542. }
  543. CRef<CBioseq_ScopeInfo>
  544. CScope_Impl::x_InitBioseq_Info(TSeq_idMapValue& info, int get_flag)
  545. {
  546.     if (get_flag != CScope::eGetBioseq_Resolved) {
  547.         // Resolve only if the flag allows
  548.         CInitGuard init(info.second.m_Bioseq_Info, m_MutexPool);
  549.         if ( init ) {
  550.             x_ResolveSeq_id(info, get_flag);
  551.         }
  552.     }
  553.     //_ASSERT(info.second.m_Bioseq_Info);
  554.     return info.second.m_Bioseq_Info;
  555. }
  556. bool CScope_Impl::x_InitBioseq_Info(TSeq_idMapValue& info,
  557.                                     CBioseq_ScopeInfo& bioseq_info)
  558. {
  559.     {{
  560.         CInitGuard init(info.second.m_Bioseq_Info, m_MutexPool);
  561.         if ( init ) {
  562.             _ASSERT(!info.second.m_Bioseq_Info);
  563.             info.second.m_Bioseq_Info.Reset(&bioseq_info);
  564.             return true;
  565.         }
  566.     }}
  567.     return info.second.m_Bioseq_Info.GetPointerOrNull() == &bioseq_info;
  568. }
  569. CRef<CBioseq_ScopeInfo>
  570. CScope_Impl::x_GetBioseq_Info(const CSeq_id_Handle& id, int get_flag)
  571. {
  572.     return x_InitBioseq_Info(x_GetSeq_id_Info(id), get_flag);
  573. }
  574. CRef<CBioseq_ScopeInfo>
  575. CScope_Impl::x_FindBioseq_Info(const CSeq_id_Handle& id, int get_flag)
  576. {
  577.     CRef<CBioseq_ScopeInfo> ret;
  578.     TSeq_idMapValue* info = x_FindSeq_id_Info(id);
  579.     if ( info ) {
  580.         ret = x_InitBioseq_Info(*info, get_flag);
  581.     }
  582.     return ret;
  583. }
  584. CBioseq_Handle CScope_Impl::x_GetBioseqHandleFromTSE(const CSeq_id_Handle& id,
  585.                                                      const CTSE_Info& tse)
  586. {
  587.     CBioseq_Handle ret;
  588.     TReadLockGuard rguard(m_Scope_Conf_RWLock);
  589.     CRef<CBioseq_ScopeInfo> info = x_FindBioseq_Info(id, CScope::eGetBioseq_Loaded);
  590.     if ( bool(info)  &&  info->HasBioseq() ) {
  591.         if ( &info->GetTSE_Info() == &tse ) {
  592.             ret.m_Bioseq_Info = info.GetPointer();
  593.         }
  594.     }
  595.     else {
  596.         // new bioseq - try to find it in source TSE
  597.         {{
  598.             // first try main id
  599.             CSeqMatch_Info match(id, tse);
  600.             CConstRef<CBioseq_Info> bioseq = match.GetBioseq_Info();
  601.             if ( bioseq ) {
  602.                 _ASSERT(m_HeapScope);
  603.                 CBioseq_Handle bh =
  604.                     GetBioseqHandle(id, CScope::eGetBioseq_Loaded);
  605.                 if ( bh && &bh.x_GetInfo().GetTSE_Info() == &tse ) {
  606.                     ret = bh;
  607.                     return ret;
  608.                 }
  609.             }
  610.         }}
  611.         
  612.         CSeq_id_Mapper& mapper = CSeq_id_Mapper::GetSeq_id_Mapper();
  613.         if ( mapper.HaveMatchingHandles(id) ) {
  614.             // than try matching handles
  615.             TSeq_id_HandleSet hset;
  616.             mapper.GetMatchingHandles(id, hset);
  617.             ITERATE ( TSeq_id_HandleSet, hit, hset ) {
  618.                 if ( *hit == id ) // already checked
  619.                     continue;
  620.                 CSeqMatch_Info match(*hit, tse);
  621.                 CConstRef<CBioseq_Info> bioseq = match.GetBioseq_Info();
  622.                 if ( bioseq ) {
  623.                     _ASSERT(m_HeapScope);
  624.                     CBioseq_Handle bh = GetBioseqHandle(*hit,
  625.                         CScope::eGetBioseq_Loaded);
  626.                     if ( bh && &bh.x_GetInfo().GetTSE_Info() == &tse ) {
  627.                         ret = bh;
  628.                         break;
  629.                     }
  630.                 }
  631.             }
  632.         }
  633.     }
  634.     ret.m_Seq_id = id;
  635.     ret.m_Scope.Set(m_HeapScope);
  636.     return ret;
  637. }
  638. CBioseq_Handle CScope_Impl::GetBioseqHandle(const CSeq_id_Handle& id,
  639.                                             int get_flag)
  640. {
  641.     CBioseq_Handle ret;
  642.     if ( id )  {
  643.         {{
  644.             TReadLockGuard rguard(m_Scope_Conf_RWLock);
  645.             ret.m_Bioseq_Info = x_GetBioseq_Info(id, get_flag).GetPointer();
  646.         }}
  647.         if ( bool(ret.m_Bioseq_Info) && !ret.x_GetScopeInfo().HasBioseq() ) {
  648.             ret.m_Bioseq_Info.Reset();
  649.         }
  650.         ret.m_Seq_id = id;
  651.     }
  652.     ret.m_Scope.Set(m_HeapScope);
  653.     return ret;
  654. }
  655. CBioseq_EditHandle CScope_Impl::GetEditHandle(const CBioseq_Handle& h)
  656. {
  657.     if ( !h ) {
  658.         NCBI_THROW(CObjMgrException, eInvalidHandle,
  659.                    "CScope::GetEditHandle: null handle");
  660.     }
  661.     
  662.     if ( h.x_GetInfo().GetDataSource().GetDataLoader() ) {
  663.         NCBI_THROW(CObjMgrException, eNotImplemented,
  664.                    "CScope::GetEditHandle: detach is not implemented");
  665.     }
  666.     
  667.     return CBioseq_EditHandle(h);
  668. }
  669. CSeq_entry_EditHandle CScope_Impl::GetEditHandle(const CSeq_entry_Handle& h)
  670. {
  671.     if ( !h ) {
  672.         NCBI_THROW(CObjMgrException, eInvalidHandle,
  673.                    "CScope::GetEditHandle: null handle");
  674.     }
  675.     
  676.     if ( h.x_GetInfo().GetDataSource().GetDataLoader() ) {
  677.         NCBI_THROW(CObjMgrException, eNotImplemented,
  678.                    "CScope::GetEditHandle: detach is not implemented");
  679.     }
  680.     
  681.     return CSeq_entry_EditHandle(h);
  682. }
  683. CSeq_annot_EditHandle CScope_Impl::GetEditHandle(const CSeq_annot_Handle& h)
  684. {
  685.     if ( !h ) {
  686.         NCBI_THROW(CObjMgrException, eInvalidHandle,
  687.                    "CScope::GetEditHandle: null handle");
  688.     }
  689.     
  690.     if ( h.x_GetInfo().GetDataSource().GetDataLoader() ) {
  691.         NCBI_THROW(CObjMgrException, eNotImplemented,
  692.                    "CScope::GetEditHandle: detach is not implemented");
  693.     }
  694.     
  695.     return CSeq_annot_EditHandle(h);
  696. }
  697. CBioseq_set_EditHandle CScope_Impl::GetEditHandle(const CBioseq_set_Handle& h)
  698. {
  699.     if ( !h ) {
  700.         NCBI_THROW(CObjMgrException, eInvalidHandle,
  701.                    "CScope::GetEditHandle: null handle");
  702.     }
  703.     
  704.     if ( h.x_GetInfo().GetDataSource().GetDataLoader() ) {
  705.         NCBI_THROW(CObjMgrException, eNotImplemented,
  706.                    "CScope::GetEditHandle: detach is not implemented");
  707.     }
  708.     
  709.     return CBioseq_set_EditHandle(h);
  710. }
  711. CBioseq_Handle CScope_Impl::GetBioseqHandle(const CSeq_id& id, int get_flag)
  712. {
  713.     return GetBioseqHandle(CSeq_id_Handle::GetHandle(id), get_flag);
  714. }
  715. CBioseq_Handle
  716. CScope_Impl::GetBioseqHandleFromTSE(const CSeq_id_Handle& id,
  717.                                     const CBioseq_Handle& bh)
  718. {
  719.     CBioseq_Handle ret;
  720.     if ( bh ) {
  721.         ret = x_GetBioseqHandleFromTSE(id, bh.x_GetInfo().GetTSE_Info());
  722.     }
  723.     else {
  724.         ret.m_Seq_id = id;
  725.         ret.m_Scope.Set(m_HeapScope);
  726.     }
  727.     return ret;
  728. }
  729. CBioseq_Handle
  730. CScope_Impl::GetBioseqHandleFromTSE(const CSeq_id_Handle& id,
  731.                                     const CSeq_entry_Handle& seh)
  732. {
  733.     CBioseq_Handle ret;
  734.     if ( seh ) {
  735.         ret = x_GetBioseqHandleFromTSE(id, seh.x_GetInfo().GetTSE_Info());
  736.     }
  737.     else {
  738.         ret.m_Seq_id = id;
  739.         ret.m_Scope.Set(m_HeapScope);
  740.     }
  741.     return ret;
  742. }
  743. CBioseq_Handle
  744. CScope_Impl::GetBioseqHandleFromTSE(const CSeq_id& id,
  745.                                     const CBioseq_Handle& bh)
  746. {
  747.     return GetBioseqHandleFromTSE(CSeq_id_Handle::GetHandle(id), bh);
  748. }
  749. CBioseq_Handle
  750. CScope_Impl::GetBioseqHandleFromTSE(const CSeq_id& id,
  751.                                     const CSeq_entry_Handle& seh)
  752. {
  753.     return GetBioseqHandleFromTSE(CSeq_id_Handle::GetHandle(id), seh);
  754. }
  755. CBioseq_Handle CScope_Impl::GetBioseqHandle(const CSeq_loc& loc, int get_flag)
  756. {
  757.     CBioseq_Handle bh;
  758.     for (CSeq_loc_CI citer (loc); citer; ++citer) {
  759.         bh = GetBioseqHandle(citer.GetSeq_id(), get_flag);
  760.         if ( bh ) {
  761.             break;
  762.         }
  763.     }
  764.     return bh;
  765. }
  766. CBioseq_Handle CScope_Impl::GetBioseqHandle(const CBioseq_Info& seq)
  767. {
  768.     CBioseq_Handle ret;
  769.     {{
  770.         TReadLockGuard guard(m_Scope_Conf_RWLock);
  771.         ret = x_GetBioseqHandle(seq);
  772.     }}
  773.     return ret;
  774. }
  775. CBioseq_Handle CScope_Impl::x_GetBioseqHandle(const CBioseq_Info& seq)
  776. {
  777.     CBioseq_Handle ret;
  778.     ITERATE ( CBioseq_Info::TId, id, seq.GetId() ) {
  779.         CBioseq_Handle bh = x_GetBioseqHandleFromTSE(*id, seq.GetTSE_Info());
  780.         if ( bh && &bh.x_GetInfo() == &seq ) {
  781.             ret = bh;
  782.             break;
  783.         }
  784.     }
  785.     return ret;
  786. }
  787. CDataSource_ScopeInfo*
  788. CScope_Impl::x_FindBioseqInfo(const CPriorityTree& tree,
  789.                               const CSeq_id_Handle& idh,
  790.                               const TSeq_id_HandleSet* hset,
  791.                               CSeqMatch_Info& match_info,
  792.                               int get_flag)
  793. {
  794.     CDataSource_ScopeInfo* ret = 0;
  795.     // Process sub-tree
  796.     TPriority last_priority = 0;
  797.     ITERATE( CPriorityTree::TPriorityMap, mit, tree.GetTree() ) {
  798.         // Search in all nodes of the same priority regardless
  799.         // of previous results
  800.         TPriority new_priority = mit->first;
  801.         if ( new_priority != last_priority ) {
  802.             // Don't process lower priority nodes if something
  803.             // was found
  804.             if ( ret ) {
  805.                 break;
  806.             }
  807.             last_priority = new_priority;
  808.         }
  809.         CDataSource_ScopeInfo* new_ret =
  810.             x_FindBioseqInfo(mit->second, idh, hset, match_info, get_flag);
  811.         if ( new_ret ) {
  812.             _ASSERT(!ret); // should be checked by match_info already
  813.             ret = new_ret;
  814.         }
  815.     }
  816.     return ret;
  817. }
  818. CDataSource_ScopeInfo*
  819. CScope_Impl::x_FindBioseqInfo(CDataSource_ScopeInfo& ds_info,
  820.                               const CSeq_id_Handle& main_idh,
  821.                               const TSeq_id_HandleSet* hset,
  822.                               CSeqMatch_Info& match_info,
  823.                               int get_flag)
  824. {
  825.     // skip already matched CDataSource
  826.     CDataSource& ds = ds_info.GetDataSource();
  827.     if ( match_info && &match_info.GetDataSource() == &ds ) {
  828.         return 0;
  829.     }
  830.     CSeqMatch_Info info;
  831.     {{
  832.         CFastMutexGuard guard(ds_info.GetMutex());
  833.         info = ds.HistoryResolve(main_idh, ds_info.GetTSESet());
  834.         if ( !info && hset ) {
  835.             ITERATE(TSeq_id_HandleSet, hit, *hset) {
  836.                 if ( *hit == main_idh ) // already checked
  837.                     continue;
  838.                 if ( info  &&  info.GetIdHandle().IsBetter(*hit) ) // worse hit
  839.                     continue;
  840.                 CSeqMatch_Info new_info =
  841.                     ds.HistoryResolve(*hit, ds_info.GetTSESet());
  842.                 if ( !new_info )
  843.                     continue;
  844.                 _ASSERT(&new_info.GetDataSource() == &ds);
  845.                 if ( !info ) {
  846.                     info = new_info;
  847.                     continue;
  848.                 }
  849.                 CSeqMatch_Info* best_info =
  850.                     ds.ResolveConflict(main_idh, info, new_info);
  851.                 if (best_info) {
  852.                     info = *best_info;
  853.                     continue;
  854.                 }
  855.                 x_ThrowConflict(eConflict_History, info, new_info);
  856.             }
  857.         }
  858.     }}
  859.     if ( !info  &&  get_flag == CScope::eGetBioseq_All ) {
  860.         // Try to load the sequence from the data source
  861.         info = ds_info.GetDataSource().BestResolve(main_idh);
  862.     }
  863.     if ( info ) {
  864.         if ( match_info ) {
  865.             x_ThrowConflict(eConflict_Live, match_info, info);
  866.         }
  867.         match_info = info;
  868.         return &ds_info;
  869.     }
  870.     return 0;
  871. }
  872. CDataSource_ScopeInfo*
  873. CScope_Impl::x_FindBioseqInfo(const CPriorityNode& node,
  874.                               const CSeq_id_Handle& idh,
  875.                               const TSeq_id_HandleSet* hset,
  876.                               CSeqMatch_Info& match_info,
  877.                               int get_flag)
  878. {
  879.     if ( node.IsTree() ) {
  880.         // Process sub-tree
  881.         return x_FindBioseqInfo(node.GetTree(), idh, hset, match_info, get_flag);
  882.     }
  883.     else if ( node.IsLeaf() ) {
  884.         return x_FindBioseqInfo(const_cast<CDataSource_ScopeInfo&>(node.GetLeaf()),
  885.                                 idh, hset, match_info, get_flag);
  886.     }
  887.     return 0;
  888. }
  889. void CScope_Impl::x_ResolveSeq_id(TSeq_idMapValue& id_info, int get_flag)
  890. {
  891.     // Use priority, do not scan all DSs - find the first one.
  892.     // Protected by m_Scope_Conf_RWLock in upper-level functions
  893.     CSeqMatch_Info match_info;
  894.     auto_ptr<TSeq_id_HandleSet> hset;
  895.     CSeq_id_Mapper& mapper = CSeq_id_Mapper::GetSeq_id_Mapper();
  896.     if ( mapper.HaveMatchingHandles(id_info.first) ) {
  897.         hset.reset(new TSeq_id_HandleSet);
  898.         mapper.GetMatchingHandles(id_info.first, *hset);
  899.         hset->erase(id_info.first);
  900.         if ( hset->empty() )
  901.             hset.reset();
  902.     }
  903.     CDataSource_ScopeInfo* ds_info =
  904.         x_FindBioseqInfo(m_setDataSrc, id_info.first, hset.get(), match_info,
  905.         get_flag);
  906.     if ( !ds_info ) {
  907.         // Map unresoved ids only if loading was requested
  908.         if (get_flag == CScope::eGetBioseq_All) {
  909.             _ASSERT(m_HeapScope);
  910.             id_info.second.m_Bioseq_Info.Reset(new CBioseq_ScopeInfo(&id_info));
  911.         }
  912.     }
  913.     else {
  914.         {{
  915.             CFastMutexGuard guard(ds_info->GetMutex());
  916.             ds_info->AddTSE(match_info.GetTSE_Info());
  917.         }}
  918.         CConstRef<CBioseq_Info> info = match_info.GetBioseq_Info();
  919.         {{
  920.             TReadLockGuard guard(m_BioseqMapLock);
  921.             TBioseqMap::const_iterator bm_it = m_BioseqMap.find(&*info);
  922.             if ( bm_it != m_BioseqMap.end() ) {
  923.                 id_info.second.m_Bioseq_Info = bm_it->second;
  924.                 return;
  925.             }
  926.         }}
  927.         {{
  928.             TWriteLockGuard guard(m_BioseqMapLock);
  929.             pair<TBioseqMap::iterator, bool> ins = m_BioseqMap
  930.                 .insert(TBioseqMap::value_type(&*info,
  931.                                                CRef<CBioseq_ScopeInfo>()));
  932.             if ( ins.second ) { // new
  933.                 _ASSERT(m_HeapScope);
  934.                 ins.first->second.Reset(new CBioseq_ScopeInfo(&id_info, info));
  935.             }
  936.             id_info.second.m_Bioseq_Info = ins.first->second;
  937.         }}
  938.     }
  939. }
  940. void CScope_Impl::UpdateAnnotIndex(const CSeq_annot& annot)
  941. {
  942.     UpdateAnnotIndex(GetSeq_annotHandle(annot));
  943. }
  944. void CScope_Impl::UpdateAnnotIndex(const CSeq_annot_Handle& annot)
  945. {
  946.     TReadLockGuard rguard(m_Scope_Conf_RWLock);
  947.     const CSeq_annot_Info& info = annot.x_GetInfo();
  948.     info.GetDataSource().UpdateAnnotIndex(info);
  949. }
  950. CConstRef<CScope_Impl::TAnnotRefSet>
  951. CScope_Impl::GetTSESetWithAnnots(const CSeq_id_Handle& idh)
  952. {
  953.     TReadLockGuard rguard(m_Scope_Conf_RWLock);
  954.     TSeq_idMapValue& info = x_GetSeq_id_Info(idh);
  955.     CRef<CBioseq_ScopeInfo> binfo = x_InitBioseq_Info(info,
  956.         CScope::eGetBioseq_All);
  957.     {{
  958.         CInitGuard init(info.second.m_AllAnnotRef_Info, m_MutexPool);
  959.         if ( init ) {
  960.             CRef<TAnnotRefSet> ref_set(new TAnnotRefSet);
  961.             TTSE_LockSet& tse_set = *ref_set;
  962.             if ( binfo->HasBioseq() ) {
  963.                 TTSE_Lock tse(&binfo->GetTSE_Info());
  964.                 tse_set.insert(tse);
  965.             }
  966.             TTSE_LockSet with_ref;
  967.             for (CPriority_I it(m_setDataSrc); it; ++it) {
  968.                 it->GetDataSource().GetTSESetWithAnnots(idh, with_ref);
  969.                 CFastMutexGuard guard(it->GetMutex());
  970.                 const TTSE_LockSet& tse_cache = it->GetTSESet();
  971.                 ITERATE(TTSE_LockSet, ref_it, with_ref) {
  972.                     if ( (*ref_it)->IsDead() &&
  973.                          tse_cache.find(*ref_it) == tse_cache.end() ) {
  974.                         continue;
  975.                     }
  976.                     tse_set.insert(*ref_it);
  977.                 }
  978.                 with_ref.clear();
  979.             }
  980.             info.second.m_AllAnnotRef_Info = ref_set;
  981.         }
  982.     }}
  983.     return info.second.m_AllAnnotRef_Info;
  984. }
  985. CConstRef<CScope_Impl::TAnnotRefSet>
  986. CScope_Impl::GetTSESetWithAnnots(const CBioseq_Handle& bh)
  987. {
  988.     TReadLockGuard rguard(m_Scope_Conf_RWLock);
  989.     TSeq_idMapValue& info = x_GetSeq_id_Info(bh);
  990.     _ASSERT(info.second.m_Bioseq_Info);
  991.     CRef<CBioseq_ScopeInfo> binfo = info.second.m_Bioseq_Info;
  992.     {{
  993.         CInitGuard init(info.second.m_AllAnnotRef_Info, m_MutexPool);
  994.         if ( init ) {
  995.             CRef<TAnnotRefSet> ref_set(new TAnnotRefSet);
  996.             TTSE_LockSet& tse_set = *ref_set;
  997.             if ( binfo->HasBioseq() ) {
  998.                 TTSE_Lock tse(&binfo->GetTSE_Info());
  999.                 
  1000.                 tse_set.insert(tse);
  1001.             }
  1002.             TTSE_LockSet with_ref;
  1003.             for (CPriority_I it(m_setDataSrc); it; ++it) {
  1004.                 it->GetDataSource().GetTSESetWithAnnots(info.first, with_ref);
  1005.                 CFastMutexGuard guard(it->GetMutex());
  1006.                 const TTSE_LockSet& tse_cache = it->GetTSESet();
  1007.                 ITERATE(TTSE_LockSet, ref_it, with_ref) {
  1008.                     if ( (*ref_it)->IsDead() &&
  1009.                          tse_cache.find(*ref_it) == tse_cache.end() ) {
  1010.                         continue;
  1011.                     }
  1012.                     tse_set.insert(*ref_it);
  1013.                 }
  1014.                 with_ref.clear();
  1015.             }
  1016.             info.second.m_AllAnnotRef_Info = ref_set;
  1017.         }
  1018.     }}
  1019.     return info.second.m_AllAnnotRef_Info;
  1020. }
  1021. void CScope_Impl::x_ThrowConflict(EConflict conflict_type,
  1022.                                   const CSeqMatch_Info& info1,
  1023.                                   const CSeqMatch_Info& info2) const
  1024. {
  1025.     const char* msg_type =
  1026.         conflict_type == eConflict_History? "history": "live TSE";
  1027.     CNcbiOstrstream s;
  1028.     s << "CScope_Impl -- multiple " << msg_type << " matches: " <<
  1029.         info1.GetDataSource().GetName() << "::" <<
  1030.         info1.GetIdHandle().AsString() <<
  1031.         " vs " <<
  1032.         info2.GetDataSource().GetName() << "::" <<
  1033.         info2.GetIdHandle().AsString();
  1034.     string msg = CNcbiOstrstreamToString(s);
  1035.     NCBI_THROW(CObjMgrException, eFindConflict, msg);
  1036. }
  1037. void CScope_Impl::ResetHistory(void)
  1038. {
  1039.     TWriteLockGuard guard(m_Scope_Conf_RWLock);
  1040.     x_ResetHistory();
  1041. }
  1042. void CScope_Impl::x_ResetHistory(void)
  1043. {
  1044.     // 1. detach all CBbioseq_Handle objects from scope, and
  1045.     // 2. break circular link:
  1046.     // CBioseq_ScopeInfo-> CSynonymsSet-> SSeq_id_ScopeInfo-> CBioseq_ScopeInfo
  1047.     NON_CONST_ITERATE ( TSeq_idMap, it, m_Seq_idMap ) {
  1048.         if ( it->second.m_Bioseq_Info ) {
  1049.             it->second.m_Bioseq_Info->m_ScopeInfo = 0; // detaching from scope
  1050.             it->second.m_Bioseq_Info->m_SynCache.Reset(); // breaking the link
  1051.         }
  1052.     }
  1053.     m_Seq_idMap.clear();
  1054.     m_BioseqMap.clear();
  1055.     for (CPriority_I it(m_setDataSrc); it; ++it) {
  1056.         it->m_TSE_LockSet.clear();
  1057.     }
  1058. }
  1059. void CScope_Impl::x_PopulateBioseq_HandleSet(const CSeq_entry_Handle& seh,
  1060.                                              TBioseq_HandleSet& handles,
  1061.                                              CSeq_inst::EMol filter,
  1062.                                              TBioseqLevelFlag level)
  1063. {
  1064.     if ( seh ) {
  1065.         TReadLockGuard rguard(m_Scope_Conf_RWLock);
  1066.         const CSeq_entry_Info& info = seh.x_GetInfo();
  1067.         CDataSource::TBioseq_InfoSet info_set;
  1068.         info.GetDataSource().GetBioseqs(info, info_set, filter, level);
  1069.         // Convert each bioseq info into bioseq handle
  1070.         ITERATE (CDataSource::TBioseq_InfoSet, iit, info_set) {
  1071.             CBioseq_Handle bh = x_GetBioseqHandle(**iit);
  1072.             if ( bh ) {
  1073.                 handles.push_back(bh);
  1074.             }
  1075.         }
  1076.     }
  1077. }
  1078. CConstRef<CSynonymsSet> CScope_Impl::GetSynonyms(const CSeq_id& id)
  1079. {
  1080.     return GetSynonyms(CSeq_id_Handle::GetHandle(id));
  1081. }
  1082. CConstRef<CSynonymsSet> CScope_Impl::GetSynonyms(const CSeq_id_Handle& id)
  1083. {
  1084.     _ASSERT(id);
  1085.     TReadLockGuard rguard(m_Scope_Conf_RWLock);
  1086.     return x_GetSynonyms(*x_GetBioseq_Info(id, CScope::eGetBioseq_All));
  1087. }
  1088. CConstRef<CSynonymsSet> CScope_Impl::GetSynonyms(const CBioseq_Handle& bh)
  1089. {
  1090.     if ( !bh ) {
  1091.         return CConstRef<CSynonymsSet>();
  1092.     }
  1093.     TReadLockGuard rguard(m_Scope_Conf_RWLock);
  1094.     return x_GetSynonyms(const_cast<CBioseq_ScopeInfo&>(bh.x_GetScopeInfo()));
  1095. }
  1096. void CScope_Impl::x_AddSynonym(const CSeq_id_Handle& idh,
  1097.                                CSynonymsSet& syn_set,
  1098.                                CBioseq_ScopeInfo& info)
  1099. {
  1100.     // Check current ID for conflicts, add to the set.
  1101.     TSeq_idMapValue& seq_id_info = x_GetSeq_id_Info(idh);
  1102.     if ( x_InitBioseq_Info(seq_id_info, info) ) {
  1103.         // the same bioseq - add synonym
  1104.         if ( !syn_set.ContainsSynonym(seq_id_info.first) ) {
  1105.             syn_set.AddSynonym(&seq_id_info);
  1106.         }
  1107.     }
  1108.     else {
  1109.         CRef<CBioseq_ScopeInfo> info2 = seq_id_info.second.m_Bioseq_Info;
  1110.         _ASSERT(info2 != &info);
  1111.         LOG_POST(Warning << "CScope::GetSynonyms: Bioseq["<<
  1112.                  info.GetBioseq_Info().IdString()<<"]: id "<<
  1113.                  idh.AsString()<<" is resolved to another Bioseq["<<
  1114.                  info2->GetBioseq_Info().IdString()<<"]");
  1115.     }
  1116. }
  1117. CConstRef<CSynonymsSet>
  1118. CScope_Impl::x_GetSynonyms(CBioseq_ScopeInfo& info)
  1119. {
  1120.     {{
  1121.         CInitGuard init(info.m_SynCache, m_MutexPool);
  1122.         if ( init ) {
  1123.             // It's OK to use CRef, at least one copy should be kept
  1124.             // alive by the id cache (for the ID requested).
  1125.             CRef<CSynonymsSet> syn_set(new CSynonymsSet);
  1126.             //syn_set->AddSynonym(id);
  1127.             if ( info.HasBioseq() ) {
  1128.                 ITERATE(CBioseq_Info::TId, it, info.GetBioseq_Info().GetId()) {
  1129.                     CSeq_id_Mapper& mapper=CSeq_id_Mapper::GetSeq_id_Mapper();
  1130.                     if ( mapper.HaveReverseMatch(*it) ) {
  1131.                         TSeq_id_HandleSet hset;
  1132.                         mapper.GetReverseMatchingHandles(*it, hset);
  1133.                         ITERATE(TSeq_id_HandleSet, mit, hset) {
  1134.                             x_AddSynonym(*mit, *syn_set, info);
  1135.                         }
  1136.                     }
  1137.                     else {
  1138.                         x_AddSynonym(*it, *syn_set, info);
  1139.                     }
  1140.                 }
  1141.             }
  1142.             info.m_SynCache = syn_set;
  1143.         }
  1144.     }}
  1145.     return info.m_SynCache;
  1146. }
  1147. void CScope_Impl::GetAllTSEs(TTSE_Handles& tses, int kind)
  1148. {
  1149.     TReadLockGuard rguard(m_Scope_Conf_RWLock);
  1150.     for (CPriority_I it(m_setDataSrc); it; ++it) {
  1151.         if (it->GetDataLoader() &&  kind == CScope::eManualTSEs) {
  1152.             // Skip data sources with loaders
  1153.             continue;
  1154.         }
  1155.         CFastMutexGuard guard(it->GetMutex());
  1156.         const TTSE_LockSet& tse_cache = it->GetTSESet();
  1157.         ITERATE(TTSE_LockSet, tse_it, tse_cache) {
  1158.             tses.push_back(CSeq_entry_Handle(*m_HeapScope, **tse_it));
  1159.         }
  1160.     }
  1161. }
  1162. CDataSource* CScope_Impl::GetFirstLoaderSource(void)
  1163. {
  1164.     TReadLockGuard rguard(m_Scope_Conf_RWLock);
  1165.     for (CPriority_I it(m_setDataSrc); it; ++it) {
  1166.         if ( it->GetDataLoader() ) {
  1167.             return &it->GetDataSource();
  1168.         }
  1169.     }
  1170.     return 0;
  1171. }
  1172. void CScope_Impl::DebugDump(CDebugDumpContext ddc, unsigned int depth) const
  1173. {
  1174.     ddc.SetFrame("CScope_Impl");
  1175.     CObject::DebugDump( ddc, depth);
  1176.     ddc.Log("m_pObjMgr", m_pObjMgr,0);
  1177.     if (depth == 0) {
  1178.     } else {
  1179.         DebugDumpValue(ddc,"m_setDataSrc.type", "set<CDataSource*>");
  1180.     }
  1181. }
  1182. END_SCOPE(objects)
  1183. END_NCBI_SCOPE
  1184. /*
  1185. * ---------------------------------------------------------------------------
  1186. * $Log: scope_impl.cpp,v $
  1187. * Revision 1000.3  2004/06/01 19:23:39  gouriano
  1188. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.15
  1189. *
  1190. * Revision 1.15  2004/05/21 21:42:12  gorelenk
  1191. * Added PCH ncbi_pch.hpp
  1192. *
  1193. * Revision 1.14  2004/04/16 13:31:47  grichenk
  1194. * Added data pre-fetching functions.
  1195. *
  1196. * Revision 1.13  2004/04/14 19:12:12  vasilche
  1197. * Added storing TSE in history when returning CSeq_entry or CSeq_annot handles.
  1198. * Added test for main id before matching handles in GetBioseqHandleFromTSE().
  1199. *
  1200. * Revision 1.12  2004/04/13 15:59:35  grichenk
  1201. * Added CScope::GetBioseqHandle() with id resolving flag.
  1202. *
  1203. * Revision 1.11  2004/04/12 19:35:59  grichenk
  1204. * Added locks in GetAllTSEs()
  1205. *
  1206. * Revision 1.10  2004/04/12 18:40:24  grichenk
  1207. * Added GetAllTSEs()
  1208. *
  1209. * Revision 1.9  2004/03/31 19:54:08  vasilche
  1210. * Fixed removal of bioseqs and bioseq-sets.
  1211. *
  1212. * Revision 1.8  2004/03/31 19:23:13  vasilche
  1213. * Fixed scope in CBioseq_Handle::GetEditHandle().
  1214. *
  1215. * Revision 1.7  2004/03/31 17:08:07  vasilche
  1216. * Implemented ConvertSeqToSet and ConvertSetToSeq.
  1217. *
  1218. * Revision 1.6  2004/03/29 20:51:19  vasilche
  1219. * Fixed ambiguity on MSVC.
  1220. *
  1221. * Revision 1.5  2004/03/29 20:13:06  vasilche
  1222. * Implemented whole set of methods to modify Seq-entry object tree.
  1223. * Added CBioseq_Handle::GetExactComplexityLevel().
  1224. *
  1225. * Revision 1.4  2004/03/25 19:27:44  vasilche
  1226. * Implemented MoveTo and CopyTo methods of handles.
  1227. *
  1228. * Revision 1.3  2004/03/24 18:30:30  vasilche
  1229. * Fixed edit API.
  1230. * Every *_Info object has its own shallow copy of original object.
  1231. *
  1232. * Revision 1.2  2004/03/16 18:09:10  vasilche
  1233. * Use GetPointer() to avoid ambiguity
  1234. *
  1235. * Revision 1.1  2004/03/16 15:47:28  vasilche
  1236. * Added CBioseq_set_Handle and set of EditHandles
  1237. *
  1238. * Revision 1.101  2004/02/19 17:23:01  vasilche
  1239. * Changed order of deletion of heap scope and scope impl objects.
  1240. * Reduce number of calls to x_ResetHistory().
  1241. *
  1242. * Revision 1.100  2004/02/10 21:15:16  grichenk
  1243. * Added reverse ID matching.
  1244. *
  1245. * Revision 1.99  2004/02/09 14:42:46  vasilche
  1246. * Temporary fix in GetSynonyms() to get accession without version.
  1247. *
  1248. * Revision 1.98  2004/02/02 14:46:43  vasilche
  1249. * Several performance fixed - do not iterate whole tse set in CDataSource.
  1250. *
  1251. * Revision 1.97  2004/01/29 20:33:28  vasilche
  1252. * Do not resolve any Seq-ids in CScope::GetSynonyms() -
  1253. * assume all not resolved Seq-id as synonym.
  1254. * Seq-id conflict messages made clearer.
  1255. *
  1256. * Revision 1.96  2004/01/28 20:50:49  vasilche
  1257. * Fixed NULL pointer exception in GetSynonyms() when matching Seq-id w/o version.
  1258. *
  1259. * Revision 1.95  2004/01/07 20:42:01  grichenk
  1260. * Fixed matching of accession to accession.version
  1261. *
  1262. * Revision 1.94  2003/12/18 16:38:07  grichenk
  1263. * Added CScope::RemoveEntry()
  1264. *
  1265. * Revision 1.93  2003/12/12 16:59:51  grichenk
  1266. * Fixed conflicts resolving (ask data source).
  1267. *
  1268. * Revision 1.92  2003/12/03 20:55:12  grichenk
  1269. * Check value returned by x_GetBioseq_Info()
  1270. *
  1271. * Revision 1.91  2003/11/21 20:33:03  grichenk
  1272. * Added GetBioseqHandleFromTSE(CSeq_id, CSeq_entry)
  1273. *
  1274. * Revision 1.90  2003/11/19 22:18:03  grichenk
  1275. * All exceptions are now CException-derived. Catch "exception" rather
  1276. * than "runtime_error".
  1277. *
  1278. * Revision 1.89  2003/11/12 15:49:39  vasilche
  1279. * Added loading annotations on non gi Seq-id.
  1280. *
  1281. * Revision 1.88  2003/10/23 13:47:27  vasilche
  1282. * Check CSeq_id_Handle for null in CScope::GetBioseqHandle().
  1283. *
  1284. * Revision 1.87  2003/10/22 14:08:15  vasilche
  1285. * Detach all CBbioseq_Handle objects from scope in CScope::ResetHistory().
  1286. *
  1287. * Revision 1.86  2003/10/22 13:54:36  vasilche
  1288. * All CScope::GetBioseqHandle() methods return 'null' CBioseq_Handle object
  1289. * instead of throwing an exception.
  1290. *
  1291. * Revision 1.85  2003/10/20 18:23:54  vasilche
  1292. * Make CScope::GetSynonyms() to skip conflicting ids.
  1293. *
  1294. * Revision 1.84  2003/10/09 13:58:21  vasilche
  1295. * Fixed conflict when the same datasource appears twice with equal priorities.
  1296. *
  1297. * Revision 1.83  2003/10/07 13:43:23  vasilche
  1298. * Added proper handling of named Seq-annots.
  1299. * Added feature search from named Seq-annots.
  1300. * Added configurable adaptive annotation search (default: gene, cds, mrna).
  1301. * Fixed selection of blobs for loading from GenBank.
  1302. * Added debug checks to CSeq_id_Mapper for easier finding lost CSeq_id_Handles.
  1303. * Fixed leaked split chunks annotation stubs.
  1304. * Moved some classes definitions in separate *.cpp files.
  1305. *
  1306. * Revision 1.82  2003/09/30 16:22:03  vasilche
  1307. * Updated internal object manager classes to be able to load ID2 data.
  1308. * SNP blobs are loaded as ID2 split blobs - readers convert them automatically.
  1309. * Scope caches results of requests for data to data loaders.
  1310. * Optimized CSeq_id_Handle for gis.
  1311. * Optimized bioseq lookup in scope.
  1312. * Reduced object allocations in annotation iterators.
  1313. * CScope is allowed to be destroyed before other objects using this scope are
  1314. * deleted (feature iterators, bioseq handles etc).
  1315. * Optimized lookup for matching Seq-ids in CSeq_id_Mapper.
  1316. * Added 'adaptive' option to objmgr_demo application.
  1317. *
  1318. * Revision 1.81  2003/09/05 20:50:26  grichenk
  1319. * +AddBioseq(CBioseq&)
  1320. *
  1321. * Revision 1.80  2003/09/05 17:29:40  grichenk
  1322. * Structurized Object Manager exceptions
  1323. *
  1324. * Revision 1.79  2003/09/03 20:00:02  grichenk
  1325. * Added sequence filtering by level (mains/parts/all)
  1326. *
  1327. * Revision 1.78  2003/08/04 17:03:01  grichenk
  1328. * Added constructors to iterate all annotations from a
  1329. * seq-entry or seq-annot.
  1330. *
  1331. * Revision 1.77  2003/07/25 15:25:25  grichenk
  1332. * Added CSeq_annot_CI class
  1333. *
  1334. * Revision 1.76  2003/07/17 20:07:56  vasilche
  1335. * Reduced memory usage by feature indexes.
  1336. * SNP data is loaded separately through PUBSEQ_OS.
  1337. * String compression for SNP data.
  1338. *
  1339. * Revision 1.75  2003/07/14 21:13:59  grichenk
  1340. * Added seq-loc dump in GetBioseqHandle(CSeqLoc)
  1341. *
  1342. * Revision 1.74  2003/06/30 18:42:10  vasilche
  1343. * CPriority_I made to use less memory allocations/deallocations.
  1344. *
  1345. * Revision 1.73  2003/06/24 14:25:18  vasilche
  1346. * Removed obsolete CTSE_Guard class.
  1347. * Used separate mutexes for bioseq and annot maps.
  1348. *
  1349. * Revision 1.72  2003/06/19 18:23:46  vasilche
  1350. * Added several CXxx_ScopeInfo classes for CScope related information.
  1351. * CBioseq_Handle now uses reference to CBioseq_ScopeInfo.
  1352. * Some fine tuning of locking in CScope.
  1353. *
  1354. * Revision 1.69  2003/05/27 19:44:06  grichenk
  1355. * Added CSeqVector_CI class
  1356. *
  1357. * Revision 1.68  2003/05/20 15:44:37  vasilche
  1358. * Fixed interaction of CDataSource and CDataLoader in multithreaded app.
  1359. * Fixed some warnings on WorkShop.
  1360. * Added workaround for memory leak on WorkShop.
  1361. *
  1362. * Revision 1.67  2003/05/14 18:39:28  grichenk
  1363. * Simplified TSE caching and filtering in CScope, removed
  1364. * some obsolete members and functions.
  1365. *
  1366. * Revision 1.66  2003/05/13 18:33:01  vasilche
  1367. * Fixed CScope::GetTSESetWithAnnots() conflict resolution.
  1368. *
  1369. * Revision 1.65  2003/05/12 19:18:29  vasilche
  1370. * Fixed locking of object manager classes in multi-threaded application.
  1371. *
  1372. * Revision 1.64  2003/05/09 20:28:03  grichenk
  1373. * Changed warnings to info
  1374. *
  1375. * Revision 1.63  2003/05/06 18:54:09  grichenk
  1376. * Moved TSE filtering from CDataSource to CScope, changed
  1377. * some filtering rules (e.g. priority is now more important
  1378. * than scope history). Added more caches to CScope.
  1379. *
  1380. * Revision 1.62  2003/04/29 19:51:13  vasilche
  1381. * Fixed interaction of Data Loader garbage collector and TSE locking mechanism.
  1382. * Made some typedefs more consistent.
  1383. *
  1384. * Revision 1.61  2003/04/24 16:12:38  vasilche
  1385. * Object manager internal structures are splitted more straightforward.
  1386. * Removed excessive header dependencies.
  1387. *
  1388. * Revision 1.60  2003/04/15 14:21:52  vasilche
  1389. * Removed unnecessary assignment.
  1390. *
  1391. * Revision 1.59  2003/04/14 21:32:18  grichenk
  1392. * Avoid passing CScope as an argument to CDataSource methods
  1393. *
  1394. * Revision 1.58  2003/04/09 16:04:32  grichenk
  1395. * SDataSourceRec replaced with CPriorityNode
  1396. * Added CScope::AddScope(scope, priority) to allow scope nesting
  1397. *
  1398. * Revision 1.57  2003/04/03 14:18:09  vasilche
  1399. * Added public GetSynonyms() method.
  1400. *
  1401. * Revision 1.56  2003/03/26 21:00:19  grichenk
  1402. * Added seq-id -> tse with annotation cache to CScope
  1403. *
  1404. * Revision 1.55  2003/03/24 21:26:45  grichenk
  1405. * Added support for CTSE_CI
  1406. *
  1407. * Revision 1.54  2003/03/21 19:22:51  grichenk
  1408. * Redesigned TSE locking, replaced CTSE_Lock with CRef<CTSE_Info>.
  1409. *
  1410. * Revision 1.53  2003/03/19 21:55:50  grichenk
  1411. * Avoid re-mapping TSEs in x_AddToHistory() if already indexed
  1412. *
  1413. * Revision 1.52  2003/03/18 14:52:59  grichenk
  1414. * Removed obsolete methods, replaced seq-id with seq-id handle
  1415. * where possible. Added argument to limit annotations update to
  1416. * a single seq-entry.
  1417. *
  1418. * Revision 1.51  2003/03/12 20:09:34  grichenk
  1419. * Redistributed members between CBioseq_Handle, CBioseq_Info and CTSE_Info
  1420. *
  1421. * Revision 1.50  2003/03/11 15:51:06  kuznets
  1422. * iterate -> ITERATE
  1423. *
  1424. * Revision 1.49  2003/03/11 14:15:52  grichenk
  1425. * +Data-source priority
  1426. *
  1427. * Revision 1.48  2003/03/10 16:55:17  vasilche
  1428. * Cleaned SAnnotSelector structure.
  1429. * Added shortcut when features are limited to one TSE.
  1430. *
  1431. * Revision 1.47  2003/03/05 20:55:29  vasilche
  1432. * Added cache cleaning in CScope::ResetHistory().
  1433. *
  1434. * Revision 1.46  2003/03/03 20:32:47  vasilche
  1435. * Removed obsolete method GetSynonyms().
  1436. *
  1437. * Revision 1.45  2003/02/28 21:54:18  grichenk
  1438. * +CSynonymsSet::empty(), removed _ASSERT() in CScope::GetSynonyms()
  1439. *
  1440. * Revision 1.44  2003/02/28 20:02:37  grichenk
  1441. * Added synonyms cache and x_GetSynonyms()
  1442. *
  1443. * Revision 1.43  2003/02/27 14:35:31  vasilche
  1444. * Splitted PopulateTSESet() by logically independent parts.
  1445. *
  1446. * Revision 1.42  2003/02/24 18:57:22  vasilche
  1447. * Make feature gathering in one linear pass using CSeqMap iterator.
  1448. * Do not use feture index by sub locations.
  1449. * Sort features at the end of gathering in one vector.
  1450. * Extracted some internal structures and classes in separate header.
  1451. * Delay creation of mapped features.
  1452. *
  1453. * Revision 1.41  2003/02/05 17:59:17  dicuccio
  1454. * Moved formerly private headers into include/objects/objmgr/impl
  1455. *
  1456. * Revision 1.40  2003/01/29 22:03:46  grichenk
  1457. * Use single static CSeq_id_Mapper instead of per-OM model.
  1458. *
  1459. * Revision 1.39  2003/01/22 20:11:54  vasilche
  1460. * Merged functionality of CSeqMapResolved_CI to CSeqMap_CI.
  1461. * CSeqMap_CI now supports resolution and iteration over sequence range.
  1462. * Added several caches to CScope.
  1463. * Optimized CSeqVector().
  1464. * Added serveral variants of CBioseqHandle::GetSeqVector().
  1465. * Tried to optimize annotations iterator (not much success).
  1466. * Rewritten CHandleRange and CHandleRangeMap classes to avoid sorting of list.
  1467. *
  1468. * Revision 1.38  2002/12/26 20:55:18  dicuccio
  1469. * Moved seq_id_mapper.hpp, tse_info.hpp, and bioseq_info.hpp -> include/ tree
  1470. *
  1471. * Revision 1.37  2002/12/26 16:39:24  vasilche
  1472. * Object manager class CSeqMap rewritten.
  1473. *
  1474. * Revision 1.36  2002/11/08 22:15:51  grichenk
  1475. * Added methods for removing/replacing annotations
  1476. *
  1477. * Revision 1.35  2002/11/08 19:43:35  grichenk
  1478. * CConstRef<> constructor made explicit
  1479. *
  1480. * Revision 1.34  2002/11/04 21:29:12  grichenk
  1481. * Fixed usage of const CRef<> and CRef<> constructor
  1482. *
  1483. * Revision 1.33  2002/11/01 05:34:32  kans
  1484. * added GetBioseqHandle taking CBioseq parameter
  1485. *
  1486. * Revision 1.32  2002/10/31 22:25:42  kans
  1487. * added GetBioseqHandle taking CSeq_loc parameter
  1488. *
  1489. * Revision 1.31  2002/10/18 19:12:40  grichenk
  1490. * Removed mutex pools, converted most static mutexes to non-static.
  1491. * Protected CSeqMap::x_Resolve() with mutex. Modified code to prevent
  1492. * dead-locks.
  1493. *
  1494. * Revision 1.30  2002/10/16 20:44:29  ucko
  1495. * *** empty log message ***
  1496. *
  1497. * Revision 1.29  2002/10/02 17:58:23  grichenk
  1498. * Added sequence type filter to CBioseq_CI
  1499. *
  1500. * Revision 1.28  2002/09/30 20:01:19  grichenk
  1501. * Added methods to support CBioseq_CI
  1502. *
  1503. * Revision 1.27  2002/08/09 14:59:00  ucko
  1504. * Restrict template <> to MIPSpro for now, as it also leads to link
  1505. * errors with Compaq's compiler.  (Sigh.)
  1506. *
  1507. * Revision 1.26  2002/08/08 19:51:24  ucko
  1508. * Omit EMPTY_TEMPLATE for GCC and KCC, as it evidently leads to link errors(!)
  1509. *
  1510. * Revision 1.25  2002/08/08 14:28:00  ucko
  1511. * Add EMPTY_TEMPLATE to explicit instantiations.
  1512. *
  1513. * Revision 1.24  2002/08/07 18:21:57  ucko
  1514. * Explicitly instantiate CMutexPool_Base<CScope>::sm_Pool
  1515. *
  1516. * Revision 1.23  2002/07/08 20:51:02  grichenk
  1517. * Moved log to the end of file
  1518. * Replaced static mutex (in CScope, CDataSource) with the mutex
  1519. * pool. Redesigned CDataSource data locking.
  1520. *
  1521. * Revision 1.22  2002/06/04 17:18:33  kimelman
  1522. * memory cleanup :  new/delete/Cref rearrangements
  1523. *
  1524. * Revision 1.21  2002/05/28 18:00:43  gouriano
  1525. * DebugDump added
  1526. *
  1527. * Revision 1.20  2002/05/14 20:06:26  grichenk
  1528. * Improved CTSE_Info locking by CDataSource and CDataLoader
  1529. *
  1530. * Revision 1.19  2002/05/06 03:28:47  vakatov
  1531. * OM/OM1 renaming
  1532. *
  1533. * Revision 1.18  2002/04/22 20:04:39  grichenk
  1534. * Fixed TSE dropping, removed commented code
  1535. *
  1536. * Revision 1.17  2002/04/17 21:09:40  grichenk
  1537. * Fixed annotations loading
  1538. *
  1539. * Revision 1.16  2002/03/28 14:02:31  grichenk
  1540. * Added scope history checks to CDataSource::x_FindBestTSE()
  1541. *
  1542. * Revision 1.15  2002/03/27 18:45:44  gouriano
  1543. * three functions made public
  1544. *
  1545. * Revision 1.14  2002/03/20 21:20:39  grichenk
  1546. * +CScope::ResetHistory()
  1547. *
  1548. * Revision 1.13  2002/02/28 20:53:32  grichenk
  1549. * Implemented attaching segmented sequence data. Fixed minor bugs.
  1550. *
  1551. * Revision 1.12  2002/02/25 21:05:29  grichenk
  1552. * Removed seq-data references caching. Increased MT-safety. Fixed typos.
  1553. *
  1554. * Revision 1.11  2002/02/21 19:27:06  grichenk
  1555. * Rearranged includes. Added scope history. Added searching for the
  1556. * best seq-id match in data sources and scopes. Updated tests.
  1557. *
  1558. * Revision 1.10  2002/02/07 21:27:35  grichenk
  1559. * Redesigned CDataSource indexing: seq-id handle -> TSE -> seq/annot
  1560. *
  1561. * Revision 1.9  2002/02/06 21:46:11  gouriano
  1562. * *** empty log message ***
  1563. *
  1564. * Revision 1.8  2002/02/05 21:46:28  gouriano
  1565. * added FindSeqid function, minor tuneup in CSeq_id_mapper
  1566. *
  1567. * Revision 1.7  2002/01/29 17:45:34  grichenk
  1568. * Removed debug output
  1569. *
  1570. * Revision 1.6  2002/01/28 19:44:49  gouriano
  1571. * changed the interface of BioseqHandle: two functions moved from Scope
  1572. *
  1573. * Revision 1.5  2002/01/23 21:59:31  grichenk
  1574. * Redesigned seq-id handles and mapper
  1575. *
  1576. * Revision 1.4  2002/01/18 17:06:29  gouriano
  1577. * renamed CScope::GetSequence to CScope::GetSeqVector
  1578. *
  1579. * Revision 1.3  2002/01/18 15:54:14  gouriano
  1580. * changed DropTopLevelSeqEntry()
  1581. *
  1582. * Revision 1.2  2002/01/16 16:25:57  gouriano
  1583. * restructured objmgr
  1584. *
  1585. * Revision 1.1  2002/01/11 19:06:22  gouriano
  1586. * restructured objmgr
  1587. *
  1588. *
  1589. * ===========================================================================
  1590. */