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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: bdb_blob.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 18:37:11  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.17
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: bdb_blob.cpp,v 1000.2 2004/06/01 18:37:11 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: Anatoliy Kuznetsov
  35.  *
  36.  * File Description:  BDB libarary BLOB implementations.
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <bdb/bdb_blob.hpp>
  41. #include <bdb/bdb_trans.hpp>
  42. #include <db.h>
  43. BEGIN_NCBI_SCOPE
  44. /////////////////////////////////////////////////////////////////////////////
  45. //  CBDB_BLobFile::
  46. //
  47. CBDB_BLobFile::CBDB_BLobFile() 
  48.     DisableDataBufProcessing(); 
  49. }
  50. EBDB_ErrCode CBDB_BLobFile::Fetch()
  51. {
  52.     return Fetch(0, 0, eReallocForbidden);
  53. }
  54. EBDB_ErrCode CBDB_BLobFile::Fetch(void**       buf, 
  55.                                   size_t       buf_size, 
  56.                                   EReallocMode allow_realloc)
  57. {
  58.     m_DBT_Data->data = buf ? *buf : 0;
  59.     m_DBT_Data->ulen = (unsigned)buf_size;
  60.     m_DBT_Data->size = 0;
  61.     if (allow_realloc == eReallocForbidden) {
  62.         m_DBT_Data->flags = DB_DBT_USERMEM;
  63.     } else {
  64.         if (m_DBT_Data->data == 0) {
  65.             m_DBT_Data->flags = DB_DBT_MALLOC;
  66.         } else {
  67.             m_DBT_Data->flags = DB_DBT_REALLOC;
  68.         }
  69.     }
  70.     EBDB_ErrCode ret;
  71.     ret = CBDB_File::Fetch();
  72.     if ( buf )
  73.         *buf = m_DBT_Data->data;
  74.     if (ret == eBDB_NotFound)
  75.         return eBDB_NotFound;
  76.     return eBDB_Ok;
  77. }
  78. EBDB_ErrCode CBDB_BLobFile::GetData(void* buf, size_t size)
  79. {
  80.     return Fetch(&buf, size, eReallocForbidden);
  81. }
  82. EBDB_ErrCode CBDB_BLobFile::Insert(const void* data, size_t size)
  83. {
  84.     m_DBT_Data->data = const_cast<void*> (data);
  85.     m_DBT_Data->size = m_DBT_Data->ulen = (unsigned)size;
  86.     EBDB_ErrCode ret = CBDB_File::Insert();
  87.     return ret;
  88. }
  89. size_t CBDB_BLobFile::LobSize() const 
  90.     return m_DBT_Data->size; 
  91. }
  92. CBDB_BLobStream* CBDB_BLobFile::CreateStream()
  93. {
  94.     EBDB_ErrCode ret = Fetch();
  95.     DBT* dbt = CloneDBT_Key();
  96.     // lob exists, we can read it now (or write)
  97.     if (ret == eBDB_Ok) {
  98.         return new CBDB_BLobStream(m_DB, dbt, LobSize(), GetTxn());
  99.     }
  100.     // no lob yet (write stream)
  101.     return new CBDB_BLobStream(m_DB, dbt, 0, GetTxn());
  102. }
  103. /////////////////////////////////////////////////////////////////////////////
  104. //  CBDB_BLobFile::
  105. //
  106. CBDB_BLobStream::CBDB_BLobStream(DB* db, 
  107.                                  DBT* dbt_key, 
  108.                                  size_t blob_size, 
  109.                                  DB_TXN* txn)
  110. : m_DB(db),
  111.   m_DBT_Key(dbt_key),
  112.   m_DBT_Data(0),
  113.   m_Txn(txn),
  114.   m_Pos(0),
  115.   m_BlobSize(blob_size)
  116. {
  117.     m_DBT_Data = new DBT;
  118.     ::memset(m_DBT_Data, 0, sizeof(DBT));
  119. }
  120. CBDB_BLobStream::~CBDB_BLobStream()
  121. {
  122.     CBDB_File::DestroyDBT_Clone(m_DBT_Key);
  123.     delete m_DBT_Data;
  124. }
  125. void CBDB_BLobStream::SetTransaction(CBDB_Transaction* trans)
  126. {
  127.     if (trans) {
  128.         m_Txn = trans->GetTxn();
  129.     } else {
  130.         m_Txn = 0;
  131.     }
  132. }
  133. void CBDB_BLobStream::Read(void *buf, size_t buf_size, size_t *bytes_read)
  134. {
  135.     m_DBT_Data->flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
  136.     m_DBT_Data->data = buf;
  137.     m_DBT_Data->ulen = (unsigned)buf_size;
  138.     m_DBT_Data->dlen = (unsigned)buf_size;
  139.     m_DBT_Data->doff = m_Pos;
  140.     m_DBT_Data->size = 0;
  141.     
  142.     int ret = m_DB->get(m_DB,
  143.                         0,         // DB_TXN*
  144.                         m_DBT_Key,
  145.                         m_DBT_Data,
  146.                         0);
  147.     BDB_CHECK(ret, "BLOBStream");
  148.     m_Pos += m_DBT_Data->size;
  149.     *bytes_read = m_DBT_Data->size;
  150. }
  151. void CBDB_BLobStream::Write(const void* buf, size_t buf_size)
  152. {
  153. /*    if (m_Pos == 0)
  154.         m_DBT_Data->flags = 0;
  155.     else*/
  156.         m_DBT_Data->flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
  157.     m_DBT_Data->data = const_cast<void*> (buf);
  158.     m_DBT_Data->size = (unsigned)buf_size;
  159.     m_DBT_Data->ulen = (unsigned)buf_size;
  160.     m_DBT_Data->doff = m_Pos;
  161.     m_DBT_Data->dlen = (unsigned)buf_size;
  162.     int ret = m_DB->put(m_DB,
  163.                         m_Txn,
  164.                         m_DBT_Key,
  165.                         m_DBT_Data,
  166.                         0);
  167.     BDB_CHECK(ret, "BLOBStream");
  168.     m_Pos += (unsigned)buf_size;
  169. }
  170. /////////////////////////////////////////////////////////////////////////////
  171. //  CBDB_LobFile::
  172. //
  173. CBDB_LobFile::CBDB_LobFile()
  174.  : m_LobKey(0)
  175. {
  176.     m_DBT_Key->data = &m_LobKey;
  177.     m_DBT_Key->size = (unsigned)sizeof(m_LobKey);
  178.     m_DBT_Key->ulen = (unsigned)sizeof(m_LobKey);
  179.     m_DBT_Key->flags = DB_DBT_USERMEM;
  180. }
  181. EBDB_ErrCode CBDB_LobFile::Insert(unsigned int lob_id,
  182.                                   const void*  data,
  183.                                   size_t       size)
  184. {
  185.     _ASSERT(lob_id);
  186.     _ASSERT(size);
  187.     _ASSERT(m_DB);
  188.     // paranoia check
  189.     _ASSERT(m_DBT_Key->data == &m_LobKey);
  190.     _ASSERT(m_DBT_Key->size == sizeof(m_LobKey));
  191.     m_LobKey = lob_id;
  192.     m_DBT_Data->data = const_cast<void*> (data);
  193.     m_DBT_Data->size = m_DBT_Data->ulen = (unsigned)size;
  194.     int ret = m_DB->put(m_DB,
  195.                         0,     // DB_TXN*
  196.                         m_DBT_Key,
  197.                         m_DBT_Data,
  198.                         DB_NOOVERWRITE /*| DB_NODUPDATA*/
  199.                         );
  200.     if (ret == DB_KEYEXIST)
  201.         return eBDB_KeyDup;
  202.     BDB_CHECK(ret, FileName().c_str());
  203.     return eBDB_Ok;
  204. }
  205. EBDB_ErrCode CBDB_LobFile::Fetch(unsigned int lob_id,
  206.                                  void**       buf,
  207.                                  size_t       buf_size,
  208.                                  EReallocMode allow_realloc)
  209. {
  210.     _ASSERT(lob_id);
  211.     _ASSERT(m_DB);
  212.     // paranoia check
  213.     _ASSERT(m_DBT_Key->data  == &m_LobKey);
  214.     _ASSERT(m_DBT_Key->size  == sizeof(m_LobKey));
  215.     _ASSERT(m_DBT_Key->ulen  == sizeof(m_LobKey));
  216.     _ASSERT(m_DBT_Key->flags == DB_DBT_USERMEM);
  217.     m_LobKey = lob_id;
  218.     // Here we attempt to read only key value and get information
  219.     // about LOB size. In this case get operation fails with ENOMEM
  220.     // error message (ignored)
  221.     m_DBT_Data->data = buf ? *buf : 0;
  222.     m_DBT_Data->ulen = (unsigned)buf_size;
  223.     m_DBT_Data->size = 0;
  224.     if (m_DBT_Data->data == 0  &&  m_DBT_Data->ulen != 0) {
  225.         _ASSERT(0);
  226.     }
  227.     if (allow_realloc == eReallocForbidden) {
  228.         m_DBT_Data->flags = DB_DBT_USERMEM;
  229.     } else {
  230.         if (m_DBT_Data->data == 0) {
  231.             m_DBT_Data->flags = DB_DBT_MALLOC;
  232.         } else {
  233.             m_DBT_Data->flags = DB_DBT_REALLOC;
  234.         }
  235.     }
  236.     int ret = m_DB->get(m_DB,
  237.                         0,          // DB_TXN*
  238.                         m_DBT_Key,
  239.                         m_DBT_Data,
  240.                         0
  241.                         );
  242.     if (ret == DB_NOTFOUND)
  243.         return eBDB_NotFound;
  244.     if (ret == ENOMEM) {
  245.         if (m_DBT_Data->data == 0)
  246.             return eBDB_Ok;  // to be retrieved later using GetData()
  247.     }
  248.     BDB_CHECK(ret, FileName().c_str());
  249.     if ( buf )
  250.         *buf = m_DBT_Data->data;
  251.     return eBDB_Ok;
  252. }
  253. EBDB_ErrCode CBDB_LobFile::GetData(void* buf, size_t size)
  254. {
  255.     _ASSERT(m_LobKey);
  256.     _ASSERT(m_DB);
  257.     _ASSERT(size >= m_DBT_Data->size);
  258.     _ASSERT(m_DBT_Data->size);
  259.     // paranoia check
  260.     _ASSERT(m_DBT_Key->data == &m_LobKey);
  261.     _ASSERT(m_DBT_Key->size == sizeof(m_LobKey));
  262.     _ASSERT(m_DBT_Key->ulen == sizeof(m_LobKey));
  263.     _ASSERT(m_DBT_Key->flags == DB_DBT_USERMEM);
  264.     m_DBT_Data->data  = buf;
  265.     m_DBT_Data->ulen  = (unsigned)size;
  266.     m_DBT_Data->flags = DB_DBT_USERMEM;
  267.     int ret = m_DB->get(m_DB,
  268.                         0,          // DB_TXN*
  269.                         m_DBT_Key,
  270.                         m_DBT_Data,
  271.                         0
  272.                         );
  273.     if (ret == DB_NOTFOUND)
  274.         return eBDB_NotFound;
  275.     BDB_CHECK(ret, FileName().c_str());
  276.     return eBDB_Ok;
  277. }
  278. size_t CBDB_LobFile::LobSize() const
  279. {
  280.     return m_DBT_Data->size;
  281. }
  282. void CBDB_LobFile::SetCmp(DB*)
  283. {
  284.     BDB_CompareFunction func = BDB_UintCompare;
  285.     if (IsByteSwapped()) {
  286.         func = BDB_ByteSwap_UintCompare;
  287.     }
  288.     _ASSERT(func);
  289.     int ret = m_DB->set_bt_compare(m_DB, func);
  290.     BDB_CHECK(ret, 0);
  291. }
  292. END_NCBI_SCOPE
  293. /*
  294.  * ===========================================================================
  295.  * $Log: bdb_blob.cpp,v $
  296.  * Revision 1000.2  2004/06/01 18:37:11  gouriano
  297.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.17
  298.  *
  299.  * Revision 1.17  2004/05/17 20:55:11  gorelenk
  300.  * Added include of PCH ncbi_pch.hpp
  301.  *
  302.  * Revision 1.16  2004/03/12 15:08:04  kuznets
  303.  * Removed unnecessary DB_NODUPDATA flag (db->put)
  304.  *
  305.  * Revision 1.15  2003/12/29 17:06:24  kuznets
  306.  * +CBDB_BlobStream::SetTransaction()
  307.  *
  308.  * Revision 1.14  2003/12/29 16:52:29  kuznets
  309.  * Added transaction support for BLOB stream
  310.  *
  311.  * Revision 1.13  2003/10/24 13:40:32  kuznets
  312.  * Implemeneted PendingCount
  313.  *
  314.  * Revision 1.12  2003/09/29 16:44:56  kuznets
  315.  * Reimplemented SetCmp to fix cross-platform byte swapping bug
  316.  *
  317.  * Revision 1.11  2003/09/29 16:27:06  kuznets
  318.  * Cleaned up 64-bit compilation warnings
  319.  *
  320.  * Revision 1.10  2003/09/26 18:48:30  kuznets
  321.  * Removed dead SetCmp function
  322.  *
  323.  * Revision 1.9  2003/09/17 18:18:42  kuznets
  324.  * Implemented BLOB streaming
  325.  *
  326.  * Revision 1.8  2003/07/02 17:55:34  kuznets
  327.  * Implementation modifications to eliminated direct dependency from <db.h>
  328.  *
  329.  * Revision 1.7  2003/06/10 20:08:27  kuznets
  330.  * Fixed function names.
  331.  *
  332.  * Revision 1.6  2003/05/09 13:44:57  kuznets
  333.  * Fixed a bug in cursors based on BLOB storage
  334.  *
  335.  * Revision 1.5  2003/05/08 13:43:40  kuznets
  336.  * Bug fix.
  337.  *
  338.  * Revision 1.4  2003/05/05 20:15:32  kuznets
  339.  * Added CBDB_BLobFile
  340.  *
  341.  * Revision 1.3  2003/04/29 19:07:22  kuznets
  342.  * Cosmetics..
  343.  *
  344.  * Revision 1.2  2003/04/28 14:51:55  kuznets
  345.  * #include directives changed to conform the NCBI policy
  346.  *
  347.  * Revision 1.1  2003/04/24 16:34:30  kuznets
  348.  * Initial revision
  349.  *
  350.  * ===========================================================================
  351.  */