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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: reader_id1_cache.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:41:59  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.25
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: reader_id1_cache.cpp,v 1000.2 2004/06/01 19:41:59 gouriano Exp $
  10.  * ===========================================================================
  11.  *                            PUBLIC DOMAIN NOTICE
  12.  *               National Center for Biotechnology Information
  13.  *
  14.  *  This software/database is a "United States Government Work" under the
  15.  *  terms of the United States Copyright Act.  It was written as part of
  16.  *  the author's official duties as a United States Government employee and
  17.  *  thus cannot be copyrighted.  This software/database is freely available
  18.  *  to the public for use. The National Library of Medicine and the U.S.
  19.  *  Government have not placed any restriction on its use or reproduction.
  20.  *
  21.  *  Although all reasonable efforts have been taken to ensure the accuracy
  22.  *  and reliability of the software and data, the NLM and the U.S.
  23.  *  Government do not and cannot warrant the performance or results that
  24.  *  may be obtained by using this software or data. The NLM and the U.S.
  25.  *  Government disclaim all warranties, express or implied, including
  26.  *  warranties of performance, merchantability or fitness for any particular
  27.  *  purpose.
  28.  *
  29.  *  Please cite the author in any work or product based on this material.
  30.  *
  31.  * ===========================================================================
  32.  *
  33.  *  Author:  Eugene Vasilchenko, Anatoliy Kuznetsov
  34.  *
  35.  *  File Description: Cached extension of data reader from ID1
  36.  *
  37.  */
  38. #include <ncbi_pch.hpp>
  39. #include <objtools/data_loaders/genbank/readers/id1/reader_id1_cache.hpp>
  40. #include <objtools/data_loaders/genbank/reader_snp.hpp>
  41. #include <objtools/data_loaders/genbank/split_parser.hpp>
  42. #include <corelib/ncbitime.hpp>
  43. #include <util/cache/blob_cache.hpp>
  44. #include <util/cache/int_cache.hpp>
  45. #include <util/cache/icache.hpp>
  46. #include <util/rwstream.hpp>
  47. #include <util/bytesrc.hpp>
  48. #include <serial/objistr.hpp>
  49. #include <serial/objistrasnb.hpp>
  50. #include <serial/objostrasnb.hpp>
  51. #include <objmgr/objmgr_exception.hpp>
  52. #include <objmgr/impl/snp_annot_info.hpp>
  53. #include <objmgr/impl/tse_chunk_info.hpp>
  54. #include <util/compress/reader_zlib.hpp>
  55. #include <connect/ncbi_conn_stream.hpp>
  56. #include <objects/seqset/Seq_entry.hpp>
  57. #include <objects/seqsplit/ID2S_Split_Info.hpp>
  58. #include <objects/seqsplit/ID2S_Chunk_Info.hpp>
  59. #include <objects/seqsplit/ID2S_Chunk.hpp>
  60. #include <objects/seqsplit/ID2S_Chunk_Id.hpp>
  61. #include <objects/id1/id1__.hpp>
  62. #include <objects/id2/ID2_Reply_Data.hpp>
  63. #include <serial/serial.hpp>
  64. #include <stdio.h>
  65. BEGIN_NCBI_SCOPE
  66. BEGIN_SCOPE(objects)
  67. /// Utility function to skip part of the input byte source
  68. void Id1ReaderSkipBytes(CByteSourceReader& reader, size_t to_skip);
  69. static size_t resolve_id_count = 0;
  70. static double resolve_id_time = 0;
  71. static size_t resolve_gi_count = 0;
  72. static double resolve_gi_time = 0;
  73. static size_t resolve_ver_count = 0;
  74. static double resolve_ver_time = 0;
  75. static size_t main_blob_count = 0;
  76. static double main_bytes = 0;
  77. static double main_time = 0;
  78. static size_t chunk_blob_count = 0;
  79. static double chunk_bytes = 0;
  80. static double chunk_time = 0;
  81. static size_t snp_load_count = 0;
  82. static double snp_load_bytes = 0;
  83. static double snp_load_time = 0;
  84. static size_t snp_store_count = 0;
  85. static double snp_store_bytes = 0;
  86. static double snp_store_time = 0;
  87. CCachedId1Reader::CCachedId1Reader(TConn noConn, 
  88.                                    IBLOB_Cache* blob_cache,
  89.                                    IIntCache* id_cache)
  90.     : CId1Reader(noConn),
  91.       m_BlobCache(0), m_IdCache(0),
  92.       m_OldBlobCache(0), m_OldIdCache(0)
  93. {
  94.     SetBlobCache(blob_cache);
  95.     SetIdCache(id_cache);
  96. }
  97. CCachedId1Reader::CCachedId1Reader(TConn noConn, 
  98.                                    ICache* blob_cache,
  99.                                    ICache* id_cache)
  100.     : CId1Reader(noConn),
  101.       m_BlobCache(0), m_IdCache(0),
  102.       m_OldBlobCache(0), m_OldIdCache(0)
  103. {
  104.     SetBlobCache(blob_cache);
  105.     SetIdCache(id_cache);
  106. }
  107. CCachedId1Reader::~CCachedId1Reader()
  108. {
  109.     if ( CollectStatistics() ) {
  110.         PrintStatistics();
  111.     }
  112. }
  113. void CCachedId1Reader::PrintStatistics(void) const
  114. {
  115.     PrintStat("Cache resolution: resolved",
  116.                 resolve_id_count, "ids", resolve_id_time);
  117.     PrintStat("Cache resolution: resolved",
  118.                 resolve_gi_count, "gis", resolve_gi_time);
  119.     PrintStat("Cache resolution: resolved",
  120.               resolve_ver_count, "blob vers", resolve_ver_time);
  121.     PrintBlobStat("Cache main: loaded",
  122.                   main_blob_count, main_bytes, main_time);
  123.     PrintBlobStat("Cache chunk: loaded",
  124.                   chunk_blob_count, chunk_bytes, chunk_time);
  125.     PrintBlobStat("Cache SNP: loaded",
  126.                   snp_load_count, snp_load_bytes, snp_load_time);
  127.     PrintBlobStat("Cache SNP: stored",
  128.                   snp_store_count, snp_store_bytes, snp_store_time);
  129. }
  130. void CCachedId1Reader::SetBlobCache(ICache* blob_cache)
  131. {
  132.     m_OldBlobCache = 0;
  133.     m_BlobCache = blob_cache;
  134. }
  135. void CCachedId1Reader::SetIdCache(ICache* id_cache)
  136. {
  137.     m_OldIdCache = 0;
  138.     m_IdCache = id_cache;
  139. }
  140. void CCachedId1Reader::SetBlobCache(IBLOB_Cache* blob_cache)
  141. {
  142.     m_BlobCache = 0;
  143.     if ( blob_cache && blob_cache != m_OldBlobCache ) {
  144.         ERR_POST(Warning << "CCachedId1Reader: "
  145.                  "IBLOB_Cache is deprecated, use ICache instead");
  146.     }
  147.     m_OldBlobCache = blob_cache;
  148. }
  149. void CCachedId1Reader::SetIdCache(IIntCache* id_cache)
  150. {
  151.     m_IdCache = 0;
  152.     if ( id_cache && id_cache != m_OldIdCache ) {
  153.         ERR_POST(Warning << "CCachedId1Reader: "
  154.                  "IIntCache is deprecated, use ICache instead");
  155.     }
  156.     m_OldIdCache = id_cache;
  157. }
  158. string CCachedId1Reader::GetBlobKey(const CSeqref& seqref) const
  159. {
  160.     int sat = seqref.GetSat();
  161.     int sat_key = seqref.GetSatKey();
  162.     char szBlobKeyBuf[256];
  163.     sprintf(szBlobKeyBuf, "%i-%i", sat, sat_key);
  164.     return szBlobKeyBuf;
  165. }
  166. string CCachedId1Reader::GetIdKey(int gi) const
  167. {
  168.     return NStr::IntToString(gi);
  169. }
  170. string CCachedId1Reader::GetIdKey(const CSeq_id& id) const
  171. {
  172.     return id.IsGi()? GetIdKey(id.GetGi()): id.AsFastaString();
  173. }
  174. const char* CCachedId1Reader::GetSeqrefsSubkey(void) const
  175. {
  176.     return "srs";
  177. }
  178. const char* CCachedId1Reader::GetGiSubkey(void) const
  179. {
  180.     return "gi";
  181. }
  182. const char* CCachedId1Reader::GetBlobVersionSubkey(void) const
  183. {
  184.     return "ver";
  185. }
  186. const char* CCachedId1Reader::GetSeqEntrySubkey(void) const
  187. {
  188.     return "Seq-entry";
  189. }
  190. const char* CCachedId1Reader::GetSNPTableSubkey(void) const
  191. {
  192.     return "SNP table";
  193. }
  194. const char* CCachedId1Reader::GetSkeletonSubkey(void) const
  195. {
  196.     return "Skeleton";
  197. }
  198. const char* CCachedId1Reader::GetSplitInfoSubkey(void) const
  199. {
  200.     return "ID2S-Split-Info";
  201. }
  202. string CCachedId1Reader::GetChunkSubkey(int chunk_id) const
  203. {
  204.     return "ID2S-Chunk "+NStr::IntToString(chunk_id);
  205. }
  206. void CCachedId1Reader::PurgeSeqrefs(const TSeqrefs& srs, const CSeq_id& id)
  207. {
  208.     if ( m_IdCache ) {
  209.         m_IdCache->Remove(GetIdKey(id));
  210.         ITERATE ( TSeqrefs, it, srs ) {
  211.             const CSeqref& sr = **it;
  212.             m_IdCache->Remove(GetBlobKey(sr));
  213.         }
  214.     }
  215.     else if ( m_OldIdCache ) {
  216.         ITERATE ( TSeqrefs, it, srs ) {
  217.             const CSeqref& sr = **it;
  218.             m_OldIdCache->Remove(sr.GetGi(), 0);
  219.             m_OldIdCache->Remove(sr.GetSatKey(), sr.GetSat());
  220.         }
  221.     }
  222. }
  223. bool CCachedId1Reader::x_GetIdCache(const string& key,
  224.                                     const string& subkey,
  225.                                     vector<int>& ints)
  226. {
  227.     CStopWatch sw;
  228.     if ( CollectStatistics() ) {
  229.         sw.Start();
  230.     }
  231.     size_t size = m_IdCache->GetSize(key, 0, subkey);
  232.     ints.resize(size / sizeof(int));
  233.     if ( size == 0 || size % sizeof(int) != 0 ||
  234.          !m_IdCache->Read(key, 0, subkey, &ints[0], size) ) {
  235.         if ( CollectStatistics() ) {
  236.             double time = sw.Elapsed();
  237.             LogStat("CId1Cache: failed to read id cache record for id",
  238.                     key, subkey, time);
  239.             resolve_id_count++;
  240.             resolve_id_time += time;
  241.         }
  242.         return false;
  243.     }
  244.     if ( CollectStatistics() ) {
  245.         double time = sw.Elapsed();
  246.         LogStat("CId1Cache: resolved id", key, subkey, time);
  247.         resolve_id_count++;
  248.         resolve_id_time += time;
  249.     }
  250.     return true;
  251. }
  252. bool CCachedId1Reader::x_GetIdCache(const string& key,
  253.                                     const string& subkey,
  254.                                     int& value)
  255. {
  256.     CStopWatch sw;
  257.     if ( CollectStatistics() ) {
  258.         sw.Start();
  259.     }
  260.     size_t size = m_IdCache->GetSize(key, 0, subkey);
  261.     if ( size != sizeof(int) ||
  262.          !m_IdCache->Read(key, 0, subkey, &value, size) ) {
  263.         if ( CollectStatistics() ) {
  264.             double time = sw.Elapsed();
  265.             LogStat("CId1Cache: failed to read id cache record for id",
  266.                     key, subkey, time);
  267.             resolve_id_count++;
  268.             resolve_id_time += time;
  269.         }
  270.         return false;
  271.     }
  272.     if ( CollectStatistics() ) {
  273.         double time = sw.Elapsed();
  274.         LogStat("CId1Cache: resolved id", key, subkey, time);
  275.         resolve_id_count++;
  276.         resolve_id_time += time;
  277.     }
  278.     return true;
  279. }
  280. void CCachedId1Reader::x_StoreIdCache(const string& key,
  281.                                       const string& subkey,
  282.                                       const vector<int>& ints)
  283. {
  284.     CStopWatch sw;
  285.     if ( CollectStatistics() ) {
  286.         sw.Start();
  287.     }
  288.     
  289.     m_IdCache->Store(key, 0, subkey, &ints[0], ints.size()*sizeof(int));
  290.     
  291.     if ( CollectStatistics() ) {
  292.         double time = sw.Elapsed();
  293.         LogStat("CId1Cache: stored id", key, subkey, time);
  294.         resolve_id_count++;
  295.         resolve_id_time += time;
  296.     }
  297. }
  298. void CCachedId1Reader::x_StoreIdCache(const string& key,
  299.                                       const string& subkey,
  300.                                       const int& value)
  301. {
  302.     CStopWatch sw;
  303.     if ( CollectStatistics() ) {
  304.         sw.Start();
  305.     }
  306.     
  307.     m_IdCache->Store(key, 0, subkey, &value, sizeof(value));
  308.     
  309.     if ( CollectStatistics() ) {
  310.         double time = sw.Elapsed();
  311.         LogStat("CId1Cache: stored id", key, subkey, time);
  312.         resolve_id_count++;
  313.         resolve_id_time += time;
  314.     }
  315. }
  316. bool CCachedId1Reader::GetSeqrefs(const string& key, TSeqrefs& srs)
  317. {
  318.     vector<int> data;
  319.     if ( !x_GetIdCache(key, GetSeqrefsSubkey(), data) ) {
  320.         return false;
  321.     }
  322.     if ( data.size() % 5 != 0 || data.size() > 50 ) {
  323.         return false;
  324.     }
  325.     ITERATE ( vector<int>, it, data ) {
  326.         int gi      = *it++;
  327.         int sat     = *it++;
  328.         int satkey  = *it++;
  329.         int version = *it++;
  330.         int flags   = *it;
  331.         CRef<CSeqref> sr(new CSeqref(gi, sat, satkey));
  332.         sr->SetVersion(version);
  333.         sr->SetFlags(flags);
  334.         srs.push_back(sr);
  335.     }
  336.     return true;
  337. }
  338. void CCachedId1Reader::StoreSeqrefs(const string& key, const TSeqrefs& srs)
  339. {
  340.     vector<int> data;
  341.     ITERATE ( TSeqrefs, it, srs ) {
  342.         const CSeqref& sr = **it;
  343.         data.push_back(sr.GetGi());
  344.         data.push_back(sr.GetSat());
  345.         data.push_back(sr.GetSatKey());
  346.         data.push_back(sr.GetVersion());
  347.         data.push_back(sr.GetFlags());
  348.     }
  349.     x_StoreIdCache(key, GetSeqrefsSubkey(), data);
  350. }
  351. bool CCachedId1Reader::GetSeqrefs(int gi, TSeqrefs& srs)
  352. {
  353.     if ( m_IdCache ) {
  354.         return GetSeqrefs(GetIdKey(gi), srs);
  355.     }
  356.     else if ( m_OldIdCache) {
  357.         CStopWatch sw;
  358.         if ( CollectStatistics() ) {
  359.             sw.Start();
  360.         }
  361.         vector<int> data;
  362.         if ( !m_OldIdCache->Read(gi, 0, data) ) {
  363.             if ( CollectStatistics() ) {
  364.                 double time = sw.Elapsed();
  365.                 LogStat("CId1Cache: failed to resolve gi", gi, time);
  366.                 resolve_gi_count++;
  367.                 resolve_gi_time += time;
  368.             }
  369.             return false;
  370.         }
  371.     
  372.         _ASSERT(data.size() == 4 || data.size() == 8);
  373.         for ( size_t pos = 0; pos + 4 <= data.size(); pos += 4 ) {
  374.             int sat = data[pos];
  375.             int satkey = data[pos+1];
  376.             int version = data[pos+2];
  377.             int flags = data[pos+3];
  378.             CRef<CSeqref> sr(new CSeqref(gi, sat, satkey));
  379.             sr->SetVersion(version);
  380.             sr->SetFlags(flags);
  381.             srs.push_back(sr);
  382.         }
  383.         if ( CollectStatistics() ) {
  384.             double time = sw.Elapsed();
  385.             LogStat("CId1Cache: resolved gi", gi, time);
  386.             resolve_gi_count++;
  387.             resolve_gi_time += time;
  388.         }
  389.         return true;
  390.     }
  391.     else {
  392.         return false;
  393.     }
  394. }
  395. void CCachedId1Reader::StoreSeqrefs(int gi, const TSeqrefs& srs)
  396. {
  397.     if ( m_IdCache ) {
  398.         StoreSeqrefs(GetIdKey(gi), srs);
  399.     }
  400.     else if ( m_OldIdCache ) {
  401.         CStopWatch sw;
  402.         if ( CollectStatistics() ) {
  403.             sw.Start();
  404.         }
  405.         vector<int> data;
  406.         ITERATE ( TSeqrefs, it, srs ) {
  407.             const CSeqref& sr = **it;
  408.             data.push_back(sr.GetSat());
  409.             data.push_back(sr.GetSatKey());
  410.             data.push_back(sr.GetVersion());
  411.             data.push_back(sr.GetFlags());
  412.         }
  413.         _ASSERT(data.size() == 4 || data.size() == 8);
  414.         m_OldIdCache->Store(gi, 0, data);
  415.         if ( CollectStatistics() ) {
  416.             double time = sw.Elapsed();
  417.             LogStat("CId1Cache: saved gi", gi, time);
  418.             resolve_gi_count++;
  419.             resolve_gi_time += time;
  420.         }
  421.     }
  422. }
  423. bool CCachedId1Reader::GetSeqrefs(const CSeq_id& id, TSeqrefs& srs)
  424. {
  425.     if ( m_IdCache ) {
  426.         return GetSeqrefs(GetIdKey(id), srs);
  427.     }
  428.     else {
  429.         return false;
  430.     }
  431. }
  432. void CCachedId1Reader::StoreSeqrefs(const CSeq_id& id, const TSeqrefs& srs)
  433. {
  434.     if ( m_IdCache ) {
  435.         StoreSeqrefs(GetIdKey(id), srs);
  436.     }
  437. }
  438. int CCachedId1Reader::GetBlobVersion(const CSeqref& seqref)
  439. {
  440.     if ( m_IdCache ) {
  441.         int version = 0;
  442.         if ( x_GetIdCache(GetBlobKey(seqref),
  443.                           GetBlobVersionSubkey(),
  444.                           version) ) {
  445.             return version;
  446.         }
  447.     }
  448.     else if ( m_OldIdCache ) {
  449.         CStopWatch sw;
  450.         if ( CollectStatistics() ) {
  451.             sw.Start();
  452.         }
  453.         vector<int> data;
  454.         if ( !m_OldIdCache->Read(seqref.GetSatKey(), seqref.GetSat(), data) ) {
  455.             if ( CollectStatistics() ) {
  456.                 double time = sw.Elapsed();
  457.                 LogStat("CId1Cache: failed to get blob version",
  458.                         seqref.printTSE(), time);
  459.                 resolve_ver_count++;
  460.                 resolve_ver_time += time;
  461.             }
  462.             return 0;
  463.         }
  464.     
  465.         _ASSERT(data.size() == 1);
  466.         if ( CollectStatistics() ) {
  467.             double time = sw.Elapsed();
  468.             LogStat("CId1Cache: got blob version", seqref.printTSE(), time);
  469.             resolve_ver_count++;
  470.             resolve_ver_time += time;
  471.         }
  472.         return data[0];
  473.     }
  474.     return 0;
  475. }
  476. void CCachedId1Reader::StoreBlobVersion(const CSeqref& seqref, int version)
  477. {
  478.     if ( m_IdCache ) {
  479.         x_StoreIdCache(GetBlobKey(seqref),
  480.                        GetBlobVersionSubkey(),
  481.                        version);
  482.     }
  483.     else if ( m_OldIdCache ) {
  484.         CStopWatch sw;
  485.         if ( CollectStatistics() ) {
  486.             sw.Start();
  487.         }
  488.         vector<int> data;
  489.         data.push_back(version);
  490.         _ASSERT(data.size() == 1);
  491.         m_OldIdCache->Store(seqref.GetSatKey(), seqref.GetSat(), data);
  492.         if ( CollectStatistics() ) {
  493.             double time = sw.Elapsed();
  494.             LogStat("CId1Cache: saved blob version", seqref.printTSE(), time);
  495.             resolve_ver_count++;
  496.             resolve_ver_time += time;
  497.         }
  498.     }
  499. }
  500. int CCachedId1Reader::ResolveSeq_id_to_gi(const CSeq_id& id, TConn conn)
  501. {
  502.     if ( m_IdCache ) {
  503.         int gi = 0;
  504.         string key = GetIdKey(id);
  505.         string subkey = GetGiSubkey();
  506.         if ( !x_GetIdCache(key, subkey, gi) ) {
  507.             gi = CId1Reader::ResolveSeq_id_to_gi(id, conn);
  508.             x_StoreIdCache(key, subkey, gi);
  509.         }
  510.         return gi;
  511.     }
  512.     else {
  513.         return CId1Reader::ResolveSeq_id_to_gi(id, conn);
  514.     }
  515. }
  516. void CCachedId1Reader::RetrieveSeqrefs(TSeqrefs& srs, int gi, TConn conn)
  517. {
  518.     if ( !GetSeqrefs(gi, srs) ) {
  519.         CId1Reader::RetrieveSeqrefs(srs, gi, conn);
  520.         StoreSeqrefs(gi, srs);
  521.     }
  522. }
  523. void CCachedId1Reader::GetTSEChunk(const CSeqref& seqref,
  524.                                    CTSE_Chunk_Info& chunk_info,
  525.                                    TConn /*conn*/)
  526. {
  527.     if ( m_BlobCache ) {
  528.         CID2_Reply_Data chunk_data;
  529.         string key = GetBlobKey(seqref);
  530.         string subkey = GetChunkSubkey(chunk_info.GetChunkId());
  531.         if ( !LoadData(key, seqref.GetVersion(), subkey.c_str(),
  532.                        chunk_data) ) {
  533.             NCBI_THROW(CLoaderException, eLoaderFailed,
  534.                        "CCachedId1Reader::GetTSEChunk: chunk is missing");
  535.         }
  536.         CRef<CID2S_Chunk> chunk(new CID2S_Chunk);
  537.         size_t size = 0;
  538.         {{
  539.             CRef<CByteSourceReader> reader = GetReader(chunk_data,
  540.                                                        eDataType_Chunk);
  541.             AutoPtr<CObjectIStream> in(OpenData(chunk_data, *reader));
  542.             CReader::SetSeqEntryReadHooks(*in);
  543.             *in >> *chunk;
  544.             size = in->GetStreamOffset();
  545.         }}
  546.         CSplitParser::Load(chunk_info, *chunk);
  547.     
  548.         // everything is fine
  549.     }
  550.     else if ( m_OldBlobCache ) {
  551.         CStopWatch sw;
  552.         if ( CollectStatistics() ) {
  553.             sw.Start();
  554.         }
  555.         CID2_Reply_Data chunk_data;
  556.         string key = GetBlobKey(seqref);
  557.         string suffix = "-chunk-"+NStr::IntToString(chunk_info.GetChunkId());
  558.         if ( !LoadData(key, suffix.c_str(), seqref.GetVersion(),
  559.                        chunk_data) ) {
  560.             NCBI_THROW(CLoaderException, eLoaderFailed,
  561.                        "CCachedId1Reader::GetTSEChunk: chunk is missing");
  562.         }
  563.         CRef<CID2S_Chunk> chunk(new CID2S_Chunk);
  564.         size_t size = 0;
  565.         {{
  566.             CRef<CByteSourceReader> reader = GetReader(chunk_data,
  567.                                                        eDataType_Chunk);
  568.             AutoPtr<CObjectIStream> in(OpenData(chunk_data, *reader));
  569.             CReader::SetSeqEntryReadHooks(*in);
  570.             *in >> *chunk;
  571.             size = in->GetStreamOffset();
  572.         }}
  573.         CSplitParser::Load(chunk_info, *chunk);
  574.     
  575.         // everything is fine
  576.         if ( CollectStatistics() ) {
  577.             double time = sw.Elapsed();
  578.             LogBlobStat("CId1Cache: read chunk", seqref, size, time);
  579.             chunk_blob_count++;
  580.             chunk_bytes += size;
  581.             chunk_time += time;
  582.         }
  583.     }
  584.     else {
  585.     }
  586. }
  587. int CCachedId1Reader::x_GetVersion(const CSeqref& seqref, TConn conn)
  588. {
  589.     int version = GetBlobVersion(seqref);
  590.     if ( version == 0 ) {
  591.         version = CId1Reader::x_GetVersion(seqref, conn);
  592.         _ASSERT(version != 0);
  593.         StoreBlobVersion(seqref, version);
  594.     }
  595.     return version;
  596. }
  597. void CCachedId1Reader::x_GetTSEBlob(CID1server_back& id1_reply,
  598.                                     CRef<CID2S_Split_Info>& split_info,
  599.                                     const CSeqref& seqref,
  600.                                     TConn conn)
  601. {
  602.     // update seqref's version
  603.     GetVersion(seqref, conn);
  604.     if ( !LoadBlob(id1_reply, split_info, seqref) ) {
  605.         // we'll intercept loading deeper and write loaded data on the fly
  606.         CId1Reader::x_GetTSEBlob(id1_reply, split_info, seqref, conn);
  607.     }
  608. }
  609. void CCachedId1Reader::x_ReadTSEBlob(CID1server_back& id1_reply,
  610.                                      const CSeqref& seqref,
  611.                                      CNcbiIstream& stream)
  612. {
  613.     if ( m_BlobCache ) {
  614.         string key = GetBlobKey(seqref);
  615.         int ver = seqref.GetVersion();
  616.         string subkey = GetSeqEntrySubkey();
  617.         try {
  618.             auto_ptr<IWriter> writer(
  619.                 m_BlobCache->GetWriteStream(key, ver, subkey));
  620.             
  621.             if ( writer.get() ) {
  622.                 {{
  623.                     CWriterByteSourceReader proxy(&stream, writer.get());
  624.                     
  625.                     CObjectIStreamAsnBinary obj_stream(proxy);
  626.                     
  627.                     CStreamDelayBufferGuard guard(obj_stream);
  628.                     
  629.                     CId1Reader::x_ReadTSEBlob(id1_reply, obj_stream);
  630.                 }}
  631.                 writer->Flush();
  632.                 // everything is fine
  633.                 return;
  634.             }
  635.         }
  636.         catch ( ... ) {
  637.             // In case of an error we need to remove incomplete BLOB
  638.             // from the cache.
  639.             try {
  640.                 m_BlobCache->Remove(key);
  641.             }
  642.             catch ( exception& /*exc*/ ) {
  643.                 // ignored
  644.             }
  645.             // continue with exception
  646.             throw;
  647.         }
  648.     }
  649.     else if ( m_OldBlobCache ) {
  650.         string key = GetBlobKey(seqref);
  651.         int version = seqref.GetVersion();
  652.         try {
  653.             auto_ptr<IWriter> writer(m_OldBlobCache->GetWriteStream(key,
  654.                                                                     version));
  655.             
  656.             if ( writer.get() ) {
  657.                 {{
  658.                     CWriterByteSourceReader proxy(&stream, writer.get());
  659.                     
  660.                     CObjectIStreamAsnBinary obj_stream(proxy);
  661.                     
  662.                     CStreamDelayBufferGuard guard(obj_stream);
  663.                     
  664.                     CId1Reader::x_ReadTSEBlob(id1_reply, obj_stream);
  665.                 }}
  666.                 writer->Flush();
  667.                 writer.reset();
  668.                 // everything is fine
  669.                 return;
  670.             }
  671.         }
  672.         catch ( ... ) {
  673.             // In case of an error we need to remove incomplete BLOB
  674.             // from the cache.
  675.             try {
  676.                 m_OldBlobCache->Remove(key);
  677.             }
  678.             catch ( exception& /*exc*/ ) {
  679.                 // ignored
  680.             }
  681.             // continue with exception
  682.             throw;
  683.         }
  684.     }
  685.     // by deault read from ID1
  686.     CId1Reader::x_ReadTSEBlob(id1_reply, seqref, stream);
  687. }
  688. void CCachedId1Reader::x_GetSNPAnnot(CSeq_annot_SNP_Info& snp_info,
  689.                                      const CSeqref& seqref,
  690.                                      TConn conn)
  691. {
  692.     // update seqref's version
  693.     GetVersion(seqref, conn);
  694.     if ( !LoadSNPTable(snp_info, seqref) ) {
  695.         snp_info.Reset();
  696.         // load SNP table from GenBank
  697.         CId1Reader::x_GetSNPAnnot(snp_info, seqref, conn);
  698.         // and store SNP table in cache
  699.         StoreSNPTable(snp_info, seqref);
  700.     }
  701. }
  702. bool CCachedId1Reader::LoadBlob(CID1server_back& id1_reply,
  703.                                 CRef<CID2S_Split_Info>& split_info,
  704.                                 const CSeqref& seqref)
  705. {
  706.     return LoadSplitBlob(id1_reply, split_info, seqref) ||
  707.         LoadWholeBlob(id1_reply, seqref);
  708. }
  709. bool CCachedId1Reader::LoadWholeBlob(CID1server_back& id1_reply,
  710.                                      const CSeqref& seqref)
  711. {
  712.     if ( m_BlobCache ) {
  713.         string key = GetBlobKey(seqref);
  714.         int ver = seqref.GetVersion();
  715.         string subkey = GetSeqEntrySubkey();
  716.         CStopWatch sw;
  717.         if ( CollectStatistics() ) {
  718.             sw.Start();
  719.         }
  720.         try {
  721.             auto_ptr<IReader> reader(
  722.                 m_BlobCache->GetReadStream(key, ver, subkey));
  723.             if ( !reader.get() ) {
  724.                 return false;
  725.             }
  726.             CIRByteSourceReader rd(reader.get());
  727.         
  728.             CObjectIStreamAsnBinary in(rd);
  729.         
  730.             CReader::SetSeqEntryReadHooks(in);
  731.             in >> id1_reply;
  732.         
  733.             // everything is fine
  734.             if ( CollectStatistics() ) {
  735.                 double time = sw.Elapsed();
  736.                 size_t size = in.GetStreamOffset();
  737.                 LogBlobStat("CId1Cache: read blob", seqref, size, time);
  738.                 main_blob_count++;
  739.                 main_bytes += size;
  740.                 main_time += time;
  741.             }
  742.             return true;
  743.         }
  744.         catch ( exception& exc ) {
  745.             ERR_POST("CId1Cache: Exception while loading cached blob: " <<
  746.                      seqref.printTSE() << ": " << exc.what());
  747.             if ( CollectStatistics() ) {
  748.                 double time = sw.Elapsed();
  749.                 LogBlobStat("CId1Cache: read fail blob",
  750.                             seqref, 0, time);
  751.                 main_blob_count++;
  752.                 main_time += time;
  753.             }
  754.             return false;
  755.         }
  756.     }
  757.     else if ( m_OldBlobCache ) {
  758.         string key = GetBlobKey(seqref);
  759.         int ver = seqref.GetVersion();
  760.         CStopWatch sw;
  761.         if ( CollectStatistics() ) {
  762.             sw.Start();
  763.         }
  764.         try {
  765.             auto_ptr<IReader> reader(m_OldBlobCache->GetReadStream(key, ver));
  766.             if ( !reader.get() ) {
  767.                 return false;
  768.             }
  769.             CIRByteSourceReader rd(reader.get());
  770.         
  771.             CObjectIStreamAsnBinary in(rd);
  772.         
  773.             CReader::SetSeqEntryReadHooks(in);
  774.             in >> id1_reply;
  775.         
  776.             // everything is fine
  777.             if ( CollectStatistics() ) {
  778.                 double time = sw.Elapsed();
  779.                 size_t size = in.GetStreamOffset();
  780.                 LogBlobStat("CId1Cache: read blob", seqref, size, time);
  781.                 main_blob_count++;
  782.                 main_bytes += size;
  783.                 main_time += time;
  784.             }
  785.             return true;
  786.         }
  787.         catch ( exception& exc ) {
  788.             ERR_POST("CId1Cache: Exception while loading cached blob: " <<
  789.                      seqref.printTSE() << ": " << exc.what());
  790.             if ( CollectStatistics() ) {
  791.                 double time = sw.Elapsed();
  792.                 LogBlobStat("CId1Cache: read fail blob",
  793.                             seqref, 0, time);
  794.                 main_blob_count++;
  795.                 main_time += time;
  796.             }
  797.             return false;
  798.         }
  799.     }
  800.     else {
  801.         return false;
  802.     }
  803. }
  804. bool CCachedId1Reader::LoadSplitBlob(CID1server_back& id1_reply,
  805.                                      CRef<CID2S_Split_Info>& split_info,
  806.                                      const CSeqref& seqref)
  807. {
  808.     if ( m_BlobCache ) {
  809.         string key = GetBlobKey(seqref);
  810.         int ver = seqref.GetVersion();
  811.         try {
  812.             CID2_Reply_Data main_data, split_data;
  813.             if ( !LoadData(key, ver, GetSkeletonSubkey(), main_data) ||
  814.                  !LoadData(key, ver, GetSplitInfoSubkey(), split_data) ) {
  815.                 return false;
  816.             }
  817.             size_t size = 0;
  818.             CRef<CSeq_entry> main(new CSeq_entry);
  819.             {{
  820.                 CRef<CByteSourceReader> reader(GetReader(main_data,
  821.                                                          eDataType_MainBlob));
  822.                 AutoPtr<CObjectIStream> in(OpenData(main_data, *reader));
  823.                 CReader::SetSeqEntryReadHooks(*in);
  824.                 *in >> *main;
  825.                 size += in->GetStreamOffset();
  826.             }}
  827.             CRef<CID2S_Split_Info> split(new CID2S_Split_Info);
  828.             {{
  829.                 CRef<CByteSourceReader> reader(GetReader(split_data,
  830.                                                          eDataType_SplitInfo));
  831.                 AutoPtr<CObjectIStream> in(OpenData(split_data, *reader));
  832.                 CReader::SetSeqEntryReadHooks(*in);
  833.                 *in >> *split;
  834.                 size += in->GetStreamOffset();
  835.             }}
  836.         
  837.             id1_reply.SetGotseqentry(*main);
  838.             split_info = split;
  839.             // everything is fine
  840.             return true;
  841.         }
  842.         catch ( exception& exc ) {
  843.             ERR_POST("CId1Cache: Exception while loading cached blob: " <<
  844.                      seqref.printTSE() << ": " << exc.what());
  845.             return false;
  846.         }
  847.         return false;
  848.     }
  849.     else if ( m_OldBlobCache ) {
  850.         string key = GetBlobKey(seqref);
  851.         int ver = seqref.GetVersion();
  852.         CStopWatch sw;
  853.         if ( CollectStatistics() ) {
  854.             sw.Start();
  855.         }
  856.         try {
  857.             CID2_Reply_Data main_data, split_data;
  858.             if ( !LoadData(key, "-main", ver, main_data) ||
  859.                  !LoadData(key, "-split", ver, split_data) ) {
  860.                 return false;
  861.             }
  862.             size_t size = 0;
  863.             CRef<CSeq_entry> main(new CSeq_entry);
  864.             {{
  865.                 CRef<CByteSourceReader> reader(GetReader(main_data,
  866.                                                          eDataType_MainBlob));
  867.                 AutoPtr<CObjectIStream> in(OpenData(main_data, *reader));
  868.                 CReader::SetSeqEntryReadHooks(*in);
  869.                 *in >> *main;
  870.                 size += in->GetStreamOffset();
  871.             }}
  872.             CRef<CID2S_Split_Info> split(new CID2S_Split_Info);
  873.             {{
  874.                 CRef<CByteSourceReader> reader(GetReader(split_data,
  875.                                                          eDataType_SplitInfo));
  876.                 AutoPtr<CObjectIStream> in(OpenData(split_data, *reader));
  877.                 CReader::SetSeqEntryReadHooks(*in);
  878.                 *in >> *split;
  879.                 size += in->GetStreamOffset();
  880.             }}
  881.         
  882.             id1_reply.SetGotseqentry(*main);
  883.             split_info = split;
  884.             // everything is fine
  885.             if ( CollectStatistics() ) {
  886.                 double time = sw.Elapsed();
  887.                 LogBlobStat("CId1Cache: read blob", seqref, size, time);
  888.                 main_blob_count++;
  889.                 main_bytes += size;
  890.                 main_time += time;
  891.             }
  892.         
  893.             return true;
  894.         }
  895.         catch ( exception& exc ) {
  896.             ERR_POST("CId1Cache: Exception while loading cached blob: " <<
  897.                      seqref.printTSE() << ": " << exc.what());
  898.             if ( CollectStatistics() ) {
  899.                 double time = sw.Elapsed();
  900.                 LogBlobStat("CId1Cache: read fail blob",
  901.                             seqref, 0, time);
  902.                 main_blob_count++;
  903.                 main_time += time;
  904.             }
  905.             return false;
  906.         }
  907.     }
  908.     else {
  909.         return false;
  910.     }
  911. }
  912. bool CCachedId1Reader::LoadSNPTable(CSeq_annot_SNP_Info& snp_info,
  913.                                     const CSeqref& seqref)
  914. {
  915.     if ( m_BlobCache ) {
  916.         string key = GetBlobKey(seqref);
  917.         int ver = seqref.GetVersion();
  918.         string subkey = GetSNPTableSubkey();
  919.         CStopWatch sw;
  920.         if ( CollectStatistics() ) {
  921.             sw.Start();
  922.         }
  923.         try {
  924.             auto_ptr<IReader> reader(
  925.                 m_BlobCache->GetReadStream(key, ver, subkey));
  926.             if ( !reader.get() ) {
  927.                 return false;
  928.             }
  929.             CRStream stream(reader.get());
  930.             // table
  931.             CSeq_annot_SNP_Info_Reader::Read(stream, snp_info);
  932.             if ( CollectStatistics() ) {
  933.                 double time = sw.Elapsed();
  934.                 size_t size = m_BlobCache->GetSize(key, ver, subkey);
  935.                 LogBlobStat("CId1Cache: read SNP blob",
  936.                             seqref, size, time);
  937.                 snp_load_count++;
  938.                 snp_load_bytes += size;
  939.                 snp_load_time += time;
  940.             }
  941.             return true;
  942.         }
  943.         catch ( exception& exc ) {
  944.             ERR_POST("CId1Cache: "
  945.                      "Exception while loading cached SNP table: "<<
  946.                      seqref.printTSE() << ": " << exc.what());
  947.             snp_info.Reset();
  948.             if ( CollectStatistics() ) {
  949.                 double time = sw.Elapsed();
  950.                 LogBlobStat("CId1Cache: read fail SNP blob",
  951.                             seqref, 0, time);
  952.                 snp_load_count++;
  953.                 snp_load_time += time;
  954.             }
  955.             return false;
  956.         }
  957.     }
  958.     else if ( m_OldBlobCache ) {
  959.         string key = GetBlobKey(seqref);
  960.         int ver = seqref.GetVersion();
  961.         CStopWatch sw;
  962.         if ( CollectStatistics() ) {
  963.             sw.Start();
  964.         }
  965.         try {
  966.             auto_ptr<IReader> reader(m_OldBlobCache->GetReadStream(key, ver));
  967.             if ( !reader.get() ) {
  968.                 return false;
  969.             }
  970.             CRStream stream(reader.get());
  971.             // blob type
  972.             char type[4];
  973.             if ( !stream.read(type, 4) || memcmp(type, "STBL", 4) != 0 ) {
  974.                 if ( CollectStatistics() ) {
  975.                     double time = sw.Elapsed();
  976.                     LogBlobStat("CId1Cache: read fail SNP blob",
  977.                                 seqref, 0, time);
  978.                     snp_load_count++;
  979.                     snp_load_time += time;
  980.                 }
  981.                 return false;
  982.             }
  983.             // table
  984.             CSeq_annot_SNP_Info_Reader::Read(stream, snp_info);
  985.             if ( CollectStatistics() ) {
  986.                 double time = sw.Elapsed();
  987.                 size_t size = m_OldBlobCache->GetSize(key, ver);
  988.                 LogBlobStat("CId1Cache: read SNP blob",
  989.                             seqref, size, time);
  990.                 snp_load_count++;
  991.                 snp_load_bytes += size;
  992.                 snp_load_time += time;
  993.             }
  994.             return true;
  995.         }
  996.         catch ( exception& exc ) {
  997.             ERR_POST("CId1Cache: "
  998.                      "Exception while loading cached SNP table: "<<
  999.                      seqref.printTSE() << ": " << exc.what());
  1000.             snp_info.Reset();
  1001.             if ( CollectStatistics() ) {
  1002.                 double time = sw.Elapsed();
  1003.                 LogBlobStat("CId1Cache: read fail SNP blob",
  1004.                             seqref, 0, time);
  1005.                 snp_load_count++;
  1006.                 snp_load_time += time;
  1007.             }
  1008.             return false;
  1009.         }
  1010.     }
  1011.     else {
  1012.         return false;
  1013.     }
  1014. }
  1015. void CCachedId1Reader::StoreSNPTable(const CSeq_annot_SNP_Info& snp_info,
  1016.                                      const CSeqref& seqref)
  1017. {
  1018.     if ( m_BlobCache ) {
  1019.         string key = GetBlobKey(seqref);
  1020.         int ver = seqref.GetVersion();
  1021.         string subkey = GetSNPTableSubkey();
  1022.         CStopWatch sw;
  1023.         if ( CollectStatistics() ) {
  1024.             sw.Start();
  1025.         }
  1026.         try {
  1027.             {{
  1028.                 auto_ptr<IWriter> writer;
  1029.                 writer.reset(m_BlobCache->GetWriteStream(key, ver, subkey));
  1030.                 if ( !writer.get() ) {
  1031.                     return;
  1032.                 }
  1033.                 {{
  1034.                     CWStream stream(writer.get());
  1035.                     CSeq_annot_SNP_Info_Reader::Write(stream, snp_info);
  1036.                 }}
  1037.                 writer->Flush();
  1038.                 writer.reset();
  1039.             }}
  1040.             if ( CollectStatistics() ) {
  1041.                 double time = sw.Elapsed();
  1042.                 size_t size = m_BlobCache->GetSize(key, ver, subkey);
  1043.                 LogBlobStat("CId1Cache: saved SNP blob",
  1044.                             seqref, size, time);
  1045.                 snp_store_count++;
  1046.                 snp_store_bytes += size;
  1047.                 snp_store_time += time;
  1048.             }
  1049.         }
  1050.         catch ( exception& exc ) {
  1051.             ERR_POST("CId1Cache: "
  1052.                      "Exception while storing SNP table: "<<
  1053.                      seqref.printTSE() << ": " << exc.what());
  1054.             try {
  1055.                 m_BlobCache->Remove(key);
  1056.             }
  1057.             catch ( exception& /*exc*/ ) {
  1058.                 // ignored
  1059.             }
  1060.             if ( CollectStatistics() ) {
  1061.                 double time = sw.Elapsed();
  1062.                 LogBlobStat("CId1Cache: save fail SNP blob",
  1063.                             seqref, 0, time);
  1064.                 snp_store_count++;
  1065.                 snp_store_time += time;
  1066.             }
  1067.         }
  1068.     }
  1069.     else if ( m_OldBlobCache ) {
  1070.         string key = GetBlobKey(seqref);
  1071.         int ver = seqref.GetVersion();
  1072.         CStopWatch sw;
  1073.         if ( CollectStatistics() ) {
  1074.             sw.Start();
  1075.         }
  1076.         try {
  1077.             {{
  1078.                 auto_ptr<IWriter> writer;
  1079.                 writer.reset(m_OldBlobCache->GetWriteStream(key, ver));
  1080.                 if ( !writer.get() ) {
  1081.                     return;
  1082.                 }
  1083.                 {{
  1084.                     CWStream stream(writer.get());
  1085.                     stream.write("STBL", 4);
  1086.                     CSeq_annot_SNP_Info_Reader::Write(stream, snp_info);
  1087.                 }}
  1088.                 writer->Flush();
  1089.                 writer.reset();
  1090.             }}
  1091.             if ( CollectStatistics() ) {
  1092.                 double time = sw.Elapsed();
  1093.                 size_t size = m_OldBlobCache->GetSize(key, ver);
  1094.                 LogBlobStat("CId1Cache: saved SNP blob",
  1095.                             seqref, size, time);
  1096.                 snp_store_count++;
  1097.                 snp_store_bytes += size;
  1098.                 snp_store_time += time;
  1099.             }
  1100.         }        
  1101.         catch ( exception& exc ) {
  1102.             ERR_POST("CId1Cache: "
  1103.                      "Exception while storing SNP table: "<<
  1104.                      seqref.printTSE() << ": " << exc.what());
  1105.             try {
  1106.                 m_OldBlobCache->Remove(key);
  1107.             }
  1108.             catch ( exception& /*exc*/ ) {
  1109.                 // ignored
  1110.             }
  1111.             if ( CollectStatistics() ) {
  1112.                 double time = sw.Elapsed();
  1113.                 LogBlobStat("CId1Cache: save fail SNP blob",
  1114.                             seqref, 0, time);
  1115.                 snp_store_count++;
  1116.                 snp_store_time += time;
  1117.             }
  1118.         }
  1119.     }
  1120. }
  1121. bool CCachedId1Reader::LoadData(const string& key, int version,
  1122.                                 const char* suffix,
  1123.                                 CID2_Reply_Data& data)
  1124. {
  1125.     AutoPtr<IReader> reader(m_BlobCache->GetReadStream(key, version, suffix));
  1126.     if ( !reader.get() ) {
  1127.         return false;
  1128.     }
  1129.     
  1130.     CIRByteSourceReader rd(reader.get());
  1131.     
  1132.     CObjectIStreamAsnBinary in(rd);
  1133.     
  1134.     in >> data;
  1135.     return true;
  1136. }
  1137. bool CCachedId1Reader::LoadData(const string& key, const char* suffix,
  1138.                                 int version, CID2_Reply_Data& data)
  1139. {
  1140.     AutoPtr<IReader> reader(m_OldBlobCache->GetReadStream(key + suffix,
  1141.                                                           version));
  1142.     if ( !reader.get() ) {
  1143.         return false;
  1144.     }
  1145.     
  1146.     CIRByteSourceReader rd(reader.get());
  1147.     
  1148.     CObjectIStreamAsnBinary in(rd);
  1149.     
  1150.     in >> data;
  1151.     return true;
  1152. }
  1153. class CVectorListReader : public CByteSourceReader
  1154. {
  1155. public:
  1156.     typedef list< vector< char >* > TData;
  1157.     CVectorListReader(const TData& data)
  1158.         : m_Data(data),
  1159.           m_CurrentIter(data.begin()),
  1160.           m_CurrentOffset(0)
  1161.         {
  1162.         }
  1163.     size_t Read(char* buffer, size_t bufferLength)
  1164.         {
  1165.             while ( m_CurrentIter != m_Data.end() ) {
  1166.                 const vector<char> curr = **m_CurrentIter;
  1167.                 if ( m_CurrentOffset < curr.size() ) {
  1168.                     size_t remaining = curr.size() - m_CurrentOffset;
  1169.                     size_t count = min(bufferLength, remaining);
  1170.                     memcpy(buffer, &curr[m_CurrentOffset], count);
  1171.                     m_CurrentOffset += count;
  1172.                     return count;
  1173.                 }
  1174.                 ++m_CurrentIter;
  1175.                 m_CurrentOffset = 0;
  1176.             }
  1177.             return 0;
  1178.         }
  1179.     
  1180. private:
  1181.     const TData& m_Data;
  1182.     TData::const_iterator m_CurrentIter;
  1183.     size_t m_CurrentOffset;
  1184. };
  1185. CRef<CByteSourceReader> CCachedId1Reader::GetReader(CID2_Reply_Data& data,
  1186.                                                     EDataType data_type)
  1187. {
  1188.     CRef<CByteSourceReader> ret;
  1189.     if ( data.GetData_type() != data_type ) {
  1190.         return ret;
  1191.     }
  1192.     ret.Reset(new CVectorListReader(data.GetData()));
  1193.     switch ( data.GetData_compression() ) {
  1194.     case eCompression_none:
  1195.         break;
  1196.     case eCompression_nlm_zip:
  1197.         ret.Reset(new CNlmZipBtRdr(ret.GetPointer()));
  1198.         break;
  1199.     default:
  1200.         NCBI_THROW(CLoaderException, eLoaderFailed,
  1201.                    "unknown compression");
  1202.     }
  1203.     return ret;
  1204. }
  1205. AutoPtr<CObjectIStream> CCachedId1Reader::OpenData(CID2_Reply_Data& data,
  1206.                                                    CByteSourceReader& reader)
  1207. {
  1208.     if ( data.GetData_format() != eSerial_AsnBinary ) {
  1209.         NCBI_THROW(CLoaderException, eLoaderFailed,
  1210.                    "unknown serial format");
  1211.     }
  1212.     return new CObjectIStreamAsnBinary(reader);
  1213. }
  1214. END_SCOPE(objects)
  1215. END_NCBI_SCOPE
  1216. /*
  1217.  * $Log: reader_id1_cache.cpp,v $
  1218.  * Revision 1000.2  2004/06/01 19:41:59  gouriano
  1219.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.25
  1220.  *
  1221.  * Revision 1.25  2004/05/21 21:42:52  gorelenk
  1222.  * Added PCH ncbi_pch.hpp
  1223.  *
  1224.  * Revision 1.24  2004/04/28 17:06:25  vasilche
  1225.  * Load split blobs from new ICache.
  1226.  *
  1227.  * Revision 1.23  2004/02/17 21:20:11  vasilche
  1228.  * Fixed 'unused argument' warning.
  1229.  *
  1230.  * Revision 1.22  2004/01/22 20:53:31  vasilche
  1231.  * Fixed include path.
  1232.  *
  1233.  * Revision 1.21  2004/01/22 20:10:37  vasilche
  1234.  * 1. Splitted ID2 specs to two parts.
  1235.  * ID2 now specifies only protocol.
  1236.  * Specification of ID2 split data is moved to seqsplit ASN module.
  1237.  * For now they are still reside in one resulting library as before - libid2.
  1238.  * As the result split specific headers are now in objects/seqsplit.
  1239.  * 2. Moved ID2 and ID1 specific code out of object manager.
  1240.  * Protocol is processed by corresponding readers.
  1241.  * ID2 split parsing is processed by ncbi_xreader library - used by all readers.
  1242.  * 3. Updated OBJMGR_LIBS correspondingly.
  1243.  *
  1244.  * Revision 1.20  2004/01/20 16:56:04  vasilche
  1245.  * Allow storing version of any blob (not only SNP).
  1246.  *
  1247.  * Revision 1.19  2004/01/13 21:54:50  vasilche
  1248.  * Requrrected new version
  1249.  *
  1250.  * Revision 1.5  2004/01/13 16:55:56  vasilche
  1251.  * CReader, CSeqref and some more classes moved from xobjmgr to separate lib.
  1252.  * Headers moved from include/objmgr to include/objtools/data_loaders/genbank.
  1253.  *
  1254.  * Revision 1.4  2003/12/30 22:14:42  vasilche
  1255.  * Updated genbank loader and readers plugins.
  1256.  *
  1257.  * Revision 1.17  2003/12/30 16:00:25  vasilche
  1258.  * Added support for new ICache (CBDB_Cache) interface.
  1259.  *
  1260.  * Revision 1.16  2003/12/09 17:30:32  ucko
  1261.  * +<stdio.h> for sprintf
  1262.  *
  1263.  * Revision 1.15  2003/11/26 17:55:59  vasilche
  1264.  * Implemented ID2 split in ID1 cache.
  1265.  * Fixed loading of splitted annotations.
  1266.  *
  1267.  * Revision 1.14  2003/10/27 15:05:41  vasilche
  1268.  * Added correct recovery of cached ID1 loader if gi->sat/satkey cache is invalid.
  1269.  * Added recognition of ID1 error codes: private, etc.
  1270.  * Some formatting of old code.
  1271.  *
  1272.  * Revision 1.13  2003/10/24 15:36:46  vasilche
  1273.  * Fixed incorrect order of objects' destruction - IWriter before object stream.
  1274.  *
  1275.  * Revision 1.12  2003/10/24 13:27:40  vasilche
  1276.  * Cached ID1 reader made more safe. Process errors and exceptions correctly.
  1277.  * Cleaned statistics printing methods.
  1278.  *
  1279.  * Revision 1.11  2003/10/23 13:48:38  vasilche
  1280.  * Use CRStream and CWStream instead of strstreams.
  1281.  *
  1282.  * Revision 1.10  2003/10/21 16:32:50  vasilche
  1283.  * Cleaned ID1 statistics messages.
  1284.  * Now by setting GENBANK_ID1_STATS=1 CId1Reader collects and displays stats.
  1285.  * And by setting GENBANK_ID1_STATS=2 CId1Reader logs all activities.
  1286.  *
  1287.  * Revision 1.9  2003/10/21 14:27:35  vasilche
  1288.  * Added caching of gi -> sat,satkey,version resolution.
  1289.  * SNP blobs are stored in cache in preprocessed format (platform dependent).
  1290.  * Limit number of connections to GenBank servers.
  1291.  * Added collection of ID1 loader statistics.
  1292.  *
  1293.  * Revision 1.8  2003/10/14 21:06:25  vasilche
  1294.  * Fixed compression statistics.
  1295.  * Disabled caching of SNP blobs.
  1296.  *
  1297.  * Revision 1.7  2003/10/14 19:31:18  kuznets
  1298.  * Removed unnecessary hook in SNP deserialization.
  1299.  *
  1300.  * Revision 1.6  2003/10/14 18:31:55  vasilche
  1301.  * Added caching support for SNP blobs.
  1302.  * Added statistics collection of ID1 connection.
  1303.  *
  1304.  * Revision 1.5  2003/10/08 18:58:23  kuznets
  1305.  * Implemented correct ID1 BLOB versions
  1306.  *
  1307.  * Revision 1.4  2003/10/03 17:41:44  kuznets
  1308.  * Added an option, that cache is owned by the ID1 reader.
  1309.  *
  1310.  * Revision 1.3  2003/10/02 19:29:14  kuznets
  1311.  * First working revision
  1312.  *
  1313.  * Revision 1.2  2003/10/01 19:32:22  kuznets
  1314.  * Work in progress
  1315.  *
  1316.  * Revision 1.1  2003/09/30 19:38:26  vasilche
  1317.  * Added support for cached id1 reader.
  1318.  *
  1319.  */