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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: gbloader.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:41:37  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.106
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: gbloader.cpp,v 1000.1 2004/06/01 19:41:37 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. *  Author: Michael Kimelman, Eugene Vasilchenko
  35. *
  36. *  File Description: GenBank Data loader
  37. *
  38. */
  39. #include <ncbi_pch.hpp>
  40. #include <objtools/data_loaders/genbank/gbloader.hpp>
  41. #include <objtools/data_loaders/genbank/reader.hpp>
  42. // TODO: remove the following two includes
  43. # include <objtools/data_loaders/genbank/readers/id1/reader_id1.hpp>
  44. #if defined(HAVE_PUBSEQ_OS)
  45. # include <objtools/data_loaders/genbank/readers/pubseqos/reader_pubseq.hpp>
  46. #endif
  47. #include <objmgr/objmgr_exception.hpp>
  48. #include <objmgr/annot_selector.hpp>
  49. #include <objmgr/impl/tse_info.hpp>
  50. #include <objmgr/impl/tse_chunk_info.hpp>
  51. #include <objmgr/impl/handle_range_map.hpp>
  52. #include <objmgr/impl/data_source.hpp>
  53. #include <objmgr/impl/annot_object.hpp>
  54. #include <objects/seqloc/Seq_loc.hpp>
  55. #include <objects/seqloc/Seq_id.hpp>
  56. #include <objects/seqset/Seq_entry.hpp>
  57. #include <objects/seq/Seq_annot.hpp>
  58. #include <dbapi/driver/exception.hpp>
  59. #include <dbapi/driver/interfaces.hpp>
  60. BEGIN_NCBI_SCOPE
  61. BEGIN_SCOPE(objects)
  62. static int x_Request2SeqrefMask(CGBDataLoader::EChoice choice);
  63. //=======================================================================
  64. //   GBLoader sub classes 
  65. //
  66. //=======================================================================
  67. // GBLoader Public interface 
  68. // 
  69. static const char* const DRV_ENV_VAR = "GENBANK_LOADER_METHOD";
  70. static const char* const DEFAULT_DRV_ORDER = "PUBSEQOS:ID1";
  71. static const char* const DRV_PUBSEQOS = "PUBSEQOS";
  72. static const char* const DRV_ID1 = "ID1";
  73. SSeqrefs::SSeqrefs(const CSeq_id_Handle& h)
  74.     : m_Handle(h)
  75. {
  76. }
  77. SSeqrefs::~SSeqrefs(void)
  78. {
  79. }
  80. CGBDataLoader::STSEinfo::STSEinfo()
  81.     : next(0), prev(0), locked(0), tseinfop(0), m_LoadState(eLoadStateNone)
  82. {
  83. }
  84. CGBDataLoader::STSEinfo::~STSEinfo()
  85. {
  86. }
  87. #define TSE(stse) CSeqref::printTSE((stse).key)
  88. #define DUMP(stse) CSeqref::printTSE((stse).key) << 
  89.     " stse=" << &(stse) << 
  90.     " tsei=" << (stse).tseinfop << 
  91.     " tse=" << ((stse).tseinfop? (stse).tseinfop->GetSeq_entryCore().GetPointer(): 0)
  92. // Create driver specified in "env"
  93. /*
  94. CReader* s_CreateReader(string env)
  95. {
  96. #if defined(HAVE_PUBSEQ_OS)
  97.     if (env == DRV_PUBSEQOS) {
  98.         try {
  99.             return new CPubseqReader;
  100.         }
  101.         catch ( exception& e ) {
  102.             GBLOG_POST("CPubseqReader is not available ::" << e.what());
  103.             return 0;
  104.         }
  105.         catch ( ... ) {
  106.             LOG_POST("CPubseqReader:: unable to init ");
  107.             return 0;
  108.         }
  109.     }
  110. #endif
  111.     if (env == DRV_ID1) {
  112.         return new CId1Reader;
  113.     }
  114.     return 0;
  115. }
  116. */
  117. CGBDataLoader::CGBDataLoader(const string& loader_name, CReader *driver,
  118.                              int gc_threshold)
  119.   : CDataLoader(loader_name),
  120.     m_Driver(driver),
  121.     m_ReaderPluginManager(0),
  122.     m_UseListHead(0),
  123.     m_UseListTail(0)
  124. {
  125.     GBLOG_POST( "CGBDataLoader");
  126.     if ( !m_Driver ) {
  127.         x_CreateDriver();
  128. // Commented out by kuznets Dec 03, 2003
  129. /*
  130.         const char* env = ::getenv(DRV_ENV_VAR);
  131.         if (!env) {
  132.             env = DEFAULT_DRV_ORDER; // default drivers' order
  133.         }
  134.         list<string> drivers;
  135.         NStr::Split(env, ":", drivers);
  136.         ITERATE ( list<string>, drv, drivers ) {
  137.             m_Driver = s_CreateReader(*drv);
  138.             if ( m_Driver )
  139.                 break;
  140.         }
  141.         if(!m_Driver) {
  142.             NCBI_THROW(CLoaderException, eNoConnection,
  143.                        "Could not create driver: " + string(env));
  144.         }
  145. */
  146.     }
  147.   
  148.     size_t i = m_Driver->GetParallelLevel();
  149.     m_Locks.m_Pool.SetSize(i<=0?10:i);
  150.     m_Locks.m_SlowTraverseMode=0;
  151.   
  152.     m_TseCount=0;
  153.     m_TseGC_Threshhold=gc_threshold;
  154.     m_InvokeGC=false;
  155.     //GBLOG_POST( "CGBDataLoader("<<loader_name<<"::" <<gc_threshold << ")" );
  156. }
  157. CGBDataLoader::CGBDataLoader(const string& loader_name,
  158.                              TReader_PluginManager *plugin_manager,
  159.                              EOwnership  take_plugin_manager,
  160.                              int gc_threshold)
  161.   : CDataLoader(loader_name),
  162.     m_Driver(0),
  163.     m_ReaderPluginManager(plugin_manager),
  164.     m_OwnReaderPluginManager(take_plugin_manager),
  165.     m_UseListHead(0),
  166.     m_UseListTail(0)
  167. {
  168.     GBLOG_POST( "CGBDataLoader");
  169.     if (!m_ReaderPluginManager) {
  170.         x_CreateReaderPluginManager();
  171.     }
  172.     x_CreateDriver();
  173.     size_t i = m_Driver->GetParallelLevel();
  174.     m_Locks.m_Pool.SetSize(i<=0?10:i);
  175.     m_Locks.m_SlowTraverseMode=0;
  176.   
  177.     m_TseCount=0;
  178.     m_TseGC_Threshhold=gc_threshold;
  179.     m_InvokeGC=false;
  180. }
  181. void CGBDataLoader::x_CreateReaderPluginManager(void)
  182. {
  183.     if (m_OwnReaderPluginManager == eTakeOwnership) {
  184.         delete m_ReaderPluginManager;
  185.         m_ReaderPluginManager = 0;
  186.     }
  187.     m_ReaderPluginManager = new TReader_PluginManager;
  188.     m_OwnReaderPluginManager = eTakeOwnership;
  189.     TReader_PluginManager::FNCBI_EntryPoint ep1 = NCBI_EntryPoint_Id1Reader;
  190.     m_ReaderPluginManager->RegisterWithEntryPoint(ep1);
  191. #if defined(HAVE_PUBSEQ_OS)
  192.     TReader_PluginManager::FNCBI_EntryPoint ep2 = NCBI_EntryPoint_Reader_Pubseqos;
  193.     m_ReaderPluginManager->RegisterWithEntryPoint(ep2);
  194. #endif
  195. }
  196. void CGBDataLoader::x_CreateDriver(void)
  197. {
  198.     if (!m_ReaderPluginManager) {
  199.         x_CreateReaderPluginManager();
  200.         _ASSERT(m_ReaderPluginManager);
  201.     }
  202.     const char* env = ::getenv(DRV_ENV_VAR);
  203.     if (!env) {
  204.         env = DEFAULT_DRV_ORDER; // default drivers' order
  205.     }
  206.     list<string> drivers;
  207.     NStr::Split(env, ":", drivers);
  208.     ITERATE ( list<string>, drv, drivers ) {
  209.         m_Driver = x_CreateReader(*drv);
  210.         if ( m_Driver )
  211.             break;
  212.     }
  213.     if (!m_Driver) {
  214.         NCBI_THROW(CLoaderException, eNoConnection,
  215.                    "Could not create driver: " + string(env));
  216.     }
  217. }
  218. CReader* CGBDataLoader::x_CreateReader(const string& env)
  219. {
  220.     _ASSERT(m_ReaderPluginManager);
  221. #if defined(HAVE_PUBSEQ_OS)
  222.     if (env == DRV_PUBSEQOS) {
  223.         try {
  224.             return m_ReaderPluginManager->CreateInstance("pubseq_reader");
  225.         }
  226.         catch ( exception& e ) {
  227.             GBLOG_POST("CPubseqReader is not available ::" << e.what());
  228.             return 0;
  229.         }
  230.         catch ( ... ) {
  231.             LOG_POST("CPubseqReader:: unable to init ");
  232.             return 0;
  233.         }
  234.     }
  235. #endif
  236.     if (env == DRV_ID1) {
  237.         try {
  238.             return m_ReaderPluginManager->CreateInstance("id1_reader");
  239.         }
  240.         catch ( exception& e ) {
  241.             LOG_POST("CId1Reader is not available ::" << e.what());
  242.             return 0;
  243.         }
  244.         catch ( ... ) {
  245.             LOG_POST("CId1Reader:: unable to init ");
  246.             return 0;
  247.         }
  248.     }
  249.     return 0;
  250. }
  251. CGBDataLoader::~CGBDataLoader(void)
  252. {
  253.     GBLOG_POST( "~CGBDataLoader");
  254.     CGBLGuard g(m_Locks,"~CGBDataLoader");
  255.     while ( m_UseListHead ) {
  256.         if ( m_UseListHead->tseinfop ) {
  257.             ERR_POST("CGBDataLoader::~CGBDataLoader: TSE not dropped: "<<
  258.                      TSE(*m_UseListHead));
  259.         }
  260.         x_DropTSEinfo(m_UseListHead);
  261.     }
  262.     m_Bs2Sr.clear();
  263.     if (m_OwnReaderPluginManager == eTakeOwnership) {
  264.         delete m_ReaderPluginManager;
  265.     }
  266. }
  267. static const char* const s_ChoiceName[] = {
  268.     "eBlob",
  269.     "eBioseq",
  270.     "eCore",
  271.     "eBioseqCore",
  272.     "eSequence",
  273.     "eFeatures",
  274.     "eGraph",
  275.     "eAlign",
  276.     "eAll",
  277.     "eAnnot",
  278.     "???"
  279. };
  280. static
  281. const size_t kChoiceNameCount = sizeof(s_ChoiceName)/sizeof(s_ChoiceName[0]);
  282. void CGBDataLoader::GetRecords(const CSeq_id_Handle& idh,
  283.                                const EChoice choice)
  284. {
  285.     if ( choice == eAnnot && !idh.IsGi() ) {
  286.         // no external annots available on non-gi ids
  287.         return;
  288.     }
  289.     CMutexGuard guard(m_Locks.m_Lookup);
  290.     x_GetRecords(s_ChoiceName[min(size_t(choice), kChoiceNameCount-1)],
  291.                  idh, x_Request2SeqrefMask(choice));
  292. }
  293. void CGBDataLoader::GetChunk(CTSE_Chunk_Info& chunk_info)
  294. {
  295.     CMutexGuard guard(m_Locks.m_Lookup);
  296.     x_GetChunk(GetTSEinfo(chunk_info.GetTSE_Info()), chunk_info);
  297. }
  298. CConstRef<CSeqref> CGBDataLoader::GetSatSatkey(const CSeq_id& id)
  299. {
  300.     return GetSatSatkey(CSeq_id_Handle::GetHandle(id));
  301. }
  302. CConstRef<CSeqref> CGBDataLoader::GetSatSatkey(const CSeq_id_Handle& idh)
  303. {
  304.     CConstRef<CSeqref> ret;
  305.     {{
  306.         CMutexGuard guard(m_Locks.m_Lookup);
  307.         CRef<SSeqrefs> srs = x_ResolveHandle(idh);
  308.         ITERATE ( SSeqrefs::TSeqrefs, it, srs->m_Sr ) {
  309.             const CSeqref& sr = **it;
  310.             if ( sr.GetFlags() & CSeqref::fHasCore ) {
  311.                 ret = &sr;
  312.                 break;
  313.             }
  314.         }
  315.     }}
  316.     return ret;
  317. }
  318. void CGBDataLoader::x_GetRecords(const char*
  319. #ifdef DEBUG_SYNC
  320.                                  type_name
  321. #endif
  322.                                  ,
  323.                                  const CSeq_id_Handle& idh,
  324.                                  TMask sr_mask)
  325. {
  326.     GC();
  327.     char s[100];
  328. #ifdef DEBUG_SYNC
  329.     memset(s,0,sizeof(s));
  330.     {
  331.         strstream ss(s,sizeof(s));
  332.         ss << "GetRecords(" << type_name <<")";
  333.     }
  334. #else
  335.     s[0] = 0;
  336. #endif
  337.     CGBLGuard g(m_Locks,s);
  338.     x_GetRecords(idh, sr_mask);
  339. }
  340. #if !defined(_DEBUG)
  341. inline
  342. #endif
  343. void
  344. CGBDataLoader::x_Check(const STSEinfo* _DEBUG_ARG(me))
  345. {
  346. #if defined(_DEBUG)
  347.     unsigned c = 0;
  348.     bool tse_found=false;
  349.     const STSEinfo* tse2 = m_UseListHead;
  350.     const STSEinfo* t1 = 0;
  351.     while ( tse2 ) {
  352.         c++;
  353.         if( tse2 == me )
  354.             tse_found = true;
  355.         t1 = tse2;
  356.         tse2 = tse2->next;
  357.     }
  358.     _ASSERT(t1 == m_UseListTail);
  359.     _ASSERT(m_Sr2TseInfo.size() == m_TseCount ||
  360.             m_Sr2TseInfo.size() == m_TseCount + 1);
  361.     _ASSERT(c  <= m_TseCount);
  362.     //_ASSERT(m_Tse2TseInfo.size() <= m_TseCount);
  363.     if(me) {
  364.         //GBLOG_POST("check tse " << me << " by " << CThread::GetSelf() );
  365.         _ASSERT(tse_found);
  366.     }
  367. #endif
  368. }
  369. CRef<CGBDataLoader::STSEinfo>
  370. CGBDataLoader::GetTSEinfo(const CTSE_Info& tse_info)
  371. {
  372.     return CRef<STSEinfo>(const_cast<STSEinfo*>
  373.                           (dynamic_cast<const STSEinfo*>
  374.                            (tse_info.GetBlobId().GetPointerOrNull())));
  375. }
  376. void CGBDataLoader::DropTSE(const CTSE_Info& tse_info)
  377. {
  378.     CGBLGuard g(m_Locks,"drop_tse");
  379.     //TTse2TSEinfo::iterator it = m_Tse2TseInfo.find(sep);
  380.     //if (it == m_Tse2TseInfo.end()) // oops - apprently already done;
  381.     //    return true;
  382.     CRef<STSEinfo> tse = GetTSEinfo(tse_info);
  383.     if ( !tse )
  384.         return;
  385.     g.Lock(&*tse);
  386.     _ASSERT(tse);
  387.     x_Check(tse);
  388.   
  389.     //m_Tse2TseInfo.erase(it);
  390.     x_DropTSEinfo(tse);
  391. }
  392. CConstRef<CTSE_Info>
  393. CGBDataLoader::ResolveConflict(const CSeq_id_Handle& handle,
  394.                                const TTSE_LockSet& tse_set)
  395. {
  396.     bool         conflict=false;
  397. #ifdef _DEBUG  
  398.     {{
  399.         CNcbiOstrstream s;
  400.         s << "CGBDataLoader::ResolveConflict("<<handle.AsString();
  401.         ITERATE ( TTSE_LockSet, it, tse_set ) {
  402.             CRef<STSEinfo> ti = GetTSEinfo(**it);
  403.             s << ", " << DUMP(*ti);
  404.         }
  405.         _TRACE(string(CNcbiOstrstreamToString(s)));
  406.     }}
  407. #endif
  408.     GBLOG_POST( "ResolveConflict" );
  409.     CGBLGuard g(m_Locks,"ResolveConflict");
  410.     CRef<SSeqrefs> sr;
  411.     CConstRef<CTSE_Info> best;
  412.     {
  413.         int cnt = 5;
  414.         while ( !(sr = x_ResolveHandle(handle))  && cnt>0 )
  415.             cnt --;
  416.         if ( !sr )
  417.             return best;
  418.     }
  419.     ITERATE(TTSE_LockSet, sit, tse_set) {
  420.         CConstRef<CTSE_Info> ti = *sit;
  421.         CRef<STSEinfo> tse = GetTSEinfo(*ti);
  422.         if ( !tse )
  423.             continue;
  424.       
  425.         x_Check(tse);
  426.         g.Lock(&*tse);
  427.         if(tse->mode.test(STSEinfo::eDead) && !ti->IsDead()) {
  428.             GetDataSource()->x_UpdateTSEStatus(const_cast<CTSE_Info&>(*ti),
  429.                                                true);
  430.         }
  431.         if(tse->m_SeqIds.find(handle)!=tse->m_SeqIds.end()) {
  432.             // listed for given TSE
  433.             if(!best) {
  434.                 best=ti; conflict=false;
  435.             }
  436.             else if(!ti->IsDead() && best->IsDead()) {
  437.                 best=ti; conflict=false;
  438.             }
  439.             else if(ti->IsDead() && best->IsDead()) {
  440.                 conflict=true;
  441.             }
  442.             else if(ti->IsDead() && !best->IsDead()) {
  443.             }
  444.             else {
  445.                 conflict=true;
  446.                 //_ASSERT(ti->IsDead() || best->IsDead());
  447.             }
  448.         }
  449.         g.Unlock(&*tse);
  450.     }
  451.     if ( !best || conflict ) {
  452.         // try harder
  453.         
  454.         best.Reset();conflict=false;
  455.         ITERATE (SSeqrefs::TSeqrefs, srp, sr->m_Sr) {
  456.             TSr2TSEinfo::iterator tsep =
  457.                 m_Sr2TseInfo.find((*srp)->GetKeyByTSE());
  458.             if (tsep == m_Sr2TseInfo.end()) continue;
  459.             ITERATE(TTSE_LockSet, sit, tse_set) {
  460.                 CConstRef<CTSE_Info> ti = *sit;
  461.                 //TTse2TSEinfo::iterator it =
  462.                 //    m_Tse2TseInfo.find(&ti->GetSeq_entry());
  463.                 //if(it==m_Tse2TseInfo.end()) continue;
  464.                 CRef<STSEinfo> tinfo = GetTSEinfo(*ti);
  465.                 if ( !tinfo )
  466.                     continue;
  467.                 if(tinfo==tsep->second) {
  468.                     if ( !best )
  469.                         best=ti;
  470.                     else if (ti != best)
  471.                         conflict=true;
  472.                 }
  473.             }
  474.         }
  475.         if(conflict)
  476.             best.Reset();
  477.     }
  478.     if ( !best ) {
  479.         _TRACE("CGBDataLoader::ResolveConflict("<<handle.AsString()<<
  480.                ") - conflict");
  481.     }
  482.     return best;
  483. }
  484. //=======================================================================
  485. // GBLoader private interface
  486. // 
  487. void CGBDataLoader::x_ExcludeFromDropList(STSEinfo* tse)
  488. {
  489.     _ASSERT(tse);
  490.     _TRACE("x_ExcludeFromDropList("<<DUMP(*tse)<<")");
  491.     STSEinfo* next = tse->next;
  492.     STSEinfo* prev = tse->prev;
  493.     if ( next || prev ) {
  494.         x_Check(tse);
  495.         if ( next ) {
  496.             _ASSERT(tse != m_UseListTail);
  497.             _ASSERT(tse == next->prev);
  498.             next->prev = prev;
  499.         }
  500.         else {
  501.             _ASSERT(tse == m_UseListTail);
  502.             m_UseListTail = prev;
  503.         }
  504.         if ( prev ) {
  505.             _ASSERT(tse != m_UseListHead);
  506.             _ASSERT(tse == prev->next);
  507.             prev->next = next;
  508.         }
  509.         else {
  510.             _ASSERT(tse == m_UseListHead);
  511.             m_UseListHead = next;
  512.         }
  513.         tse->prev = tse->next = 0;
  514.         --m_TseCount;
  515.     }
  516.     else if ( tse == m_UseListHead ) {
  517.         _ASSERT(tse == m_UseListTail);
  518.         x_Check(tse);
  519.         m_UseListHead = m_UseListTail = 0;
  520.         --m_TseCount;
  521.     }
  522.     else {
  523.         _ASSERT(tse != m_UseListTail);
  524.     }
  525.     x_Check();
  526. }
  527. void CGBDataLoader::x_AppendToDropList(STSEinfo* tse)
  528. {
  529.     _ASSERT(tse);
  530.     _TRACE("x_AppendToDropList("<<DUMP(*tse)<<")");
  531.     _ASSERT(m_Sr2TseInfo[tse->key] == tse);
  532.     x_Check();
  533.     _ASSERT(!tse->next && !tse->prev);
  534.     if ( m_UseListTail ) {
  535.         tse->prev = m_UseListTail;
  536.         m_UseListTail->next = tse;
  537.         m_UseListTail = tse;
  538.     }
  539.     else {
  540.         _ASSERT(!m_UseListHead);
  541.         m_UseListHead = m_UseListTail = tse;
  542.     }
  543.     ++m_TseCount;
  544.     x_Check(tse);
  545. }
  546. void CGBDataLoader::x_UpdateDropList(STSEinfo* tse)
  547. {
  548.     _ASSERT(tse);
  549.     // reset LRU links
  550.     if(tse == m_UseListTail) // already the last one
  551.         return;
  552.   
  553.     // Unlink from current place
  554.     x_ExcludeFromDropList(tse);
  555.     x_AppendToDropList(tse);
  556. }
  557. void CGBDataLoader::x_DropTSEinfo(STSEinfo* tse)
  558. {
  559.     if(!tse) return;
  560.     _TRACE( "DropBlob(" << DUMP(*tse) << ")" );
  561.   
  562.     ITERATE(STSEinfo::TSeqids,sih_it,tse->m_SeqIds) {
  563.         m_Bs2Sr.erase(*sih_it);
  564.     }
  565.     x_ExcludeFromDropList(tse);
  566.     m_Sr2TseInfo.erase(tse->key);
  567. }
  568. void CGBDataLoader::GC(void)
  569. {
  570.     //LOG_POST("X_GC "<<m_TseCount<<","<<m_TseGC_Threshhold<<","<< m_InvokeGC);
  571.     // dirty read - but that ok for garbage collector
  572.     if(!m_InvokeGC || m_TseCount==0) return ;
  573.     if(m_TseCount < m_TseGC_Threshhold) {
  574.         if(m_TseCount < 0.5*m_TseGC_Threshhold)
  575.             m_TseGC_Threshhold = (m_TseCount + 3*m_TseGC_Threshhold)/4;
  576.         return;
  577.     }
  578.     GBLOG_POST( "X_GC " << m_TseCount);
  579.     //GetDataSource()->x_CleanupUnusedEntries();
  580.     CGBLGuard g(m_Locks,"GC");
  581.     x_Check();
  582.     unsigned skip=0;
  583.     // scan 10% of least recently used pile before giving up:
  584.     unsigned skip_max = (int)(0.1*m_TseCount + 1);
  585.     STSEinfo* cur_tse = m_UseListHead;
  586.     while ( cur_tse && skip<skip_max) {
  587.         STSEinfo* tse_to_drop = cur_tse;
  588.         cur_tse = cur_tse->next;
  589.         ++skip;
  590.         // fast checks
  591.         if (tse_to_drop->locked) continue;
  592.         if (tse_to_drop->tseinfop && tse_to_drop->tseinfop->Locked()) continue;
  593.         //CRef<CTSE_Info> tse_info(tse_to_drop->tseinfop);
  594.         if ( !tse_to_drop->tseinfop ) {
  595.             // not loaded yet
  596.             if ( tse_to_drop->m_LoadState != STSEinfo::eLoadStateNone ) {
  597.                 // no data
  598.                 g.Lock(tse_to_drop);
  599.                 GBLOG_POST("X_GC:: drop nonexistent tse " << tse_to_drop);
  600.                 CRef<STSEinfo> tse_ref(tse_to_drop);
  601.                 x_DropTSEinfo(tse_to_drop);
  602.                 g.Unlock(tse_to_drop);
  603.                 --skip;
  604.             }
  605.             continue;
  606.         }
  607.         //if(m_Tse2TseInfo.find(sep) == m_Tse2TseInfo.end()) continue;
  608.         
  609.         GBLOG_POST("X_GC::DropTSE("<<TSE(*tse_to_drop)<<")");
  610.         //g.Unlock();
  611.         g.Lock(tse_to_drop);
  612.         if( GetDataSource()->DropTSE(*tse_to_drop->tseinfop) ) {
  613.             --skip;
  614.             m_InvokeGC=false;
  615.         }
  616.         g.Unlock(tse_to_drop);
  617.         //g.Lock();
  618. #if defined(NCBI_THREADS)
  619.         unsigned i=0;
  620.         for(cur_tse = m_UseListHead; cur_tse && i<skip; ++i) {
  621.             cur_tse = cur_tse->next;
  622.         }
  623. #endif
  624.     }
  625.     if(m_InvokeGC) { // nothing has been cleaned up
  626.         //assert(m_TseGC_Threshhold<=m_TseCount); // GC entrance condition
  627.         m_TseGC_Threshhold = m_TseCount+2; // do not even try until next load
  628.     } else if(m_TseCount < 0.5*m_TseGC_Threshhold) {
  629.         m_TseGC_Threshhold = (m_TseCount + m_TseGC_Threshhold)/2;
  630.     }
  631. }
  632. CSeqref::TFlags x_Request2SeqrefMask(CGBDataLoader::EChoice choice)
  633. {
  634.     switch(choice) {
  635.     case CGBDataLoader::eBlob:
  636.     case CGBDataLoader::eBioseq:
  637.     case CGBDataLoader::eAll:
  638.         // whole bioseq
  639.         return CSeqref::fHasAllLocal;
  640.     case CGBDataLoader::eCore:
  641.     case CGBDataLoader::eBioseqCore:
  642.         // everything except bioseqs & annotations
  643.         return CSeqref::fHasCore;
  644.     case CGBDataLoader::eSequence:
  645.         // seq data
  646.         return CSeqref::fHasSeqMap|CSeqref::fHasSeqData;
  647.     case CGBDataLoader::eFeatures:
  648.         // SeqFeatures
  649.         return CSeqref::fHasFeatures;
  650.     case CGBDataLoader::eGraph:
  651.         // SeqGraph
  652.         return CSeqref::fHasGraph;
  653.     case CGBDataLoader::eAlign:
  654.         // SeqGraph
  655.         return CSeqref::fHasAlign;
  656.     case CGBDataLoader::eAnnot:
  657.         // all annotations
  658.         return CSeqref::fHasAlign | CSeqref::fHasGraph |
  659.             CSeqref::fHasFeatures | CSeqref::fHasExternal;
  660.     default:
  661.         return 0;
  662.     }
  663. }
  664. void CGBDataLoader::x_GetRecords(const CSeq_id_Handle& sih,
  665.                                  TMask sr_mask)
  666. {
  667.     int attempt_count = 3, attempt;
  668.     for ( attempt = 0; attempt < attempt_count; ++attempt ) {
  669.         CRef<SSeqrefs> sr = x_ResolveHandle(sih);
  670.         _ASSERT(sr);
  671.         try {
  672.             ITERATE ( SSeqrefs::TSeqrefs, srp, sr->m_Sr ) {
  673.                 // skip TSE which doesn't contain requested type of info
  674.                 if( ((*srp)->GetFlags() & sr_mask) == 0 )
  675.                     continue;
  676.                 
  677.                 // find TSE info for each seqref
  678.                 TSr2TSEinfo::iterator tsep =
  679.                     m_Sr2TseInfo.find((*srp)->GetKeyByTSE());
  680.                 CRef<STSEinfo> tse;
  681.                 if (tsep != m_Sr2TseInfo.end()) {
  682.                     tse = tsep->second;
  683.                 }
  684.                 else {
  685.                     tse.Reset(new STSEinfo());
  686.                     tse->seqref = *srp;
  687.                     tse->key = tse->seqref->GetKeyByTSE();
  688.                     m_Sr2TseInfo[tse->key] = tse;
  689.                     x_AppendToDropList(tse.GetPointer());
  690.                     GBLOG_POST("x_GetRecords-newTSE(" << tse << ")");
  691.                 }
  692.                 
  693.                 CGBLGuard g(m_Locks,CGBLGuard::eMain,"x_GetRecords");
  694.                 g.Lock(&*tse);
  695.                 {{ // make sure we have reverse reference to handle
  696.                     STSEinfo::TSeqids &sid = tse->m_SeqIds;
  697.                     if (sid.find(sih) == sid.end())
  698.                         sid.insert(sih);
  699.                 }}
  700.                 
  701.                 if( !x_NeedMoreData(*tse) )
  702.                     continue;
  703.                 // need update
  704.                 _ASSERT(tse->m_LoadState != STSEinfo::eLoadStateDone);
  705.                 tse->locked++;
  706.                 g.Local();
  707.                 CReader::TConn conn = m_Locks.m_Pool.Select(&*tse);
  708.                 try {
  709.                     x_GetData(tse, conn);
  710.                 }
  711.                 catch ( CLoaderException& e ) {
  712.                     g.Lock();
  713.                     g.Lock(&*tse);
  714.                     tse->locked--;
  715.                     x_UpdateDropList(&*tse); // move up as just checked
  716.                     switch ( e.GetErrCode() ) {
  717.                     case CLoaderException::eNoConnection:
  718.                         throw;
  719.                     case CLoaderException::ePrivateData:
  720.                         // no need to reconnect
  721.                         // no need to wait more
  722.                         break;
  723.                     case CLoaderException::eNoData:
  724.                         // no need to reconnect
  725.                         throw;
  726.                     default:
  727.                         ERR_POST("GenBank connection failed: Reconnecting...");
  728.                         m_Driver->Reconnect(conn);
  729.                         throw;
  730.                     }
  731.                 }
  732.                 catch ( ... ) {
  733.                     g.Lock();
  734.                     g.Lock(&*tse);
  735.                     tse->locked--;
  736.                     x_UpdateDropList(&*tse); // move up as just checked
  737.                     ERR_POST("GenBank connection failed: Reconnecting...");
  738.                     m_Driver->Reconnect(conn);
  739.                     throw;
  740.                 }
  741.                 _ASSERT(!x_NeedMoreData(*tse));
  742.                 g.Lock();
  743.                 g.Lock(&*tse);
  744.                 tse->locked--;
  745.                 x_UpdateDropList(&*tse); // move up as just checked
  746.                 x_Check(&*tse);
  747.                 x_Check();
  748.             }
  749.             // everything is loaded, break the attempt loop
  750.             break;
  751.         }
  752.         catch ( CLoaderException& e ) {
  753.             ERR_POST(e.what());
  754.             if ( e.GetErrCode() == e.eNoConnection ) {
  755.                 throw;
  756.             }
  757.         }
  758.         catch ( exception& e ) {
  759.             ERR_POST(e.what());
  760.         }
  761.         catch ( ... ) {
  762.             ERR_POST(CThread::GetSelf()<<":: Data request failed....");
  763.             throw;
  764.         }
  765.         // something is not loaded
  766.         // in case of any error we'll force reloading seqrefs
  767.         
  768.         CGBLGuard g(m_Locks,CGBLGuard::eMain,"x_ResolveHandle");
  769.         g.Lock();
  770.         sr->m_Timer.Reset();
  771.         m_Driver->PurgeSeqrefs(sr->m_Sr, *sih.GetSeqId());
  772.     }
  773.     if ( attempt >= attempt_count ) {
  774.         ERR_POST("CGBLoader:GetData: data request failed: "
  775.                  "exceeded maximum attempts count");
  776.         NCBI_THROW(CLoaderException, eLoaderFailed,
  777.                    "Multiple attempts to retrieve data failed");
  778.     }
  779. }
  780. void CGBDataLoader::x_GetChunk(CRef<STSEinfo> tse,
  781.                                CTSE_Chunk_Info& chunk_info)
  782. {
  783.     CGBLGuard g(m_Locks,"x_GetChunk");
  784.     g.Lock(&*tse);
  785.     tse->locked++;
  786.     g.Local();
  787.     bool done = false;
  788.     int try_cnt = 3;
  789.     while( !done && try_cnt-- > 0 ) {
  790.         CReader::TConn conn = m_Locks.m_Pool.Select(&*tse);
  791.         try {
  792.             x_GetChunk(tse, conn, chunk_info);
  793.             done = true;
  794.             break;
  795.         }
  796.         catch ( CLoaderException& e ) {
  797.             if ( e.GetErrCode() == CLoaderException::eNoConnection ) {
  798.                 g.Lock();
  799.                 g.Lock(&*tse);
  800.                 tse->locked--;
  801.                 x_UpdateDropList(&*tse); // move up as just checked
  802.                 throw;
  803.             }
  804.             LOG_POST(e.what());
  805.             LOG_POST("GenBank connection failed: Reconnecting....");
  806.             m_Driver->Reconnect(conn);
  807.         }
  808.         catch ( const exception &e ) {
  809.             LOG_POST(e.what());
  810.             LOG_POST("GenBank connection failed: Reconnecting....");
  811.             m_Driver->Reconnect(conn);
  812.         }
  813.         catch ( ... ) {
  814.             LOG_POST("GenBank connection failed: Reconnecting....");
  815.             m_Driver->Reconnect(conn);
  816.             g.Lock();
  817.             g.Lock(&*tse);
  818.             tse->locked--;
  819.             x_UpdateDropList(&*tse); // move up as just checked
  820.             throw;
  821.         }
  822.     }
  823.     if ( !done ) {
  824.         ERR_POST("CGBLoader:GetChunk: data request failed: "
  825.                  "exceeded maximum attempts count");
  826.         g.Lock();
  827.         g.Lock(&*tse);
  828.         tse->locked--;
  829.         x_UpdateDropList(&*tse); // move up as just checked
  830.         NCBI_THROW(CLoaderException, eLoaderFailed,
  831.                    "Multiple attempts to retrieve data failed");
  832.     }
  833.     g.Lock();
  834.     g.Lock(&*tse);
  835.     x_UpdateDropList(&*tse);
  836.     if( done ) {
  837.         x_Check();
  838.         _ASSERT(tse->tseinfop);
  839.     }
  840.     tse->locked--;
  841.     x_Check(&*tse);
  842. }
  843. class CTimerGuard
  844. {
  845.     CTimer *t;
  846.     bool    calibrating;
  847. public:
  848.     CTimerGuard(CTimer& x)
  849.         : t(&x), calibrating(x.NeedCalibration())
  850.         {
  851.             if ( calibrating ) {
  852.                 t->Start();
  853.             }
  854.         }
  855.     ~CTimerGuard(void)
  856.         {
  857.             if ( calibrating ) {
  858.                 t->Stop();
  859.             }
  860.         }
  861. };
  862. CRef<SSeqrefs> CGBDataLoader::x_ResolveHandle(const CSeq_id_Handle& h)
  863. {
  864.     CGBLGuard g(m_Locks,CGBLGuard::eMain,"x_ResolveHandle");
  865.     CRef<SSeqrefs> sr;
  866.     TSeqId2Seqrefs::iterator bsit = m_Bs2Sr.find(h);
  867.     if (bsit == m_Bs2Sr.end() ) {
  868.         sr.Reset(new SSeqrefs(h));
  869.         m_Bs2Sr[h] = sr;
  870.     }
  871.     else {
  872.         sr = bsit->second;
  873.     }
  874.     int key = sr->m_Handle.GetHash();
  875.     g.Lock(key);
  876.     if( !sr->m_Timer.NeedRefresh(m_Timer) )
  877.         return sr;
  878.     g.Local();
  879.     SSeqrefs::TSeqrefs osr;
  880.     bool got = false;
  881.     CConstRef<CSeq_id> seq_id = h.GetSeqId();
  882.     for ( int try_cnt = 3; !got && try_cnt > 0; --try_cnt ) {
  883.         osr.clear();
  884.         CTimerGuard tg(m_Timer);
  885.         CReader::TConn conn = m_Locks.m_Pool.Select(key);
  886.         try {
  887.             m_Driver->ResolveSeq_id(osr, *seq_id, conn);
  888.             got = true;
  889.             break;
  890.         }
  891.         catch ( CLoaderException& e ) {
  892.             if ( e.GetErrCode() == CLoaderException::eNoConnection ) {
  893.                 throw;
  894.             }
  895.             LOG_POST(e.what());
  896.         }
  897.         catch ( const exception &e ) {
  898.             LOG_POST(e.what());
  899.         }
  900.         LOG_POST("GenBank connection failed: Reconnecting....");
  901.         m_Driver->Reconnect(conn);
  902.     }
  903.     if ( !got ) {
  904.         ERR_POST("CGBLoader:x_ResolveHandle: Seq-id resolve failed: "
  905.                  "exceeded maximum attempts count");
  906.         NCBI_THROW(CLoaderException, eLoaderFailed,
  907.                    "Multiple attempts to resolve Seq-id failed");
  908.     }
  909.     g.Lock(); // will unlock everything and lock lookupMutex again 
  910.     swap(sr->m_Sr, osr);
  911.     sr->m_Timer.Reset(m_Timer);
  912.   
  913.     GBLOG_POST( "ResolveHandle(" << h << ") " << sr->m_Sr.size() );
  914.     ITERATE(SSeqrefs::TSeqrefs, srp, sr->m_Sr) {
  915.         GBLOG_POST( (*srp)->print());
  916.     }
  917.     
  918.     if ( !osr.empty() ) {
  919.         bsit = m_Bs2Sr.find(h);
  920.         // make sure we are not deleted in the unlocked time 
  921.         if (bsit != m_Bs2Sr.end()) {
  922.             SSeqrefs::TSeqrefs& nsr=bsit->second->m_Sr;
  923.           
  924.             // catch dissolving TSE and mark them dead
  925.             //GBLOG_POST( "old seqrefs");
  926.             ITERATE ( SSeqrefs::TSeqrefs, srp, osr ) {
  927.                 //(*srp)->print(); cout);
  928.                 bool found=false;
  929.                 ITERATE ( SSeqrefs::TSeqrefs, nsrp, nsr ) {
  930.                     if( (*srp)->SameTSE(**nsrp) ) {
  931.                         found=true;
  932.                         break;
  933.                     }
  934.                 }
  935.                 if ( found ) {
  936.                     continue;
  937.                 }
  938.                 TSr2TSEinfo::iterator tsep =
  939.                     m_Sr2TseInfo.find((*srp)->GetKeyByTSE());
  940.                 if (tsep == m_Sr2TseInfo.end()) {
  941.                     continue;
  942.                 }
  943.               
  944.                 // update TSE info 
  945.                 CRef<STSEinfo> tse = tsep->second;
  946.                 g.Lock(&*tse);
  947.                 bool mark_dead  = tse->mode.test(STSEinfo::eDead);
  948.                 if ( mark_dead ) {
  949.                     tse->mode.set(STSEinfo::eDead);
  950.                 }
  951.                 tse->m_SeqIds.erase(h); // drop h as refewrenced seqid
  952.                 g.Unlock(&*tse);
  953.                 if ( mark_dead && tse->tseinfop ) {
  954.                     // inform data_source :: make sure to avoid deadlocks
  955.                     tse->tseinfop->SetDead(true);
  956.                 }
  957.             }
  958.         }
  959.     }
  960.     return sr;
  961. }
  962. bool CGBDataLoader::x_NeedMoreData(const STSEinfo& tse)
  963. {
  964.     bool need_data=true;
  965.   
  966.     if (tse.m_LoadState==STSEinfo::eLoadStateDone)
  967.         need_data=false;
  968.     if (tse.m_LoadState==STSEinfo::eLoadStatePartial) {
  969.         // split code : check tree for presence of data and
  970.         // return from routine if all data already loaded
  971.         // present;
  972.     }
  973.     return need_data;
  974. }
  975. void CGBDataLoader::x_GetData(CRef<STSEinfo> tse,
  976.                               CReader::TConn conn)
  977. {
  978.     try {
  979.         if ( x_NeedMoreData(*tse) ) {
  980.             GBLOG_POST("GetBlob("<<TSE(*tse)<<") "<<":="<<tse->m_LoadState);
  981.             
  982.             _ASSERT(tse->m_LoadState != STSEinfo::eLoadStateDone);
  983.             if (tse->m_LoadState == STSEinfo::eLoadStateNone) {
  984.                 CRef<CTSE_Info> tse_info =
  985.                     m_Driver->GetBlob(*tse->seqref, conn);
  986.                 GBLOG_POST("GetBlob("<<TSE(*tse)<<")");
  987.                 m_InvokeGC=true;
  988.                 _ASSERT(tse_info);
  989.                 tse->m_LoadState   = STSEinfo::eLoadStateDone;
  990.                 tse_info->SetBlobId(tse);
  991.                 GetDataSource()->AddTSE(tse_info);
  992.                 tse->tseinfop = tse_info.GetPointer();
  993.                 _TRACE("GetBlob("<<DUMP(*tse)<<") - whole blob retrieved");
  994.             }
  995.         }
  996.     }
  997.     catch ( CLoaderException& e ) {
  998.         if ( e.GetErrCode() == e.ePrivateData ) {
  999.             LOG_POST("GI("<<tse->seqref->GetGi()<<") is private");
  1000.             tse->m_LoadState = STSEinfo::eLoadStateDone;
  1001.         }
  1002.         else if ( e.GetErrCode() == e.eNoData ) {
  1003.             if ( (tse->seqref->GetFlags() & CSeqref::fPossible) ) {
  1004.                 tse->m_LoadState   = STSEinfo::eLoadStateDone;
  1005.             }
  1006.             else {
  1007.                 LOG_POST("ERROR: can not retrive sequence: "<<TSE(*tse));
  1008.                 throw;
  1009.             }
  1010.         }
  1011.         else {
  1012.             throw;
  1013.         }
  1014.     }
  1015.     _ASSERT(!x_NeedMoreData(*tse));
  1016. }
  1017. void CGBDataLoader::x_GetChunk(CRef<STSEinfo> tse,
  1018.                                CReader::TConn conn,
  1019.                                CTSE_Chunk_Info& chunk_info)
  1020. {
  1021.     GBLOG_POST("GetChunk("<<TSE(*tse)<<") "<<":="<<chunk_info.GetChunkId());
  1022.   
  1023.     _ASSERT(tse->m_LoadState == STSEinfo::eLoadStateDone);
  1024.     
  1025.     CRef<CTSE_Info> tse_info =
  1026.         m_Driver->GetBlob(*tse->seqref, conn, &chunk_info);
  1027.     GBLOG_POST("GetChunk("<<TSE(*tse)<<")");
  1028.     m_InvokeGC=true;
  1029.     _ASSERT(!tse_info);
  1030.     _TRACE("GetChunk("<<DUMP(*tse)<<") - chunk retrieved");
  1031. }
  1032. const CSeqref& CGBDataLoader::GetSeqref(const CTSE_Info& tse_info)
  1033. {
  1034.     if ( &tse_info.GetDataSource() != GetDataSource() ) {
  1035.         NCBI_THROW(CLoaderException, eLoaderFailed,
  1036.                    "not mine TSE");
  1037.     }
  1038.     CRef<CGBDataLoader::STSEinfo> info(GetTSEinfo(tse_info));
  1039.     return *info->seqref;
  1040. }
  1041. void
  1042. CGBDataLoader::DebugDump(CDebugDumpContext ddc, unsigned int /*depth*/) const
  1043. {
  1044.     ddc.SetFrame("CGBLoader");
  1045.     // CObject::DebugDump( ddc, depth);
  1046.     DebugDumpValue(ddc,"m_TseCount", m_TseCount);
  1047.     DebugDumpValue(ddc,"m_TseGC_Threshhold", m_TseGC_Threshhold);
  1048. }
  1049. END_SCOPE(objects)
  1050. END_NCBI_SCOPE
  1051. /* ---------------------------------------------------------------------------
  1052. * $Log: gbloader.cpp,v $
  1053. * Revision 1000.1  2004/06/01 19:41:37  gouriano
  1054. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.106
  1055. *
  1056. * Revision 1.106  2004/05/21 21:42:52  gorelenk
  1057. * Added PCH ncbi_pch.hpp
  1058. *
  1059. * Revision 1.105  2004/03/16 15:47:29  vasilche
  1060. * Added CBioseq_set_Handle and set of EditHandles
  1061. *
  1062. * Revision 1.104  2004/02/17 21:17:53  vasilche
  1063. * Fixed 'non-const reference to temporary' warning.
  1064. *
  1065. * Revision 1.103  2004/02/04 20:59:46  ucko
  1066. * Fix the PubSeq entry point name to something that actually exists....
  1067. *
  1068. * Revision 1.102  2004/02/04 17:47:40  kuznets
  1069. * Fixed naming of entry points
  1070. *
  1071. * Revision 1.101  2004/01/22 20:10:35  vasilche
  1072. * 1. Splitted ID2 specs to two parts.
  1073. * ID2 now specifies only protocol.
  1074. * Specification of ID2 split data is moved to seqsplit ASN module.
  1075. * For now they are still reside in one resulting library as before - libid2.
  1076. * As the result split specific headers are now in objects/seqsplit.
  1077. * 2. Moved ID2 and ID1 specific code out of object manager.
  1078. * Protocol is processed by corresponding readers.
  1079. * ID2 split parsing is processed by ncbi_xreader library - used by all readers.
  1080. * 3. Updated OBJMGR_LIBS correspondingly.
  1081. *
  1082. * Revision 1.100  2004/01/13 21:52:06  vasilche
  1083. * Resurrected new version.
  1084. *
  1085. * Revision 1.4  2004/01/13 16:55:55  vasilche
  1086. * CReader, CSeqref and some more classes moved from xobjmgr to separate lib.
  1087. * Headers moved from include/objmgr to include/objtools/data_loaders/genbank.
  1088. *
  1089. * Revision 1.3  2003/12/30 22:14:41  vasilche
  1090. * Updated genbank loader and readers plugins.
  1091. *
  1092. * Revision 1.98  2003/12/30 19:51:24  vasilche
  1093. * Implemented CGBDataLoader::GetSatSatkey() method.
  1094. *
  1095. * Revision 1.97  2003/12/30 17:43:17  vasilche
  1096. * Fixed warning about unused variable.
  1097. *
  1098. * Revision 1.96  2003/12/30 16:41:19  vasilche
  1099. * Removed warning about unused variable.
  1100. *
  1101. * Revision 1.95  2003/12/19 19:49:21  vasilche
  1102. * Use direct Seq-id -> sat/satkey resolution without intermediate gi.
  1103. *
  1104. * Revision 1.94  2003/12/03 15:14:05  kuznets
  1105. * CReader management re-written to use plugin manager
  1106. *
  1107. * Revision 1.93  2003/12/02 23:17:34  vasilche
  1108. * Fixed exception in ID1 reader when invalid Seq-id is supplied.
  1109. *
  1110. * Revision 1.92  2003/12/01 23:42:29  vasilche
  1111. * Temporary fix for segfault in genbank data loader in multithreaded applications.
  1112. *
  1113. * Revision 1.91  2003/11/26 17:55:58  vasilche
  1114. * Implemented ID2 split in ID1 cache.
  1115. * Fixed loading of splitted annotations.
  1116. *
  1117. * Revision 1.90  2003/10/27 19:28:02  vasilche
  1118. * Removed debug message.
  1119. *
  1120. * Revision 1.89  2003/10/27 18:50:49  vasilche
  1121. * Detect 'private' blobs in ID1 reader.
  1122. * Avoid reconnecting after ID1 server replied with error packet.
  1123. *
  1124. * Revision 1.88  2003/10/27 15:05:41  vasilche
  1125. * Added correct recovery of cached ID1 loader if gi->sat/satkey cache is invalid.
  1126. * Added recognition of ID1 error codes: private, etc.
  1127. * Some formatting of old code.
  1128. *
  1129. * Revision 1.87  2003/10/22 16:12:37  vasilche
  1130. * Added CLoaderException::eNoConnection.
  1131. * Added check for 'fail' state of ID1 connection stream.
  1132. * CLoaderException::eNoConnection will be rethrown from CGBLoader.
  1133. *
  1134. * Revision 1.86  2003/10/07 13:43:23  vasilche
  1135. * Added proper handling of named Seq-annots.
  1136. * Added feature search from named Seq-annots.
  1137. * Added configurable adaptive annotation search (default: gene, cds, mrna).
  1138. * Fixed selection of blobs for loading from GenBank.
  1139. * Added debug checks to CSeq_id_Mapper for easier finding lost CSeq_id_Handles.
  1140. * Fixed leaked split chunks annotation stubs.
  1141. * Moved some classes definitions in separate *.cpp files.
  1142. *
  1143. * Revision 1.85  2003/09/30 16:22:02  vasilche
  1144. * Updated internal object manager classes to be able to load ID2 data.
  1145. * SNP blobs are loaded as ID2 split blobs - readers convert them automatically.
  1146. * Scope caches results of requests for data to data loaders.
  1147. * Optimized CSeq_id_Handle for gis.
  1148. * Optimized bioseq lookup in scope.
  1149. * Reduced object allocations in annotation iterators.
  1150. * CScope is allowed to be destroyed before other objects using this scope are
  1151. * deleted (feature iterators, bioseq handles etc).
  1152. * Optimized lookup for matching Seq-ids in CSeq_id_Mapper.
  1153. * Added 'adaptive' option to objmgr_demo application.
  1154. *
  1155. * Revision 1.84  2003/09/05 17:29:40  grichenk
  1156. * Structurized Object Manager exceptions
  1157. *
  1158. * Revision 1.83  2003/08/27 14:25:22  vasilche
  1159. * Simplified CCmpTSE class.
  1160. *
  1161. * Revision 1.82  2003/08/14 20:05:19  vasilche
  1162. * Simple SNP features are stored as table internally.
  1163. * They are recreated when needed using CFeat_CI.
  1164. *
  1165. * Revision 1.81  2003/07/24 19:28:09  vasilche
  1166. * Implemented SNP split for ID1 loader.
  1167. *
  1168. * Revision 1.80  2003/07/22 22:01:43  vasilche
  1169. * Removed use of HAVE_LIBDL.
  1170. *
  1171. * Revision 1.79  2003/07/17 22:51:31  vasilche
  1172. * Fixed unused variables warnings.
  1173. *
  1174. * Revision 1.78  2003/07/17 20:07:56  vasilche
  1175. * Reduced memory usage by feature indexes.
  1176. * SNP data is loaded separately through PUBSEQ_OS.
  1177. * String compression for SNP data.
  1178. *
  1179. * Revision 1.77  2003/06/24 14:25:18  vasilche
  1180. * Removed obsolete CTSE_Guard class.
  1181. * Used separate mutexes for bioseq and annot maps.
  1182. *
  1183. * Revision 1.76  2003/06/11 14:54:06  vasilche
  1184. * Fixed wrong error message in CGBDataLoader destructor when
  1185. * some data requests were failed.
  1186. *
  1187. * Revision 1.75  2003/06/10 19:01:07  vasilche
  1188. * Fixed loader methods string.
  1189. *
  1190. * Revision 1.74  2003/06/10 15:25:33  vasilche
  1191. * Changed wrong _ASSERT to _VERIFY
  1192. *
  1193. * Revision 1.73  2003/06/02 16:06:37  dicuccio
  1194. * Rearranged src/objects/ subtree.  This includes the following shifts:
  1195. *     - src/objects/asn2asn --> arc/app/asn2asn
  1196. *     - src/objects/testmedline --> src/objects/ncbimime/test
  1197. *     - src/objects/objmgr --> src/objmgr
  1198. *     - src/objects/util --> src/objmgr/util
  1199. *     - src/objects/alnmgr --> src/objtools/alnmgr
  1200. *     - src/objects/flat --> src/objtools/flat
  1201. *     - src/objects/validator --> src/objtools/validator
  1202. *     - src/objects/cddalignview --> src/objtools/cddalignview
  1203. * In addition, libseq now includes six of the objects/seq... libs, and libmmdb
  1204. * replaces the three libmmdb? libs.
  1205. *
  1206. * Revision 1.72  2003/05/20 21:13:02  vasilche
  1207. * Fixed ambiguity on MSVC.
  1208. *
  1209. * Revision 1.71  2003/05/20 18:27:29  vasilche
  1210. * Fixed ambiguity on MSVC.
  1211. *
  1212. * Revision 1.70  2003/05/20 16:18:42  vasilche
  1213. * Fixed compilation errors on GCC.
  1214. *
  1215. * Revision 1.69  2003/05/20 15:44:37  vasilche
  1216. * Fixed interaction of CDataSource and CDataLoader in multithreaded app.
  1217. * Fixed some warnings on WorkShop.
  1218. * Added workaround for memory leak on WorkShop.
  1219. *
  1220. * Revision 1.68  2003/05/13 20:27:05  vasilche
  1221. * Added lost SAT SATKEY info in error message.
  1222. *
  1223. * Revision 1.67  2003/05/13 20:21:10  vasilche
  1224. * *** empty log message ***
  1225. *
  1226. * Revision 1.66  2003/05/13 20:14:40  vasilche
  1227. * Catching exceptions and reconnection were moved from readers to genbank loader.
  1228. *
  1229. * Revision 1.65  2003/05/13 18:32:29  vasilche
  1230. * Fixed use of GBLOG_POST() macro.
  1231. *
  1232. * Revision 1.64  2003/05/12 19:18:29  vasilche
  1233. * Fixed locking of object manager classes in multi-threaded application.
  1234. *
  1235. * Revision 1.63  2003/05/12 18:26:08  vasilche
  1236. * Removed buggy _ASSERT() on reconnection.
  1237. *
  1238. * Revision 1.62  2003/05/06 16:52:28  vasilche
  1239. * Try to reconnect to genbank on any exception.
  1240. *
  1241. * Revision 1.61  2003/04/29 19:51:13  vasilche
  1242. * Fixed interaction of Data Loader garbage collector and TSE locking mechanism.
  1243. * Made some typedefs more consistent.
  1244. *
  1245. * Revision 1.60  2003/04/24 16:12:38  vasilche
  1246. * Object manager internal structures are splitted more straightforward.
  1247. * Removed excessive header dependencies.
  1248. *
  1249. * Revision 1.59  2003/04/18 17:38:01  grichenk
  1250. * Use GENBANK_LOADER_METHOD env. variable to specify GB readers.
  1251. * Default is "PUBSEQOS:ID1".
  1252. *
  1253. * Revision 1.58  2003/04/15 16:32:29  dicuccio
  1254. * Added include for I_DriverContext from DBAPI library - avoids concerning
  1255. * warning about deletion of unknwon type.
  1256. *
  1257. * Revision 1.57  2003/04/15 15:30:15  vasilche
  1258. * Added include <memory> when needed.
  1259. * Removed buggy buffer in printing methods.
  1260. * Removed unnecessary include of stream_util.hpp.
  1261. *
  1262. * Revision 1.56  2003/04/15 14:24:08  vasilche
  1263. * Changed CReader interface to not to use fake streams.
  1264. *
  1265. * Revision 1.55  2003/03/21 19:22:51  grichenk
  1266. * Redesigned TSE locking, replaced CTSE_Lock with CRef<CTSE_Info>.
  1267. *
  1268. * Revision 1.54  2003/03/11 15:51:06  kuznets
  1269. * iterate -> ITERATE
  1270. *
  1271. * Revision 1.53  2003/03/05 20:54:41  vasilche
  1272. * Commented out wrong assert().
  1273. *
  1274. * Revision 1.52  2003/03/03 20:34:51  vasilche
  1275. * Added NCBI_THREADS macro - it's opposite to NCBI_NO_THREADS.
  1276. * Avoid using _REENTRANT macro - use NCBI_THREADS instead.
  1277. *
  1278. * Revision 1.51  2003/03/01 23:07:42  kimelman
  1279. * bugfix: MTsafe
  1280. *
  1281. * Revision 1.50  2003/03/01 22:27:57  kimelman
  1282. * performance fixes
  1283. *
  1284. * Revision 1.49  2003/02/27 21:58:26  vasilche
  1285. * Fixed performance of Object Manager's garbage collector.
  1286. *
  1287. * Revision 1.48  2003/02/26 18:03:31  vasilche
  1288. * Added some error check.
  1289. * Fixed formatting.
  1290. *
  1291. * Revision 1.47  2003/02/24 18:57:22  vasilche
  1292. * Make feature gathering in one linear pass using CSeqMap iterator.
  1293. * Do not use feture index by sub locations.
  1294. * Sort features at the end of gathering in one vector.
  1295. * Extracted some internal structures and classes in separate header.
  1296. * Delay creation of mapped features.
  1297. *
  1298. * Revision 1.46  2003/02/05 17:59:17  dicuccio
  1299. * Moved formerly private headers into include/objects/objmgr/impl
  1300. *
  1301. * Revision 1.45  2003/01/22 20:11:54  vasilche
  1302. * Merged functionality of CSeqMapResolved_CI to CSeqMap_CI.
  1303. * CSeqMap_CI now supports resolution and iteration over sequence range.
  1304. * Added several caches to CScope.
  1305. * Optimized CSeqVector().
  1306. * Added serveral variants of CBioseqHandle::GetSeqVector().
  1307. * Tried to optimize annotations iterator (not much success).
  1308. * Rewritten CHandleRange and CHandleRangeMap classes to avoid sorting of list.
  1309. *
  1310. * Revision 1.44  2002/12/26 20:53:02  dicuccio
  1311. * Moved tse_info.hpp -> include/ tree.  Minor tweaks to relieve compiler
  1312. * warnings in MSVC.
  1313. *
  1314. * Revision 1.43  2002/11/08 19:43:35  grichenk
  1315. * CConstRef<> constructor made explicit
  1316. *
  1317. * Revision 1.42  2002/11/04 21:29:12  grichenk
  1318. * Fixed usage of const CRef<> and CRef<> constructor
  1319. *
  1320. * Revision 1.41  2002/09/09 16:12:43  dicuccio
  1321. * Fixed minor typo ("conneciton" -> "connection").
  1322. *
  1323. * Revision 1.40  2002/07/24 20:30:27  ucko
  1324. * Move CTimerGuard out to file scope to fix a MIPSpro compiler core dump.
  1325. *
  1326. * Revision 1.39  2002/07/22 22:53:24  kimelman
  1327. * exception handling fixed: 2level mutexing moved to Guard class + added
  1328. * handling of confidential data.
  1329. *
  1330. * Revision 1.38  2002/06/04 17:18:33  kimelman
  1331. * memory cleanup :  new/delete/Cref rearrangements
  1332. *
  1333. * Revision 1.37  2002/05/14 20:06:26  grichenk
  1334. * Improved CTSE_Info locking by CDataSource and CDataLoader
  1335. *
  1336. * Revision 1.36  2002/05/10 16:44:32  kimelman
  1337. * tuning to allow pubseq enable build
  1338. *
  1339. * Revision 1.35  2002/05/08 22:23:48  kimelman
  1340. * MT fixes
  1341. *
  1342. * Revision 1.34  2002/05/06 03:28:47  vakatov
  1343. * OM/OM1 renaming
  1344. *
  1345. * Revision 1.33  2002/05/03 21:28:10  ucko
  1346. * Introduce T(Signed)SeqPos.
  1347. *
  1348. * Revision 1.32  2002/04/30 18:56:54  gouriano
  1349. * added multithreading-related initialization
  1350. *
  1351. * Revision 1.31  2002/04/28 03:36:47  vakatov
  1352. * Temporarily turn off R1.30(b) unconditionally -- until it is buildable
  1353. *
  1354. * Revision 1.30  2002/04/26 16:32:23  kimelman
  1355. * a) turn on GC b) turn on PubSeq where sybase is available
  1356. *
  1357. * Revision 1.29  2002/04/12 22:54:28  kimelman
  1358. * pubseq_reader auto call commented per Denis request
  1359. *
  1360. * Revision 1.28  2002/04/12 21:10:33  kimelman
  1361. * traps for coredumps
  1362. *
  1363. * Revision 1.27  2002/04/11 18:45:35  ucko
  1364. * Pull in extra headers to make KCC happy.
  1365. *
  1366. * Revision 1.26  2002/04/10 22:47:56  kimelman
  1367. * added pubseq_reader as default one
  1368. *
  1369. * Revision 1.25  2002/04/09 19:04:23  kimelman
  1370. * make gcc happy
  1371. *
  1372. * Revision 1.24  2002/04/09 18:48:15  kimelman
  1373. * portability bugfixes: to compile on IRIX, sparc gcc
  1374. *
  1375. * Revision 1.23  2002/04/05 23:47:18  kimelman
  1376. * playing around tests
  1377. *
  1378. * Revision 1.22  2002/04/04 01:35:35  kimelman
  1379. * more MT tests
  1380. *
  1381. * Revision 1.21  2002/04/02 17:27:00  gouriano
  1382. * bugfix: skip test for yet unregistered data
  1383. *
  1384. * Revision 1.20  2002/04/02 16:27:20  gouriano
  1385. * memory leak
  1386. *
  1387. * Revision 1.19  2002/04/02 16:02:31  kimelman
  1388. * MT testing
  1389. *
  1390. * Revision 1.18  2002/03/30 19:37:06  kimelman
  1391. * gbloader MT test
  1392. *
  1393. * Revision 1.17  2002/03/29 02:47:04  kimelman
  1394. * gbloader: MT scalability fixes
  1395. *
  1396. * Revision 1.16  2002/03/27 20:23:50  butanaev
  1397. * Added connection pool.
  1398. *
  1399. * Revision 1.15  2002/03/26 23:31:08  gouriano
  1400. * memory leaks and garbage collector fix
  1401. *
  1402. * Revision 1.14  2002/03/26 15:39:24  kimelman
  1403. * GC fixes
  1404. *
  1405. * Revision 1.13  2002/03/25 17:49:12  kimelman
  1406. * ID1 failure handling
  1407. *
  1408. * Revision 1.12  2002/03/25 15:44:46  kimelman
  1409. * proper logging and exception handling
  1410. *
  1411. * Revision 1.11  2002/03/22 18:56:05  kimelman
  1412. * GC list fix
  1413. *
  1414. * Revision 1.10  2002/03/22 18:51:18  kimelman
  1415. * stream WS skipping fix
  1416. *
  1417. * Revision 1.9  2002/03/22 18:15:47  grichenk
  1418. * Unset "skipws" flag in binary stream
  1419. *
  1420. * Revision 1.8  2002/03/21 23:16:32  kimelman
  1421. * GC bugfixes
  1422. *
  1423. * Revision 1.7  2002/03/21 21:39:48  grichenk
  1424. * garbage collector bugfix
  1425. *
  1426. * Revision 1.6  2002/03/21 19:14:53  kimelman
  1427. * GB related bugfixes
  1428. *
  1429. * Revision 1.5  2002/03/21 01:34:53  kimelman
  1430. * gbloader related bugfixes
  1431. *
  1432. * Revision 1.4  2002/03/20 21:24:59  gouriano
  1433. * *** empty log message ***
  1434. *
  1435. * Revision 1.3  2002/03/20 19:06:30  kimelman
  1436. * bugfixes
  1437. *
  1438. * Revision 1.2  2002/03/20 17:03:24  gouriano
  1439. * minor changes to make it compilable on MS Windows
  1440. *
  1441. * Revision 1.1  2002/03/20 04:50:13  kimelman
  1442. * GB loader added
  1443. *
  1444. * ===========================================================================
  1445. */