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.21 2010/12/08 17:37:42 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     /**\brief Linked list next */
00078     extnum_t           next;        // 4 bytes
00079     /**\brief Linked list previous */
00080     extnum_t           prev;        // 4 bytes
00081     /**\brief Store number of containging store */
00082     snum_t             owner;       // 4 bytes
00083     /**\brief Not logged; space utilization by histograms */
00084     uint4_t            pbucketmap; // 4 bytes, unlogged !!! 
00085     // NOTE re: pbucketmap: If we change the number of pages per
00086     // extent, we have to adjust the size of pbucketmap or 
00087     // we have to adjust HBUCKETBITS in page_s.h
00088     // They are all closely tied.
00089 
00090     static int       logged_size();
00091     NORET            extlink_t();
00092     NORET            extlink_t(const extlink_t& e);
00093     extlink_t&       operator=(const extlink_t&);
00094 
00095     void             clrall();
00096     void             setall();
00097     void             setmap(const Pmap &m);
00098     void             getmap(Pmap &m) const;
00099     void             set(int i);
00100     void             clr(int i);
00101     bool             is_set(int i) const;
00102     bool             is_clr(int i) const;
00103     int              first_set(int start) const;
00104     int              first_clr(int start) const;
00105     int              last_set(int start) const;
00106     int              last_clr(int start) const;
00107     int              num_set() const;
00108     int              num_clr() const;
00109 
00110     space_bucket_t         get_page_bucket(int i)const;
00111 
00112     friend ostream& operator<<(ostream &, const extlink_t &e);
00113 };
00114 
00115 inline NORET
00116 extlink_t::extlink_t(const extlink_t& e) 
00117 : pmap(e.pmap),
00118   next(e.next),
00119   prev(e.prev),
00120   owner(e.owner),
00121   pbucketmap(e.pbucketmap)
00122 {
00123     // this is needed elsewhere -- see extlink_p::set_byte
00124     w_assert9(w_offsetof(extlink_t, pmap) == 0);
00125 }
00126 
00127 inline extlink_t& 
00128 extlink_t::operator=(const extlink_t& e)
00129 {
00130     pmap = e.pmap;
00131     prev = e.prev;
00132     next = e.next; 
00133     owner = e.owner;
00134     pbucketmap = e.pbucketmap;
00135     return *this;
00136 }
00137 inline void 
00138 extlink_t::setmap(const Pmap &m)
00139 {
00140     pmap = m;
00141 }
00142 inline void 
00143 extlink_t::getmap(Pmap &m) const
00144 {
00145     m = pmap;
00146     DBGTHRD(<<"getmap " << m);
00147 }
00148 
00149 inline void 
00150 extlink_t::clrall()
00151 {
00152     pmap.clear_all();
00153 }
00154 
00155 inline void 
00156 extlink_t::setall()
00157 {
00158     pmap.set_all();
00159 }
00160 
00161 inline void 
00162 extlink_t::set(int i)
00163 {
00164     pmap.set(i);
00165 }
00166 
00167 inline void 
00168 extlink_t::clr(int i)
00169 {
00170     pmap.clear(i);
00171 }
00172 
00173 inline bool 
00174 extlink_t::is_set(int i) const
00175 {
00176     w_assert9(i < smlevel_0::ext_sz);
00177     return pmap.is_set(i);
00178 }
00179 
00180 inline bool 
00181 extlink_t::is_clr(int i) const
00182 {
00183     return (! is_set(i));
00184 }
00185 
00186 inline int extlink_t::first_set(int start) const
00187 {
00188     return pmap.first_set(start);
00189 }
00190 
00191 inline int 
00192 extlink_t::first_clr(int start) const
00193 {
00194     return pmap.first_clear(start);
00195 }
00196 
00197 inline int 
00198 extlink_t::last_set(int start) const
00199 {
00200     return pmap.last_set(start);
00201 }
00202 
00203 inline int 
00204 extlink_t::last_clr(int start) const
00205 {
00206     return pmap.last_clear(start);
00207 }
00208 
00209 inline int 
00210 extlink_t::num_set() const
00211 {
00212     return pmap.num_set();
00213 }
00214 
00215 inline int 
00216 extlink_t::num_clr() const
00217 {
00218     return pmap.num_clear();
00219 }
00220 
00221 /**\cond skip */
00222 
00223 /********************************************************************
00224 * class extlink_p
00225 ********************************************************************/
00226 /**\brief Extent map page that contains extent links (extlink_t).
00227  */
00228 
00229 class extlink_p : public page_p {
00230 public:
00231     MAKEPAGE(extlink_p, page_p, 2); // make extent links a little hotter than
00232     // others
00233 
00234     // max # extent links on a page
00235     enum { max = data_sz / sizeof(extlink_t) };
00236 
00237     const extlink_t& get_const(slotid_t idx);
00238     extlink_t&       get_nonconst(slotid_t idx);
00239     void             put(slotid_t idx, const extlink_t& e);
00240     w_rc_t           set_byte(slotid_t idx, u_char bits, 
00241                           enum page_p::logical_operation);
00242     w_rc_t           set_bytes(slotid_t idx,
00243                           smsize_t    offset,
00244                           smsize_t     count,
00245                           const uint1_t* bits, 
00246                           enum page_p::logical_operation);
00247     void             clr_pmap_bit(slotid_t idx, int bit); 
00248     static bool      on_same_page(extnum_t e1, extnum_t e2);
00249 
00250 private:
00251     extlink_t&             item(int i);
00252 
00253     struct layout_t {
00254     extlink_t             item[max];
00255     };
00256 
00257     // disable
00258     friend class page_link_log;        // just to keep g++ happy
00259     friend class extlink_i;        // needs access to item
00260 };
00261 
00262 inline bool
00263 extlink_p::on_same_page(extnum_t e1, extnum_t e2)
00264 {
00265     shpid_t p1 = e1 / (extlink_p::max);
00266     shpid_t p2 = e2 / (extlink_p::max);
00267     return (p1 == p2);
00268 }
00269 
00270 inline extlink_t&
00271 extlink_p::item(int i)
00272 {
00273     w_assert9(i < max);
00274     return ((layout_t*)tuple_addr(0))->item[i];
00275 }
00276 
00277 
00278 inline extlink_t&
00279 extlink_p::get_nonconst(slotid_t idx) 
00280 {
00281     return item(idx);
00282 }
00283 inline const extlink_t&
00284 extlink_p::get_const(slotid_t idx) 
00285 {
00286     return item(idx);
00287 }
00288 
00289 inline int
00290 extlink_t::logged_size() {
00291     //
00292     // NOTE: watch the order of attributes so that we don't log the
00293     // pbucketmap!!!
00294     //
00295     // return __offsetof(extlink_t, pbucketmap);
00296     return w_offsetof(extlink_t, pbucketmap);
00297 }
00298 
00299 inline void
00300 extlink_p::put(slotid_t idx, const extlink_t& e)
00301 {
00302     DBG(<<"extlink_p::put(" <<  idx << " owner=" <<
00303     e.owner << ", " << e.next << ")");
00304     const vec_t    extent_vec_tmp(&e, extlink_t::logged_size());
00305     W_COERCE(overwrite(0, idx * sizeof(extlink_t), extent_vec_tmp));
00306 }
00307 
00308 /**\endcond skip */
00309 
00310 
00311 /**\brief Persistent structure representing the head of a store's extent list.
00312  * \details These structures sit on stnode_p pages and point to the
00313  * start of the extent list.
00314  * The stnode_t structures are indexed by store number.
00315  */
00316 struct stnode_t {
00317     /**\brief First extent of the store */
00318     extnum_t                 head; // 4 bytes
00319     /**\brief Fill factor (not used) */
00320     w_base_t::uint2_t        eff;
00321     /**\brief store flags  */
00322     w_base_t::uint2_t        flags;
00323     /**\brief non-zero if deleting or deleted */
00324     w_base_t::uint2_t        deleting; // see store_operation
00325     /**\brief alignment */
00326     fill2                    filler; // align to 4 bytes
00327 };
00328 
00329 /**\cond skip */
00330 
00331 /**\brief Extent map page that contains store nodes (stnode_t).
00332  * \details These are the pages that contain the starting points of 
00333  * a store's list of extents.
00334  */
00335 class stnode_p : public page_p {
00336     public:
00337     MAKEPAGE(stnode_p, page_p, 1);
00338 
00339     // max # store nodes on a page
00340     enum { max = data_sz / sizeof(stnode_t) };
00341 
00342     const stnode_t&       get(slotid_t idx);
00343     rc_t                  put(slotid_t idx, const stnode_t& e);
00344 
00345     private:
00346     stnode_t&             item(snum_t i);
00347     struct layout_t {
00348         stnode_t          item[max];
00349     };
00350 
00351     friend class page_link_log;        // just to keep g++ happy
00352     friend class stnode_i;        // needs access to item
00353 };    
00354 
00355 inline stnode_t&
00356 stnode_p::item(snum_t i)
00357 {
00358     w_assert9(i < max);
00359     return ((layout_t*)tuple_addr(0))->item[i];
00360 }
00361 
00362 inline const stnode_t&
00363 stnode_p::get(slotid_t idx)
00364 {
00365     return item(idx);
00366 }
00367 
00368 inline w_rc_t 
00369 stnode_p::put(slotid_t idx, const stnode_t& e)
00370 {
00371     const vec_t stnode_vec_tmp(&e, sizeof(e));
00372     W_DO(overwrite(0, idx * sizeof(stnode_t), stnode_vec_tmp));
00373     return RCOK;
00374 }
00375 /**\endcond skip */
00376 
00377 /**\brief Iterator over a list of extents.
00378  *\details  Constructor latches the given extent-map page.
00379  * Get() methods unlatch and latch extent-map pages as needed to return
00380  * a reference to the needed extlink_t.
00381  */
00382 class extlink_i {
00383 public:
00384     NORET            extlink_i(const lpid_t& root)
00385                     : 
00386                     _root(root) {
00387                         // The extent maps start on page 1. 
00388                         w_assert1(root.page >= 1);
00389                     }
00390             
00391     bool             on_same_root(extnum_t idx);
00392     
00393     lpid_t           get_pid(extnum_t idx) const;
00394     rc_t             get_const(extnum_t idx, const extlink_t* &);
00395     rc_t             get_nonconst(extnum_t idx, extlink_t* &);
00396     rc_t             get_copy_SH(extnum_t idx, extlink_t &);
00397     rc_t             get_copy_EX(extnum_t idx, extlink_t &);
00398     rc_t             put(extnum_t idx, const extlink_t&);
00399     bool             on_same_page(extnum_t ext1, extnum_t ext2) const ;
00400 
00401     rc_t             update_histo(extnum_t ext,     
00402                         int    offset,
00403                         space_bucket_t bucket);
00404     rc_t             fix_EX(extnum_t idx);
00405     void             unfix();
00406     rc_t             set_pmap_bits(snum_t snum, extnum_t idx, const Pmap &bits);
00407     rc_t             clr_pmap_bit(snum_t snum, extnum_t idx, int bit);
00408 
00409     rc_t             clr_pmap_bits(snum_t snum, extnum_t idx, const Pmap &bits);
00410     rc_t             set_next(extnum_t ext, extnum_t new_next, bool log_it = true);
00411     const extlink_p& page() const { return _page; } // for logging purposes
00412 
00413 private:
00414     extid_t             _id;
00415     lpid_t              _root;
00416     extlink_p           _page;
00417 
00418     inline w_rc_t       update_pmap(extnum_t idx,
00419                             const Pmap &pmap,
00420                             page_p::logical_operation how);
00421     inline w_rc_t       update_pbucketmap(extnum_t idx,
00422                             uint4_t map,
00423                             page_p::logical_operation how);
00424 };
00425 
00426 
00427 /*********************************************************************
00428  *
00429  *  class stnode_i
00430  *
00431  *  Iterator over store node area of volume.
00432  *
00433  *********************************************************************/
00434 /**\brief Iterator over store nodes.
00435  * \details  Constructor latches the given store node page; the get
00436  * methods unlatch and latch pages as necessary to return a reference to
00437  * a stnode_t for the given store number.
00438  * The store_operation method effects operations on entire stores, such
00439  * as deletion and changing logging attributes.
00440  */
00441 class stnode_i: private smlevel_0 {
00442 public:
00443     NORET               stnode_i(const lpid_t& root) : _root(root) {
00444                              // store nodes are after extent links and
00445                              // those start on page 1.
00446                              w_assert1(root.page >= 1);
00447                         };
00448     w_rc_t              get(snum_t idx, stnode_t &stnode);
00449     w_rc_t              get(snum_t idx, const stnode_t *&stnode);
00450     w_rc_t              put(snum_t idx, const stnode_t& stnode);      
00451     w_rc_t              store_operation(const store_operation_param & op);
00452 private:
00453     lpid_t              _root;
00454     stnode_p            _page;
00455 };
00456 
00457 
00458 /*<std-footer incl-file-exclusion='EXTENT_H'>  -- do not edit anything below this line -- */
00459 
00460 #endif          /*</std-footer>*/

Generated on Mon Jan 2 15:13:57 2012 for Shore Storage Manager by  doxygen 1.4.7