⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bdb_map.hpp

📁 ncbi源码
💻 HPP
📖 第 1 页 / 共 2 页
字号:
/* * =========================================================================== * PRODUCTION $Log: bdb_map.hpp,v $ * PRODUCTION Revision 1000.2  2004/04/29 15:32:57  gouriano * PRODUCTION PRODUCTION: UPGRADED [CATCHUP_003] Dev-tree R1.11 * PRODUCTION * =========================================================================== */#ifndef BDB_MAP__HPP#define BDB_MAP__HPP/* $Id: bdb_map.hpp,v 1000.2 2004/04/29 15:32:57 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: Templates implementing Berkeley DB based maps with syntax *                   close to standard associative containers */#include <bdb/bdb_cursor.hpp>BEGIN_NCBI_SCOPE/** @addtogroup BDB_Map * * @{ *//// Internal template used for compiler based type mapping  /// (C++ templates specialization emplyed here)///template<class T> struct CBDB_TypeMapper{    typedef T  TFieldType;};template<> struct CBDB_TypeMapper<int>{    typedef CBDB_FieldInt4 TFieldType;};template<> struct CBDB_TypeMapper<string>{    typedef CBDB_FieldLString TFieldType;};/// db_map_base /// template<class K, class T> class db_map_base{public:    typedef typename CBDB_TypeMapper<K>::TFieldType  db_first_type;    typedef typename CBDB_TypeMapper<T>::TFieldType  db_second_type;    typedef std::pair<K, T>   value_type;    struct File : public CBDB_File    {        db_first_type  key;        db_second_type value;        File(CBDB_File::EDuplicateKeys dup_keys)        : CBDB_File(dup_keys)        {            BindKey("Key", &key);            BindData("Value", &value, 1024);        }    };    typedef typename db_map_base<K, T>::File  map_file_type;protected:    // Base class for all db_map iterators    // Class opens its own copy of BerkeleyDB file and cursor on it.    class iterator_base    {            protected:        enum EIteratorStatus {            eUnknown,            eEnd,            eBeforeBegin,            eInFile        };        iterator_base(map_file_type* db_file)        : m_ParentFile(db_file),          m_CursorFile(0),          m_Cur(0),          m_OpenMode(CBDB_RawFile::eReadOnly),          m_IStatus(eUnknown)        {        }        ~iterator_base()        {            delete m_Cur;            delete m_CursorFile;        }        iterator_base(const iterator_base& it)        {            init_from(it);        }        iterator_base& operator=(const iterator_base& it)        {            return init_from(it);        }        iterator_base& init_from(const iterator_base& it)        {            m_ParentFile = it.m_ParentFile;            m_CursorFile = 0;            m_Cur = 0;            m_OpenMode = it.m_OpenMode;            m_SearchFlag = it.m_SearchFlag;            m_pair.first = it.m_pair.first;            m_pair.second = it.m_pair.second;            m_IStatus = it.m_IStatus;            return *this;        }        void open_cursor(CBDB_RawFile::EOpenMode open_mode,                          CBDB_FileCursor::ECondition cursor_condition) const        {            delete m_Cur; m_Cur = 0;            bool attached = m_CursorFile->IsAttached();            if (!attached) {                m_CursorFile->Attach(*m_ParentFile);            }            m_Cur = new CBDB_FileCursor(*m_CursorFile);            m_Cur->SetCondition(cursor_condition);        }        void open_cursor(CBDB_RawFile::EOpenMode open_mode,                          CBDB_FileCursor::ECondition cursor_condition,                         const K& key) const        {            open_cursor(open_mode, cursor_condition);            m_Cur->From << key;        }        // db_map iterators are quite heavy (opens BDB cursors and stuff) and        // to simplify the iteratros coping and assignments we use lazy initilization        // It means actual db operation is postponed until the first iterator access.        void check_open_cursor() const        {            if (m_CursorFile == 0) {                _ASSERT(m_ParentFile);                m_CursorFile = new map_file_type(m_ParentFile->GetDupKeysMode());                _ASSERT(m_Cur == 0);                if (m_SearchFlag) {                    open_cursor(m_OpenMode, CBDB_FileCursor::eGE, m_pair.first);                } else {                    if (m_IStatus == eEnd) {                        open_cursor(m_OpenMode, CBDB_FileCursor::eLast);                        m_Cur->ReverseFetchDirection();                    } else {                        open_cursor(m_OpenMode, CBDB_FileCursor::eFirst);                    }                }                if (m_Cur->Fetch() ==  eBDB_Ok) {                    m_SearchFlag = true;                    m_pair.first = m_CursorFile->key;                    m_pair.second= m_CursorFile->value;                    if (m_IStatus == eEnd) {                    } else {                        m_IStatus = eInFile;                    }                } else { // No data...                    // go to the end                    open_cursor(m_OpenMode, CBDB_FileCursor::eLast);                    m_IStatus = eEnd;                }            }        }        void go_end()        {            if (m_IStatus == eEnd) return;            // if it's "end()" iterartor, no need to open any files here            if (m_CursorFile == 0) {                m_IStatus = eEnd;                return;            }            open_cursor(m_OpenMode, CBDB_FileCursor::eLast);            m_Cur->ReverseFetchDirection();            if (m_Cur->Fetch() == eBDB_Ok) {                m_pair.first = (K)m_CursorFile->key;                m_pair.second= (T)m_CursorFile->value;            }            m_IStatus = eEnd;        }        void fetch_next()        {            _ASSERT(m_IStatus != eEnd);            check_open_cursor();            if (m_Cur->Fetch() == eBDB_Ok) {                m_pair.first = m_CursorFile->key;                m_pair.second= m_CursorFile->value;                m_IStatus = eInFile;            } else {                m_IStatus = eEnd;            }        }        void fetch_prev()        {            _ASSERT(m_IStatus != eBeforeBegin);            check_open_cursor();            if (m_Cur->Fetch(CBDB_FileCursor::eBackward) == eBDB_Ok) {                m_pair.first = m_CursorFile->key;                m_pair.second= m_CursorFile->value;                m_IStatus = eInFile;            } else {                m_IStatus = eBeforeBegin;            }        }        bool is_equal(const iterator_base& it) const        {            if (m_ParentFile != it.m_ParentFile)                 return false;            if (m_IStatus == eUnknown) {                check_open_cursor();            }            if (m_IStatus == it.m_IStatus) {                if (m_IStatus == eEnd && it.m_IStatus == eEnd)                     return true;                if (m_IStatus == eBeforeBegin && it.m_IStatus == eBeforeBegin)                    return true;                return (m_pair.first == it.m_pair.first);            }            return false;        }    public:         // Return TRUE while iterator is in the correct range        bool valid() const        {            check_open_cursor();            if (m_IStatus == eEnd) return false;            if (m_IStatus == eBeforeBegin) return false;            return true;        }    protected:        mutable map_file_type*             m_ParentFile;        mutable map_file_type*             m_CursorFile;        mutable CBDB_FileCursor*           m_Cur;        // Cursor open mode        CBDB_RawFile::EOpenMode m_OpenMode;        // TRUE if iterator searches for the specific key        mutable bool                    m_SearchFlag;         // Current key-value pair        mutable value_type              m_pair;        // Iterator "navigation" status        mutable EIteratorStatus         m_IStatus;    };public:    class const_iterator : public iterator_base    {    public:        const_iterator(map_file_type* db_file)        : iterator_base(db_file)        {            this->m_SearchFlag = false;        }        const_iterator(map_file_type* db_file, const K& key)        : iterator_base(db_file)        {            this->m_SearchFlag = true;            this->m_pair.first = key;        }        const_iterator& go_end()        {            iterator_base::go_end();            return *this;        }        const_iterator() : iterator_base(0)         {}        const_iterator(const const_iterator& it) : iterator_base(it)        {}                const_iterator& operator=(const const_iterator& it)         {             init_from(it);return *this;        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -