Fairport  v1.0.38
fairport/ndb/page.h
Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 #ifndef FAIRPORT_NDB_PAGE_H
00016 #define FAIRPORT_NDB_PAGE_H
00017 
00018 #include <vector>
00019 
00020 #include "fairport/util/btree.h"
00021 #include "fairport/util/util.h"
00022 
00023 #include "fairport/ndb/database_iface.h"
00024 
00025 #ifdef _MSC_VER
00026 #pragma warning(push)
00027 #pragma warning(disable:4250)
00028 #endif
00029 
00030 namespace fairport
00031 {
00032 
00035 
00051 class page
00052 {
00053 public:
00057     page(const shared_db_ptr& db, const page_info& pi)
00058         : m_db(db), m_pid(pi.id), m_address(pi.address) { }
00059 
00062     page_id get_page_id() const { return m_pid; }
00063 
00066     ulonglong get_address() const { return m_address; }
00067 
00068 protected:
00069     shared_db_ptr get_db_ptr() const { return shared_db_ptr(m_db); }
00070     weak_db_ptr m_db;       
00071     page_id m_pid;          
00072     ulonglong m_address;    
00073 };
00074 
00089 template<typename K, typename V>
00090 class bt_page : 
00091     public page, 
00092     public virtual btree_node<K,V>
00093 {
00094 public:
00099     bt_page(const shared_db_ptr& db, const page_info& pi, ushort level)
00100         : page(db, pi), m_level(level) { }
00101 
00104     ushort get_level() const { return m_level; }
00105 
00106 private:
00107     ushort m_level; 
00108 };
00109 
00118 template<typename K, typename V>
00119 class bt_nonleaf_page : 
00120     public bt_page<K,V>, 
00121     public btree_node_nonleaf<K,V>, 
00122     public std::tr1::enable_shared_from_this<bt_nonleaf_page<K,V> >
00123 {
00124 public:
00130 #ifndef BOOST_NO_RVALUE_REFERENCES
00131     bt_nonleaf_page(const shared_db_ptr& db, const page_info& pi, ushort level, std::vector<std::pair<K, page_info> > subpi)
00132         : bt_page<K,V>(db, pi, level), m_page_info(std::move(subpi)), m_child_pages(m_page_info.size()) { }
00133 #else
00134     bt_nonleaf_page(const shared_db_ptr& db, const page_info& pi, ushort level, const std::vector<std::pair<K, page_info> >& subpi)
00135         : bt_page<K,V>(db, pi, level), m_page_info(subpi), m_child_pages(m_page_info.size()) { }
00136 #endif
00137 
00138     // btree_node_nonleaf implementation
00139     const K& get_key(uint pos) const { return m_page_info[pos].first; }
00140     bt_page<K,V>* get_child(uint pos);
00141     const bt_page<K,V>* get_child(uint pos) const;
00142     uint num_values() const { return m_child_pages.size(); }
00143 
00144 private:
00145     std::vector<std::pair<K, page_info> > m_page_info;   
00146     mutable std::vector<std::tr1::shared_ptr<bt_page<K,V> > > m_child_pages; 
00147 };
00148 
00153 template<typename K, typename V>
00154 class bt_leaf_page : 
00155     public bt_page<K,V>, 
00156     public btree_node_leaf<K,V>, 
00157     public std::tr1::enable_shared_from_this<bt_leaf_page<K,V> >
00158 {
00159 public:
00164 #ifndef BOOST_NO_RVALUE_REFERENCES
00165     bt_leaf_page(const shared_db_ptr& db, const page_info& pi, std::vector<std::pair<K,V> > data)
00166         : bt_page<K,V>(db, pi, 0), m_page_data(std::move(data)) { }
00167 #else
00168     bt_leaf_page(const shared_db_ptr& db, const page_info& pi, const std::vector<std::pair<K,V> >& data)
00169         : bt_page<K,V>(db, pi, 0), m_page_data(data) { }
00170 #endif
00171 
00172     // btree_node_leaf implementation
00173     const V& get_value(uint pos) const
00174         { return m_page_data[pos].second; }
00175     const K& get_key(uint pos) const
00176         { return m_page_data[pos].first; }
00177     uint num_values() const
00178         { return m_page_data.size(); }
00179 
00180 private:
00181     std::vector<std::pair<K,V> > m_page_data; 
00182 };
00184 template<>
00185 inline bt_page<block_id, block_info>* bt_nonleaf_page<block_id, block_info>::get_child(uint pos)
00186 {
00187     if(m_child_pages[pos] == NULL)
00188     {
00189         m_child_pages[pos] = this->get_db_ptr()->read_bbt_page(m_page_info[pos].second);
00190     }
00191 
00192     return m_child_pages[pos].get();
00193 }
00194 
00195 template<>
00196 inline const bt_page<block_id, block_info>* bt_nonleaf_page<block_id, block_info>::get_child(uint pos) const
00197 {
00198     if(m_child_pages[pos] == NULL)
00199     {
00200         m_child_pages[pos] = this->get_db_ptr()->read_bbt_page(m_page_info[pos].second);
00201     }
00202 
00203     return m_child_pages[pos].get();
00204 }
00205 
00206 template<>
00207 inline bt_page<node_id, node_info>* bt_nonleaf_page<node_id, node_info>::get_child(uint pos)
00208 {
00209     if(m_child_pages[pos] == NULL)
00210     {
00211         m_child_pages[pos] = this->get_db_ptr()->read_nbt_page(m_page_info[pos].second); 
00212     }
00213 
00214     return m_child_pages[pos].get();
00215 }
00216 
00217 template<>
00218 inline const bt_page<node_id, node_info>* bt_nonleaf_page<node_id, node_info>::get_child(uint pos) const
00219 {
00220     if(m_child_pages[pos] == NULL)
00221     {
00222         m_child_pages[pos] = this->get_db_ptr()->read_nbt_page(m_page_info[pos].second); 
00223     }
00224 
00225     return m_child_pages[pos].get();
00226 }
00228 } // end namespace
00229 
00230 #ifdef _MSC_VER
00231 #pragma warning(pop)
00232 #endif
00233 
00234 #endif