extent.h

00001 /* -*- mode:C++; c-basic-offset:4 -*-
00002      Shore-MT -- Multi-threaded port of the SHORE storage manager
00003    
00004                        Copyright (c) 2007-2009
00005       Data Intensive Applications and Systems Labaratory (DIAS)
00006                Ecole Polytechnique Federale de Lausanne
00007    
00008                          All Rights Reserved.
00009    
00010    Permission to use, copy, modify and distribute this software and
00011    its documentation is hereby granted, provided that both the
00012    copyright notice and this permission notice appear in all copies of
00013    the software, derivative works or modified versions, and any
00014    portions thereof, and that both notices appear in supporting
00015    documentation.
00016    
00017    This code is distributed in the hope that it will be useful, but
00018    WITHOUT ANY WARRANTY; without even the implied warranty of
00019    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS
00020    DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
00021    RESULTING FROM THE USE OF THIS SOFTWARE.
00022 */
00023 
00024 /*<std-header orig-src='shore' incl-file-exclusion='EXTENT_H'>
00025 
00026  $Id: extent.h,v 1.18 2010/08/23 14:28:18 nhall Exp $
00027 
00028 SHORE -- Scalable Heterogeneous Object REpository
00029 
00030 Copyright (c) 1994-99 Computer Sciences Department, University of
00031                       Wisconsin -- Madison
00032 All Rights Reserved.
00033 
00034 Permission to use, copy, modify and distribute this software and its
00035 documentation is hereby granted, provided that both the copyright
00036 notice and this permission notice appear in all copies of the
00037 software, derivative works or modified versions, and any portions
00038 thereof, and that both notices appear in supporting documentation.
00039 
00040 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY
00041 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS
00042 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND
00043 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
00044 
00045 This software was developed with support by the Advanced Research
00046 Project Agency, ARPA order number 018 (formerly 8230), monitored by
00047 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518.
00048 Further funding for this work was provided by DARPA through
00049 Rome Research Laboratory Contract No. F30602-97-2-0247.
00050 
00051 */
00052 
00053 #ifndef EXTENT_H
00054 #define EXTENT_H
00055 
00056 #include "w_defines.h"
00057 
00058 /*  -- do not edit anything above this line --   </std-header>*/
00059 
00060 
00061 /********************************************************************
00062  * class extlink_t
00063  ********************************************************************/
00064 /**\brief
00065  * Persistent structure (on an extent map page) representing an extent.
00066  * \details Contains a bitmap indicating which of its pages are allocated,
00067  * next and previous pointers to link this extent into a store, and
00068  * an owner (store number, zero means not owned).  
00069  * Also contains unlogged space-utilization information (bucket map) used by
00070  * the file manager.
00071  */
00072 
00073 class extlink_t {
00074     // Grot: this became 4-byte aligned when extnum_t grew to 4 bytes
00075     Pmap_Align4        pmap;        // LOGGED. this must be first
00076 public:
00077     extnum_t           next;        // 4 bytes
00078     extnum_t           prev;        // 4 bytes
00079     snum_t             owner;       // 4 bytes
00080     uint4_t            pbucketmap; // 4 bytes, unlogged !!! used by
00081                                    // histograms
00082 
00083     static int       logged_size();
00084     NORET            extlink_t();
00085     NORET            extlink_t(const extlink_t& e);
00086     extlink_t&       operator=(const extlink_t&);
00087 
00088     void             clrall();
00089     void             setall();
00090     void             setmap(const Pmap &m);
00091     void             getmap(Pmap &m) const;
00092     void             set(int i);
00093     void             clr(int i);
00094     bool             is_set(int i) const;
00095     bool             is_clr(int i) const;
00096     int              first_set(int start) const;
00097     int              first_clr(int start) const;
00098     int              last_set(int start) const;
00099     int              last_clr(int start) const;
00100     int              num_set() const;
00101     int              num_clr() const;
00102 
00103     space_bucket_t         get_page_bucket(int i)const;
00104 
00105     friend ostream& operator<<(ostream &, const extlink_t &e);
00106 };
00107 
00108 inline NORET
00109 extlink_t::extlink_t(const extlink_t& e) 
00110 : pmap(e.pmap),
00111   next(e.next),
00112   prev(e.prev),
00113   owner(e.owner),
00114   pbucketmap(e.pbucketmap)
00115 {
00116     // this is needed elsewhere -- see extlink_p::set_byte
00117     w_assert9(w_offsetof(extlink_t, pmap) == 0);
00118 }
00119 
00120 inline extlink_t& 
00121 extlink_t::operator=(const extlink_t& e)
00122 {
00123     pmap = e.pmap;
00124     prev = e.prev;
00125     next = e.next; 
00126     owner = e.owner;
00127     pbucketmap = e.pbucketmap;
00128     return *this;
00129 }
00130 inline void 
00131 extlink_t::setmap(const Pmap &m)
00132 {
00133     pmap = m;
00134 }
00135 inline void 
00136 extlink_t::getmap(Pmap &m) const
00137 {
00138     m = pmap;
00139     DBGTHRD(<<"getmap " << m);
00140 }
00141 
00142 inline void 
00143 extlink_t::clrall()
00144 {
00145     pmap.clear_all();
00146 }
00147 
00148 inline void 
00149 extlink_t::setall()
00150 {
00151     pmap.set_all();
00152 }
00153 
00154 inline void 
00155 extlink_t::set(int i)
00156 {
00157     pmap.set(i);
00158 }
00159 
00160 inline void 
00161 extlink_t::clr(int i)
00162 {
00163     pmap.clear(i);
00164 }
00165 
00166 inline bool 
00167 extlink_t::is_set(int i) const
00168 {
00169     w_assert9(i < smlevel_0::ext_sz);
00170     return pmap.is_set(i);
00171 }
00172 
00173 inline bool 
00174 extlink_t::is_clr(int i) const
00175 {
00176     return (! is_set(i));
00177 }
00178 
00179 inline int extlink_t::first_set(int start) const
00180 {
00181     return pmap.first_set(start);
00182 }
00183 
00184 inline int 
00185 extlink_t::first_clr(int start) const
00186 {
00187     return pmap.first_clear(start);
00188 }
00189 
00190 inline int 
00191 extlink_t::last_set(int start) const
00192 {
00193     return pmap.last_set(start);
00194 }
00195 
00196 inline int 
00197 extlink_t::last_clr(int start) const
00198 {
00199     return pmap.last_clear(start);
00200 }
00201 
00202 inline int 
00203 extlink_t::num_set() const
00204 {
00205     return pmap.num_set();
00206 }
00207 
00208 inline int 
00209 extlink_t::num_clr() const
00210 {
00211     return pmap.num_clear();
00212 }
00213 
00214 /**\cond skip */
00215 
00216 /********************************************************************
00217 * class extlink_p
00218 ********************************************************************/
00219 /**\brief Extent map page that contains extent links (extlink_t).
00220  */
00221 
00222 class extlink_p : public page_p {
00223 public:
00224     MAKEPAGE(extlink_p, page_p, 2); // make extent links a little hotter than
00225     // others
00226 
00227     // max # extent links on a page
00228     enum { max = data_sz / sizeof(extlink_t) };
00229 
00230     const extlink_t& get(slotid_t idx);
00231     void             put(slotid_t idx, const extlink_t& e);
00232     w_rc_t           set_byte(slotid_t idx, u_char bits, 
00233                           enum page_p::logical_operation);
00234     w_rc_t           set_bytes(slotid_t idx,
00235                           smsize_t    offset,
00236                           smsize_t     count,
00237                           const uint1_t* bits, 
00238                           enum page_p::logical_operation);
00239     void             clr_pmap_bit(slotid_t idx, int bit); 
00240     static bool      on_same_page(extnum_t e1, extnum_t e2);
00241 
00242 private:
00243     extlink_t&             item(int i);
00244 
00245     struct layout_t {
00246     extlink_t             item[max];
00247     };
00248 
00249     // disable
00250     friend class page_link_log;        // just to keep g++ happy
00251     friend class extlink_i;        // needs access to item
00252 };
00253 
00254 inline bool
00255 extlink_p::on_same_page(extnum_t e1, extnum_t e2)
00256 {
00257     shpid_t p1 = e1 / (extlink_p::max);
00258     shpid_t p2 = e2 / (extlink_p::max);
00259     return (p1 == p2);
00260 }
00261 
00262 inline extlink_t&
00263 extlink_p::item(int i)
00264 {
00265     w_assert9(i < max);
00266     return ((layout_t*)tuple_addr(0))->item[i];
00267 }
00268 
00269 
00270 inline const extlink_t&
00271 extlink_p::get(slotid_t idx)
00272 {
00273     return item(idx);
00274 }
00275 
00276 inline int
00277 extlink_t::logged_size() {
00278     //
00279     // NOTE: watch the order of attributes so that we don't log the
00280     // pbucketmap!!!
00281     //
00282     // return __offsetof(extlink_t, pbucketmap);
00283     return w_offsetof(extlink_t, pbucketmap);
00284 }
00285 
00286 inline void
00287 extlink_p::put(slotid_t idx, const extlink_t& e)
00288 {
00289     DBG(<<"extlink_p::put(" <<  idx << " owner=" <<
00290     e.owner << ", " << e.next << ")");
00291     const vec_t    extent_vec_tmp(&e, extlink_t::logged_size());
00292     W_COERCE(overwrite(0, idx * sizeof(extlink_t), extent_vec_tmp));
00293 }
00294 
00295 /**\endcond skip */
00296 
00297 
00298 /**\brief Persistent structure representing the head of a store's extent list.
00299  * \details These structures sit on stnode_p pages and point to the
00300  * start of the extent list.
00301  * The stnode_t structures are indexed by store number.
00302  */
00303 struct stnode_t {
00304     extnum_t                 head;
00305     w_base_t::uint2_t        eff;
00306     w_base_t::uint2_t        flags;
00307     w_base_t::uint2_t        deleting; // nonzero if deleted/deleting
00308                              // see store_operation
00309     fill2                    filler; // align to 4 bytes
00310 };
00311 
00312 /**\cond skip */
00313 
00314 /**\brief Extent map page that contains store nodes (stnode_t).
00315  * \details These are the pages that contain the starting points of 
00316  * a store's list of extents.
00317  */
00318 class stnode_p : public page_p {
00319     public:
00320     MAKEPAGE(stnode_p, page_p, 1);
00321 
00322     // max # store nodes on a page
00323     enum { max = data_sz / sizeof(stnode_t) };
00324 
00325     const stnode_t&       get(slotid_t idx);
00326     rc_t                  put(slotid_t idx, const stnode_t& e);
00327 
00328     private:
00329     stnode_t&             item(snum_t i);
00330     struct layout_t {
00331         stnode_t          item[max];
00332     };
00333 
00334     friend class page_link_log;        // just to keep g++ happy
00335     friend class stnode_i;        // needs access to item
00336 };    
00337 
00338 inline stnode_t&
00339 stnode_p::item(snum_t i)
00340 {
00341     w_assert9(i < max);
00342     return ((layout_t*)tuple_addr(0))->item[i];
00343 }
00344 
00345 inline const stnode_t&
00346 stnode_p::get(slotid_t idx)
00347 {
00348     return item(idx);
00349 }
00350 
00351 inline w_rc_t 
00352 stnode_p::put(slotid_t idx, const stnode_t& e)
00353 {
00354     const vec_t stnode_vec_tmp(&e, sizeof(e));
00355     W_DO(overwrite(0, idx * sizeof(stnode_t), stnode_vec_tmp));
00356     return RCOK;
00357 }
00358 /**\endcond skip */
00359 
00360 /**\brief Iterator over a list of extents.
00361  *\details  Constructor latches the given extent-map page.
00362  * Get() methods unlatch and latch extent-map pages as needed to return
00363  * a reference to the needed extlink_t.
00364  */
00365 class extlink_i {
00366 public:
00367     NORET            extlink_i(const lpid_t& root)
00368                     : 
00369                     _root(root) {
00370                         // The extent maps start on page 1. 
00371                         w_assert1(root.page >= 1);
00372                     }
00373             
00374     bool             on_same_root(extnum_t idx);
00375     
00376     lpid_t           get_pid(extnum_t idx) const;
00377     rc_t             get(extnum_t idx, const extlink_t* &);
00378     rc_t             get(extnum_t idx, extlink_t* &);
00379     rc_t             get_copy(extnum_t idx, extlink_t &);
00380     rc_t             put(extnum_t idx, const extlink_t&);
00381     bool             on_same_page(extnum_t ext1, extnum_t ext2) const ;
00382 
00383     rc_t             update_histo(extnum_t ext,     
00384                         int    offset,
00385                         space_bucket_t bucket);
00386     rc_t             fix_EX(extnum_t idx);
00387     void             unfix();
00388     rc_t             set_pmap_bits(snum_t snum, extnum_t idx, const Pmap &bits);
00389     rc_t             clr_pmap_bit(snum_t snum, extnum_t idx, int bit);
00390 
00391     rc_t             clr_pmap_bits(snum_t snum, extnum_t idx, const Pmap &bits);
00392     rc_t             set_next(extnum_t ext, extnum_t new_next, bool log_it = true);
00393     const extlink_p& page() const { return _page; } // for logging purposes
00394 
00395 private:
00396     extid_t             _id;
00397     lpid_t              _root;
00398     extlink_p           _page;
00399 
00400     inline w_rc_t       update_pmap(extnum_t idx,
00401                             const Pmap &pmap,
00402                             page_p::logical_operation how);
00403     inline w_rc_t       update_pbucketmap(extnum_t idx,
00404                             uint4_t map,
00405                             page_p::logical_operation how);
00406 };
00407 
00408 
00409 /*********************************************************************
00410  *
00411  *  class stnode_i
00412  *
00413  *  Iterator over store node area of volume.
00414  *
00415  *********************************************************************/
00416 /**\brief Iterator over store nodes.
00417  * \details  Constructor latches the given store node page; the get
00418  * methods unlatch and latch pages as necessary to return a reference to
00419  * a stnode_t for the given store number.
00420  * The store_operation method effects operations on entire stores, such
00421  * as deletion and changing logging attributes.
00422  */
00423 class stnode_i: private smlevel_0 {
00424 public:
00425     NORET               stnode_i(const lpid_t& root) : _root(root) {
00426                              // store nodes are after extent links and
00427                              // those start on page 1.
00428                              w_assert1(root.page >= 1);
00429                         };
00430     w_rc_t              get(snum_t idx, stnode_t &stnode);
00431     w_rc_t              get(snum_t idx, const stnode_t *&stnode);
00432     w_rc_t              put(snum_t idx, const stnode_t& stnode);      
00433     w_rc_t              store_operation(const store_operation_param & op);
00434 private:
00435     lpid_t              _root;
00436     stnode_p            _page;
00437 };
00438 
00439 
00440 /*<std-footer incl-file-exclusion='EXTENT_H'>  -- do not edit anything below this line -- */
00441 
00442 #endif          /*</std-footer>*/

Generated on Wed Oct 27 08:48:36 2010 for Shore Storage Manager by  doxygen 1.4.7