bdb_file.cpp
来自「ncbi源码」· C++ 代码 · 共 1,015 行 · 第 1/2 页
CPP
1,015 行
/* * =========================================================================== * PRODUCTION $Log: bdb_file.cpp,v $ * PRODUCTION Revision 1000.2 2004/06/01 18:37:25 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.37 * PRODUCTION * =========================================================================== *//* $Id: bdb_file.cpp,v 1000.2 2004/06/01 18:37:25 gouriano Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Author: Anatoliy Kuznetsov * * File Description: BDB libarary file implementations. * */#include <ncbi_pch.hpp>#include <bdb/bdb_file.hpp>#include <bdb/bdb_env.hpp>#include <bdb/bdb_trans.hpp>#include <db.h>BEGIN_NCBI_SCOPEconst char CBDB_RawFile::kDefaultDatabase[] = "_table";const int CBDB_RawFile::kOpenFileMask = 0664;// Auto-pointer style guard class for DB structureclass CDB_guard{public: CDB_guard(DB** db) : m_DB(db) {} ~CDB_guard() { if (m_DB && *m_DB) { (*m_DB)->close(*m_DB, 0); *m_DB = 0; } } void release() { m_DB = 0; }private: DB** m_DB;};/////////////////////////////////////////////////////////////////////////////// CBDB_RawFile:://CBDB_RawFile::CBDB_RawFile(EDuplicateKeys dup_keys): m_DB(0), m_DBT_Key(0), m_DBT_Data(0), m_Env(0), m_Trans(0), m_DB_Attached(false), m_ByteSwapped(false), m_PageSize(0), m_CacheSize(256 * 1024), m_DuplicateKeys(dup_keys){ try { m_DBT_Key = new DBT; m_DBT_Data = new DBT; } catch (...) { delete m_DBT_Key; delete m_DBT_Data; throw; } ::memset(m_DBT_Key, 0, sizeof(DBT)); ::memset(m_DBT_Data, 0, sizeof(DBT));}CBDB_RawFile::~CBDB_RawFile(){ x_Close(eIgnoreError); delete m_DBT_Key; delete m_DBT_Data; // It's illegal to close a file involved in active transactions if (m_Trans && (m_Trans->IsInProgress())) { _ASSERT(0); // If we are here we can try to communicate by throwing // an exception. It's illegal, but situation is bad enough already BDB_THROW(eTransInProgress, "Cannot close the file while transaction is in progress."); }}void CBDB_RawFile::Close(){ x_Close(eThrowOnError);}void CBDB_RawFile::Attach(CBDB_RawFile& bdb_file){ Close(); m_DB = bdb_file.m_DB; m_DB_Attached = true; }void CBDB_RawFile::SetEnv(CBDB_Env& env){ m_Env = &env;}DB_TXN* CBDB_RawFile::GetTxn(){ if (m_Trans) return m_Trans->GetTxn(); return 0;}void CBDB_RawFile::x_Close(EIgnoreError close_mode){ if ( m_FileName.empty() ) return; if (m_DB_Attached) { m_DB = 0; m_DB_Attached = false; } else if (m_DB) { int ret = m_DB->close(m_DB, 0); m_DB = 0; if (close_mode == eThrowOnError) { BDB_CHECK(ret, m_FileName.c_str()); } } m_FileName.erase(); m_Database.erase();}void CBDB_RawFile::Open(const char* filename, const char* database, EOpenMode open_mode){ if ( !m_FileName.empty() ) Close(); if (!database || !*database) database = 0; // database = kDefaultDatabase; x_Open(filename, database, open_mode); m_FileName = filename; if (database) m_Database = database; else m_Database = "";}void CBDB_RawFile::Reopen(EOpenMode open_mode){ _ASSERT(!m_FileName.empty()); if (m_DB_Attached) { BDB_THROW(eInvalidOperation, "Cannot reopen attached object"); } int ret = m_DB->close(m_DB, 0); m_DB = 0; BDB_CHECK(ret, m_FileName.c_str()); x_Open(m_FileName.c_str(), !m_Database.empty() ? m_Database.c_str() : 0, open_mode);}void CBDB_RawFile::Remove(const char* filename, const char* database){ if (!database || !*database) database = 0; // database = kDefaultDatabase; if (m_DB_Attached) { BDB_THROW(eInvalidOperation, "Cannot remove attached object"); } // temporary DB is used here, because BDB remove call invalidates the // DB argument redardless of the result. DB* db = 0; CDB_guard guard(&db); int ret = db_create(&db, m_Env ? m_Env->GetEnv() : 0, 0); BDB_CHECK(ret, 0); ret = db->remove(db, filename, database, 0); guard.release(); if (ret == ENOENT || ret == EINVAL) return; // Non existent table cannot be removed BDB_CHECK(ret, filename);}unsigned int CBDB_RawFile::Truncate(){ _ASSERT(m_DB != 0); u_int32_t count; DB_TXN* txn = GetTxn(); int ret = m_DB->truncate(m_DB, txn, &count, 0); BDB_CHECK(ret, FileName().c_str()); return count;}void CBDB_RawFile::SetCacheSize(unsigned int cache_size){ if (m_DB) { int ret = m_DB->set_cachesize(m_DB, 0, m_CacheSize, 1); BDB_CHECK(ret, 0); } m_CacheSize = cache_size;}void CBDB_RawFile::SetTransaction(CBDB_Transaction* trans){ if (m_Trans) { m_Trans->RemoveFile(this); } m_Trans = trans; if (m_Trans) { m_Trans->AddFile(this); }}void CBDB_RawFile::x_RemoveTransaction(CBDB_Transaction* trans){ if (trans == m_Trans) { m_Trans = 0; }}void CBDB_RawFile::x_CreateDB(){ _ASSERT(m_DB == 0); _ASSERT(!m_DB_Attached); CDB_guard guard(&m_DB); int ret = db_create(&m_DB, m_Env ? m_Env->GetEnv() : 0, 0); BDB_CHECK(ret, 0); SetCmp(m_DB); if ( m_PageSize ) { ret = m_DB->set_pagesize(m_DB, m_PageSize); BDB_CHECK(ret, 0); } if (!m_Env) { ret = m_DB->set_cachesize(m_DB, 0, m_CacheSize, 1); BDB_CHECK(ret, 0); } if (DuplicatesAllowed()) { ret = m_DB->set_flags(m_DB, DB_DUP); BDB_CHECK(ret, 0); } guard.release();}void CBDB_RawFile::x_Open(const char* filename, const char* database, EOpenMode open_mode){ int ret; if (m_DB == 0) { x_CreateDB(); } if (open_mode == eCreate) { Remove(filename, database); x_Create(filename, database); } else { u_int32_t open_flags; switch (open_mode) { case eReadOnly: open_flags = DB_RDONLY; break; case eCreate: open_flags = DB_CREATE; break; default: open_flags = 0; break; } DB_TXN* txn = 0; // GetTxn(); if (m_Env) { if (m_Env->IsTransactional()) { open_flags |= DB_THREAD | DB_AUTO_COMMIT; } } ret = m_DB->open(m_DB, txn, filename, database, // database name DB_BTREE, open_flags, kOpenFileMask ); if ( ret ) { if (open_mode == eCreate || open_mode == eReadWriteCreate) { x_Create(filename, database); } else { m_DB->close(m_DB, 0); m_DB = 0; BDB_CHECK(ret, filename); } } } // else open_mode == Create m_OpenMode = open_mode; int isswapped; ret = m_DB->get_byteswapped(m_DB, &isswapped); BDB_CHECK(ret, filename); m_ByteSwapped = (isswapped!=0);}void CBDB_RawFile::SetPageSize(unsigned int page_size){ _ASSERT(m_DB == 0); // we can set page size only before opening the file if (((page_size - 1) & page_size) != 0) { BDB_THROW(eInvalidValue, "Page size must be power of 2"); } m_PageSize = page_size;}void CBDB_RawFile::Sync(){ int ret = m_DB->sync(m_DB, 0); BDB_CHECK(ret, FileName().c_str());}unsigned CBDB_RawFile::CountRecs(){ DB_BTREE_STAT* stp; int ret = m_DB->stat(m_DB, &stp, 0); BDB_CHECK(ret, FileName().c_str()); u_int32_t rc = stp->bt_ndata; return rc;}void CBDB_RawFile::x_Create(const char* filename, const char* database){ _ASSERT(!m_DB_Attached); u_int32_t open_flags = DB_CREATE; DB_TXN* txn = 0; //GetTxn(); if (m_Env) { if (m_Env->IsTransactional()) { open_flags |= DB_THREAD | DB_AUTO_COMMIT; } } int ret = m_DB->open(m_DB, txn, filename, database, // database name DB_BTREE, open_flags, kOpenFileMask); if ( ret ) { m_DB->close(m_DB, 0); m_DB = 0; BDB_CHECK(ret, filename); }}DBC* CBDB_RawFile::CreateCursor(CBDB_Transaction* trans) const{ DBC* cursor; if (!m_DB) { BDB_THROW(eInvalidValue, "Cannot create cursor for unopen file."); } DB_TXN* txn = 0; // GetTxn(); if (trans) { txn = trans->GetTxn(); } int ret = m_DB->cursor(m_DB, txn, &cursor, 0); BDB_CHECK(ret, FileName().c_str()); return cursor;}///////////////////////////////////////////////////////////////////////////////// CBDB_File:://CBDB_File::CBDB_File(EDuplicateKeys dup_keys) : CBDB_RawFile(dup_keys), m_KeyBuf(new CBDB_BufferManager), m_BufsAttached(false), m_BufsCreated(false), m_DataBufDisabled(false), m_LegacyString(false){}void CBDB_File::BindKey(const char* field_name, CBDB_Field* key_field, size_t buf_size){ _ASSERT(!IsOpen()); _ASSERT(m_KeyBuf.get()); _ASSERT(key_field); key_field->SetName(field_name); m_KeyBuf->Bind(key_field); if ( buf_size ) key_field->SetBufferSize(buf_size);}void CBDB_File::BindData(const char* field_name, CBDB_Field* data_field, size_t buf_size, ENullable is_nullable){ _ASSERT(!IsOpen()); _ASSERT(data_field); data_field->SetName(field_name); if (m_DataBuf.get() == 0) { // data buffer is not yet created auto_ptr<CBDB_BufferManager> dbuf(new CBDB_BufferManager); m_DataBuf = dbuf; m_DataBuf->SetNullable(); m_DataBuf->SetLegacyStringsCheck(m_LegacyString); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?