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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: test_objmgr_data_mt.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:42:16  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.2
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: test_objmgr_data_mt.cpp,v 1000.1 2004/06/01 19:42:16 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:  Andrei Gourianov
  35. *
  36. * File Description:
  37. *   Object Manager test: multiple threads working with annotations
  38. *
  39. * ---------------------------------------------------------------------------
  40. * $Log: test_objmgr_data_mt.cpp,v $
  41. * Revision 1000.1  2004/06/01 19:42:16  gouriano
  42. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.2
  43. *
  44. * Revision 1.2  2004/05/21 21:42:52  gorelenk
  45. * Added PCH ncbi_pch.hpp
  46. *
  47. * Revision 1.1  2003/12/16 17:51:18  kuznets
  48. * Code reorganization
  49. *
  50. * Revision 1.14  2003/11/26 17:56:04  vasilche
  51. * Implemented ID2 split in ID1 cache.
  52. * Fixed loading of splitted annotations.
  53. *
  54. * Revision 1.13  2003/11/03 21:21:41  vasilche
  55. * Limit amount of exceptions to catch while testing.
  56. *
  57. * Revision 1.12  2003/10/22 17:58:10  vasilche
  58. * Do not catch CLoaderException::eNoConnection.
  59. *
  60. * Revision 1.11  2003/09/30 16:22:05  vasilche
  61. * Updated internal object manager classes to be able to load ID2 data.
  62. * SNP blobs are loaded as ID2 split blobs - readers convert them automatically.
  63. * Scope caches results of requests for data to data loaders.
  64. * Optimized CSeq_id_Handle for gis.
  65. * Optimized bioseq lookup in scope.
  66. * Reduced object allocations in annotation iterators.
  67. * CScope is allowed to be destroyed before other objects using this scope are
  68. * deleted (feature iterators, bioseq handles etc).
  69. * Optimized lookup for matching Seq-ids in CSeq_id_Mapper.
  70. * Added 'adaptive' option to objmgr_demo application.
  71. *
  72. * Revision 1.10  2003/06/02 16:06:39  dicuccio
  73. * Rearranged src/objects/ subtree.  This includes the following shifts:
  74. *     - src/objects/asn2asn --> arc/app/asn2asn
  75. *     - src/objects/testmedline --> src/objects/ncbimime/test
  76. *     - src/objects/objmgr --> src/objmgr
  77. *     - src/objects/util --> src/objmgr/util
  78. *     - src/objects/alnmgr --> src/objtools/alnmgr
  79. *     - src/objects/flat --> src/objtools/flat
  80. *     - src/objects/validator --> src/objtools/validator
  81. *     - src/objects/cddalignview --> src/objtools/cddalignview
  82. * In addition, libseq now includes six of the objects/seq... libs, and libmmdb
  83. * replaces the three libmmdb? libs.
  84. *
  85. * Revision 1.9  2003/05/20 20:35:09  vasilche
  86. * Reduced number of threads to make test time reasonably small.
  87. *
  88. * Revision 1.8  2003/05/20 15:44:39  vasilche
  89. * Fixed interaction of CDataSource and CDataLoader in multithreaded app.
  90. * Fixed some warnings on WorkShop.
  91. * Added workaround for memory leak on WorkShop.
  92. *
  93. * Revision 1.7  2003/04/24 16:12:39  vasilche
  94. * Object manager internal structures are splitted more straightforward.
  95. * Removed excessive header dependencies.
  96. *
  97. * Revision 1.6  2003/04/15 14:23:11  vasilche
  98. * Added missing includes.
  99. *
  100. * Revision 1.5  2003/03/18 21:48:33  grichenk
  101. * Removed obsolete class CAnnot_CI
  102. *
  103. * Revision 1.4  2002/12/06 15:36:03  grichenk
  104. * Added overlap type for annot-iterators
  105. *
  106. * Revision 1.3  2002/07/22 22:49:05  kimelman
  107. * test fixes for confidential data retrieval
  108. *
  109. * Revision 1.2  2002/05/06 03:28:53  vakatov
  110. * OM/OM1 renaming
  111. *
  112. * Revision 1.1  2002/04/30 19:04:05  gouriano
  113. * multi-threaded data retrieval test
  114. *
  115. *
  116. * ===========================================================================
  117. */
  118. #include <ncbi_pch.hpp>
  119. #include <corelib/ncbithr.hpp>
  120. #include <corelib/test_mt.hpp>
  121. #include <connect/ncbi_util.h>
  122. #include <objects/seqloc/Seq_id.hpp>
  123. #include <objects/seqloc/Seq_loc.hpp>
  124. #include <objmgr/object_manager.hpp>
  125. #include <objmgr/objmgr_exception.hpp>
  126. #include <objmgr/scope.hpp>
  127. #include <objmgr/seq_vector.hpp>
  128. #include <objmgr/seqdesc_ci.hpp>
  129. #include <objmgr/feat_ci.hpp>
  130. #include <objmgr/align_ci.hpp>
  131. #include <objtools/data_loaders/genbank/gbloader.hpp>
  132. #include <connect/ncbi_core_cxx.hpp>
  133. #include <connect/ncbi_util.h>
  134. #include <test/test_assert.h>  /* This header must go last */
  135. BEGIN_NCBI_SCOPE
  136. using namespace objects;
  137. DEFINE_STATIC_FAST_MUTEX(s_GlobalLock);
  138. // GIs to process
  139. #if 0
  140.     const int g_gi_from = 156894;
  141.     const int g_gi_to   = 156896;
  142. #elif 0
  143.     const int g_gi_from = 156201;
  144.     const int g_gi_to   = 156203;
  145. #else
  146.     const int g_gi_from = 156000;
  147.     const int g_gi_to   = 157000;
  148. #endif
  149. /////////////////////////////////////////////////////////////////////////////
  150. //
  151. //  Test application
  152. //
  153. class CTestOM : public CThreadedApp
  154. {
  155. protected:
  156.     virtual bool Thread_Run(int idx);
  157.     virtual bool TestApp_Args( CArgDescriptions& args);
  158.     virtual bool TestApp_Init(void);
  159.     virtual bool TestApp_Exit(void);
  160.     typedef map<int, int> TValueMap;
  161.     CRef<CScope> m_Scope;
  162.     CRef<CObjectManager> m_ObjMgr;
  163.     TValueMap m_mapGiToDesc, m_mapGiToFeat0, m_mapGiToFeat1;
  164.     void SetValue(TValueMap& vm, int gi, int value);
  165.     int m_gi_from;
  166.     int m_gi_to;
  167.     bool failed;
  168. };
  169. /////////////////////////////////////////////////////////////////////////////
  170. void CTestOM::SetValue(TValueMap& vm, int gi, int value)
  171. {
  172.     int old_value;
  173.     {{
  174.         CFastMutexGuard guard(s_GlobalLock);
  175.         old_value = vm.insert(TValueMap::value_type(gi, value)).first->second;
  176.     }}
  177.     if ( old_value != value ) {
  178.         string name;
  179.         if ( &vm == &m_mapGiToDesc ) name = "desc";
  180.         if ( &vm == &m_mapGiToFeat0 ) name = "feat0";
  181.         if ( &vm == &m_mapGiToFeat1 ) name = "feat1";
  182.         ERR_POST("Inconsistent "<<name<<" on gi "<<gi<<
  183.                  " was "<<old_value<<" now "<<value);
  184.     }
  185.     _ASSERT(old_value == value);
  186. }
  187. bool CTestOM::Thread_Run(int idx)
  188. {
  189. // initialize scope
  190.     CScope scope(*m_ObjMgr);
  191.     scope.AddDefaults();
  192.     int from, to, delta;
  193.     // make them go in opposite directions
  194.     if (idx % 2 == 0) {
  195.         from = m_gi_from;
  196.         to = m_gi_to;
  197.     } else {
  198.         from = m_gi_to;
  199.         to = m_gi_from;
  200.     }
  201.     delta = (to > from) ? 1 : -1;
  202.     bool ok = true;
  203.     const int kMaxErrorCount = 3;
  204.     static int error_count = 0;
  205.     for (int i = from;
  206.         ((delta > 0) && (i <= to)) || ((delta < 0) && (i >= to)); i += delta) {
  207.         try {
  208. // load sequence
  209.             CSeq_id sid;
  210.             sid.SetGi(i);
  211.             CBioseq_Handle handle = scope.GetBioseqHandle(sid);
  212.             if (!handle) {
  213.                 LOG_POST("T" << idx << ": gi = " << i << ": INVALID HANDLE");
  214.                 SetValue(m_mapGiToDesc, i, -1);
  215.                 continue;
  216.             }
  217.             int count = 0;
  218. // enumerate descriptions
  219.             // Seqdesc iterator
  220.             for (CSeqdesc_CI desc_it(handle); desc_it;  ++desc_it) {
  221.                 count++;
  222.             }
  223. // verify result
  224.             SetValue(m_mapGiToDesc, i, count);
  225. // enumerate features
  226.             CSeq_loc loc;
  227.             loc.SetWhole(sid);
  228.             count = 0;
  229.             if ( idx%2 == 0 ) {
  230.                 for (CFeat_CI feat_it(scope, loc,
  231.                                       CSeqFeatData::e_not_set,
  232.                                       SAnnotSelector::eOverlap_Intervals,
  233.                                       CAnnotTypes_CI::eResolve_All);
  234.                     feat_it;  ++feat_it) {
  235.                     count++;
  236.                 }
  237. // verify result
  238.                 SetValue(m_mapGiToFeat0, i, count);
  239.             }
  240.             else {
  241.                 for (CFeat_CI feat_it(handle, 0, 0, CSeqFeatData::e_not_set);
  242.                     feat_it;  ++feat_it) {
  243.                     count++;
  244.                 }
  245. // verify result
  246.                 SetValue(m_mapGiToFeat1, i, count);
  247.             }
  248.         }
  249.         catch (CLoaderException& e) {
  250.             LOG_POST("T" << idx << ": gi = " << i 
  251.                 << ": EXCEPTION = " << e.what());
  252.             ok = false;
  253.             if ( e.GetErrCode() == CLoaderException::eNoConnection ) {
  254.                 break;
  255.             }
  256.             if ( ++error_count > kMaxErrorCount ) {
  257.                 break;
  258.             }
  259.         }
  260.         catch (exception& e) {
  261.             LOG_POST("T" << idx << ": gi = " << i 
  262.                 << ": EXCEPTION = " << e.what());
  263.             ok = false;
  264.             if ( ++error_count > kMaxErrorCount ) {
  265.                 break;
  266.             }
  267.         }
  268.         scope.ResetHistory();
  269.     }
  270.     if ( !ok ) {
  271.         failed = true;
  272.     }
  273.     return ok;
  274. }
  275. bool CTestOM::TestApp_Args( CArgDescriptions& args)
  276. {
  277.     args.AddDefaultKey
  278.         ("fromgi", "FromGi",
  279.          "Process sequences in the interval FROM this Gi",
  280.          CArgDescriptions::eInteger, NStr::IntToString(g_gi_from));
  281.     args.AddDefaultKey
  282.         ("togi", "ToGi",
  283.          "Process sequences in the interval TO this Gi",
  284.          CArgDescriptions::eInteger, NStr::IntToString(g_gi_to));
  285.     return true;
  286. }
  287. bool CTestOM::TestApp_Init(void)
  288. {
  289.     failed = false;
  290.     CORE_SetLOCK(MT_LOCK_cxx2c());
  291.     CORE_SetLOG(LOG_cxx2c());
  292.     const CArgs& args = GetArgs();
  293.     m_gi_from = args["fromgi"].AsInteger();
  294.     m_gi_to   = args["togi"].AsInteger();
  295.     NcbiCout << "Testing ObjectManager (" << s_NumThreads
  296.         << " threads, gi from "
  297.         << m_gi_from << " to " << m_gi_to << ")..." << NcbiEndl;
  298.     m_ObjMgr = new CObjectManager;
  299.     m_ObjMgr->RegisterDataLoader(*new CGBDataLoader("ID"),CObjectManager::eDefault);
  300.     // Scope shared by all threads
  301. /*
  302.     m_Scope = new CScope(*m_ObjMgr);
  303.     m_Scope->AddDefaults();
  304. */
  305.     return true;
  306. }
  307. bool CTestOM::TestApp_Exit(void)
  308. {
  309.     if ( failed ) {
  310.         NcbiCout << " Failed" << NcbiEndl << NcbiEndl;
  311.     }
  312.     else {
  313.         NcbiCout << " Passed" << NcbiEndl << NcbiEndl;
  314.     }
  315. /*
  316.     map<int, int>::iterator it;
  317.     for (it = m_mapGiToDesc.begin(); it != m_mapGiToDesc.end(); ++it) {
  318.         LOG_POST(
  319.             "gi = "         << it->first
  320.             << ": desc = "  << it->second
  321.             << ", feat0 = " << m_mapGiToFeat0[it->first]
  322.             << ", feat1 = " << m_mapGiToFeat1[it->first]
  323.             );
  324.     }
  325. */
  326.     return true;
  327. }
  328. END_NCBI_SCOPE
  329. /////////////////////////////////////////////////////////////////////////////
  330. //  MAIN
  331. USING_NCBI_SCOPE;
  332. int main(int argc, const char* argv[])
  333. {
  334.     s_NumThreads = 12;
  335.     return CTestOM().AppMain(argc, argv, 0, eDS_Default, 0);
  336. }