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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: gbload_util.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:41:34  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.25
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: gbload_util.cpp,v 1000.1 2004/06/01 19:41:34 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
  35. *
  36. *  File Description: GenBank Data loader
  37. *
  38. */
  39. #include <ncbi_pch.hpp>
  40. #include <objtools/data_loaders/genbank/gbload_util.hpp>
  41. #include <objtools/data_loaders/genbank/gbloader.hpp>
  42. #include <objmgr/impl/handle_range.hpp>
  43. #include <objmgr/objmgr_exception.hpp>
  44. BEGIN_NCBI_SCOPE
  45. BEGIN_SCOPE(objects)
  46. //============================================================================
  47. // Support Classes
  48. //
  49. //////////////////////////////////////////////////////////////////////////////
  50. //
  51. // CTimer 
  52. CTimer::CTimer(void)
  53.     : m_RequestsDevider(0), m_Requests(0)
  54. {
  55.     m_ReasonableRefreshDelay = 0;
  56.     m_LastCalibrated = m_Time= time(0);
  57. }
  58. time_t CTimer::Time(void)
  59. {
  60.     if(--m_Requests>0)
  61.         return m_Time;
  62.     m_RequestsLock.Lock();
  63.     if(m_Requests<=0) {
  64.         time_t x = time(0);
  65.         if(x==m_Time) {
  66.             m_Requests += m_RequestsDevider + 1;
  67.             m_RequestsDevider = m_RequestsDevider*2 + 1;
  68.         } else {
  69.             m_Requests = m_RequestsDevider / ( x - m_Time );
  70.             m_Time=x;
  71.         }
  72.     }
  73.     m_RequestsLock.Unlock();
  74.     return m_Time;
  75. }
  76. void CTimer::Start(void)
  77. {
  78.     m_TimerLock.Lock();
  79.     m_StartTime = Time();
  80. }
  81. void CTimer::Stop(void)
  82. {
  83.     time_t x = Time() - m_StartTime; // test request timing in seconds
  84.     m_ReasonableRefreshDelay = 60 /*sec*/ * 
  85.         (x==0 ? 5 /*min*/ : x*50 /* 50 min per sec of test request*/);
  86.     m_LastCalibrated = m_Time;
  87.     m_TimerLock.Unlock();
  88. }
  89. time_t CTimer::RetryTime(void)
  90. {
  91.     return Time() +
  92.         (m_ReasonableRefreshDelay>0?m_ReasonableRefreshDelay:24*60*60);
  93.     /* 24 hours */
  94. }
  95. bool CTimer::NeedCalibration(void)
  96. {
  97.     return
  98.         (m_ReasonableRefreshDelay==0) ||
  99.         (m_Time-m_LastCalibrated>100*m_ReasonableRefreshDelay);
  100. }
  101. /* =========================================================================== */
  102. // MutexPool
  103. //
  104. #if defined(NCBI_THREADS)
  105. CMutexPool::CMutexPool()
  106. {
  107.     m_size =0;
  108.     m_Locks=0;
  109.     spread =0;
  110. }
  111. void CMutexPool::SetSize(int size)
  112. {
  113.     _VERIFY(m_size==0 && !m_Locks);
  114.     m_size = size;
  115.     m_Locks = new CMutex[m_size];
  116.     spread  = new int[m_size];
  117.     for ( int i = 0; i < m_size; ++i ) {
  118.         spread[i]=0;
  119.     }
  120. }
  121. CMutexPool::~CMutexPool(void)
  122. {
  123.     delete [] m_Locks;
  124.     if ( spread )  {
  125.         for ( int i = 0; i < m_size; ++i ) {
  126.             GBLOG_POST("PoolMutex " << i << " used "<< spread[i] << " times");
  127.         }
  128.     }
  129.     delete [] spread;
  130. }
  131. #else
  132. CMutex CMutexPool::sm_Lock;
  133. #endif
  134. /* =========================================================================== */
  135. // CGBLGuard 
  136. //
  137. CGBLGuard::CGBLGuard(TLMutex& lm,EState orig,const char *loc,int select)
  138.     : m_Locks(&lm),
  139.       m_Loc(loc),
  140.       m_orig(orig),
  141.       m_current(orig),
  142.       m_select(select)
  143. {
  144. }
  145. CGBLGuard::CGBLGuard(TLMutex &lm,const char *loc)
  146.     // assume orig=eNone, switch to e.Main in constructor
  147.     : m_Locks(&lm),
  148.       m_Loc(loc),
  149.       m_orig(eNone),
  150.       m_current(eNone),
  151.       m_select(-1)
  152. {
  153.     Switch(eMain);
  154. }
  155. CGBLGuard::CGBLGuard(CGBLGuard &g,const char *loc)
  156.     : m_Locks(g.m_Locks),
  157.       m_Loc(g.m_Loc),
  158.       m_orig(g.m_current),
  159.       m_current(g.m_current),
  160.       m_select(g.m_select)
  161. {
  162.     if ( loc ) {
  163.         m_Loc = loc;
  164.     }
  165.     _VERIFY(m_Locks);
  166. }
  167. CGBLGuard::~CGBLGuard()
  168. {
  169.     Switch(m_orig);
  170. }
  171. #if defined(NCBI_THREADS)
  172. void CGBLGuard::Select(int s)
  173. {
  174.     if ( m_current==eMain ) {
  175.         m_select=s;
  176.     }
  177.     _ASSERT(m_select==s);
  178. }
  179. #define LOCK_POST(x) GBLOG_POST(x) 
  180. //#define LOCK_POST(x) 
  181. void CGBLGuard::MLock()
  182. {
  183.     LOCK_POST(&m_Locks << ":: MainLock tried   @ " << m_Loc);
  184.     m_Locks->m_Lookup.Lock();
  185.     LOCK_POST(&m_Locks << ":: MainLock locked  @ " << m_Loc);
  186. }
  187. void CGBLGuard::MUnlock()
  188. {
  189.     LOCK_POST(&m_Locks << ":: MainLock unlocked@ " << m_Loc);
  190.     m_Locks->m_Lookup.Unlock();
  191. }
  192. void CGBLGuard::PLock()
  193. {
  194.     _ASSERT(m_select>=0);
  195.     LOCK_POST(&m_Locks << ":: Pool["<< setw(2) << m_select << "] tried   @ "
  196.               << m_Loc);
  197.     m_Locks->m_Pool.GetMutex(m_select).Lock();
  198.     LOCK_POST(&m_Locks << ":: Pool["<< setw(2) << m_select << "] locked  @ "
  199.               << m_Loc);
  200. }
  201. void CGBLGuard::PUnlock()
  202. {
  203.     _ASSERT(m_select>=0);
  204.     LOCK_POST(&m_Locks << ":: Pool["<< setw(2) << m_select << "] unlocked@ "
  205.               << m_Loc);
  206.     m_Locks->m_Pool.GetMutex(m_select).Unlock();
  207. }
  208. void CGBLGuard::Switch(EState newstate)
  209. {
  210.     if(newstate==m_current) return;
  211.     switch(newstate) {
  212.     case eNone:
  213.         if ( m_current!=eMain ) {
  214.             Switch(eMain);
  215.         }
  216.         _ASSERT(m_current==eMain);
  217.         //LOCK_POST(&m_Locks << ":: switch 'main' to 'none'");
  218.         MUnlock();
  219.         m_current=eNone;
  220.         return;
  221.       
  222.     case eBoth:
  223.         if ( m_current!=eMain ) {
  224.             Switch(eMain);
  225.         }
  226.         _ASSERT(m_current==eMain);
  227.         //LOCK_POST(&m_Locks << ":: switch 'main' to 'both'");
  228.         if ( m_Locks->m_SlowTraverseMode>0 ) {
  229.             PLock();
  230.         }
  231.         m_current=eBoth;
  232.         return;
  233.       
  234.     case eLocal:
  235.         if ( m_current!=eBoth ) {
  236.             Switch(eBoth);
  237.         }
  238.         _ASSERT(m_current==eBoth);
  239.         //LOCK_POST(&m_Locks << ":: switch 'both' to 'local'");
  240.         if(m_Locks->m_SlowTraverseMode==0) {
  241.             PLock();
  242.         }
  243.         try {
  244.             m_Locks->m_SlowTraverseMode++;
  245.             MUnlock();
  246.         }
  247.         catch(...) {
  248.             m_Locks->m_SlowTraverseMode--;
  249.             if(m_Locks->m_SlowTraverseMode==0) {
  250.                 PUnlock();
  251.             }
  252.             throw;
  253.         }
  254.         m_current=eLocal;
  255.         return;
  256.     case eMain:
  257.         switch(m_current) {
  258.         case eNone:
  259.             m_select=-1;
  260.             //LOCK_POST(&m_Locks << ":: switch 'none' to 'main'");
  261.             MLock();
  262.             m_current=eMain;
  263.             return;
  264.         case eBoth:
  265.             //LOCK_POST(&m_Locks << ":: switch 'both' to 'main'");
  266.             if(m_Locks->m_SlowTraverseMode>0) {
  267.                 PUnlock();
  268.             }
  269.             m_select=-1;
  270.             m_current=eMain;
  271.             return;
  272.         case eLocal:
  273.             //LOCK_POST(&m_Locks << ":: switch 'local' to 'none2main'");
  274.             PUnlock();
  275.             m_current=eNoneToMain;
  276.         case eNoneToMain:
  277.             //LOCK_POST(&m_Locks << ":: switch 'none2main' to 'main'");
  278.             MLock();
  279.             m_Locks->m_SlowTraverseMode--;
  280.             m_select=-1;
  281.             m_current=eMain;
  282.             return;
  283.         default:
  284.             break;
  285.         }
  286.     default:
  287.         break;
  288.     }
  289.     NCBI_THROW(CLoaderException, eOtherError,
  290.         "CGBLGuard::Switch - state desynchronized");
  291. }
  292. #endif // if(NCBI_THREADS)
  293. END_SCOPE(objects)
  294. END_NCBI_SCOPE
  295. /* ---------------------------------------------------------------------------
  296. * $Log: gbload_util.cpp,v $
  297. * Revision 1000.1  2004/06/01 19:41:34  gouriano
  298. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.25
  299. *
  300. * Revision 1.25  2004/05/21 21:42:52  gorelenk
  301. * Added PCH ncbi_pch.hpp
  302. *
  303. * Revision 1.24  2004/01/13 21:54:49  vasilche
  304. * Requrrected new version
  305. *
  306. * Revision 1.2  2003/12/30 22:14:41  vasilche
  307. * Updated genbank loader and readers plugins.
  308. *
  309. * Revision 1.22  2003/12/01 23:42:27  vasilche
  310. * Temporary fix for segfault in genbank data loader in multithreaded applications.
  311. *
  312. * Revision 1.21  2003/11/26 17:55:57  vasilche
  313. * Implemented ID2 split in ID1 cache.
  314. * Fixed loading of splitted annotations.
  315. *
  316. * Revision 1.20  2003/11/21 16:33:10  vasilche
  317. * Some code formatting.
  318. *
  319. * Revision 1.19  2003/11/19 22:18:02  grichenk
  320. * All exceptions are now CException-derived. Catch "exception" rather
  321. * than "runtime_error".
  322. *
  323. * Revision 1.18  2003/10/27 15:05:41  vasilche
  324. * Added correct recovery of cached ID1 loader if gi->sat/satkey cache is invalid.
  325. * Added recognition of ID1 error codes: private, etc.
  326. * Some formatting of old code.
  327. *
  328. * Revision 1.17  2003/06/02 16:06:37  dicuccio
  329. * Rearranged src/objects/ subtree.  This includes the following shifts:
  330. *     - src/objects/asn2asn --> arc/app/asn2asn
  331. *     - src/objects/testmedline --> src/objects/ncbimime/test
  332. *     - src/objects/objmgr --> src/objmgr
  333. *     - src/objects/util --> src/objmgr/util
  334. *     - src/objects/alnmgr --> src/objtools/alnmgr
  335. *     - src/objects/flat --> src/objtools/flat
  336. *     - src/objects/validator --> src/objtools/validator
  337. *     - src/objects/cddalignview --> src/objtools/cddalignview
  338. * In addition, libseq now includes six of the objects/seq... libs, and libmmdb
  339. * replaces the three libmmdb? libs.
  340. *
  341. * Revision 1.16  2003/05/20 15:44:37  vasilche
  342. * Fixed interaction of CDataSource and CDataLoader in multithreaded app.
  343. * Fixed some warnings on WorkShop.
  344. * Added workaround for memory leak on WorkShop.
  345. *
  346. * Revision 1.15  2003/05/12 19:18:29  vasilche
  347. * Fixed locking of object manager classes in multi-threaded application.
  348. *
  349. * Revision 1.14  2003/03/03 21:12:58  vasilche
  350. * Added missing static memeber definition.
  351. *
  352. * Revision 1.13  2003/03/03 20:34:51  vasilche
  353. * Added NCBI_THREADS macro - it's opposite to NCBI_NO_THREADS.
  354. * Avoid using _REENTRANT macro - use NCBI_THREADS instead.
  355. *
  356. * Revision 1.12  2003/03/01 22:26:56  kimelman
  357. * performance fixes
  358. *
  359. * Revision 1.11  2003/02/05 17:59:17  dicuccio
  360. * Moved formerly private headers into include/objects/objmgr/impl
  361. *
  362. * Revision 1.10  2002/07/22 22:53:24  kimelman
  363. * exception handling fixed: 2level mutexing moved to Guard class + added
  364. * handling of confidential data.
  365. *
  366. * Revision 1.9  2002/05/06 03:28:47  vakatov
  367. * OM/OM1 renaming
  368. *
  369. * Revision 1.8  2002/05/03 21:28:09  ucko
  370. * Introduce T(Signed)SeqPos.
  371. *
  372. * Revision 1.7  2002/04/04 01:35:35  kimelman
  373. * more MT tests
  374. *
  375. * Revision 1.6  2002/04/02 16:02:30  kimelman
  376. * MT testing
  377. *
  378. * Revision 1.5  2002/03/29 02:47:03  kimelman
  379. * gbloader: MT scalability fixes
  380. *
  381. * Revision 1.4  2002/03/27 20:23:49  butanaev
  382. * Added connection pool.
  383. *
  384. * Revision 1.3  2002/03/20 21:24:59  gouriano
  385. * *** empty log message ***
  386. *
  387. * Revision 1.2  2002/03/20 17:03:24  gouriano
  388. * minor changes to make it compilable on MS Windows
  389. *
  390. * Revision 1.1  2002/03/20 04:50:13  kimelman
  391. * GB loader added
  392. *
  393. * ===========================================================================
  394. */