vec_t.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='VEC_T_H'>
00025 
00026  $Id: vec_t.h,v 1.66 2010/06/18 21:22:45 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 VEC_T_H
00054 #define VEC_T_H
00055 
00056 #include "w_defines.h"
00057 
00058 /*  -- do not edit anything above this line --   </std-header>*/
00059 
00060 /* NB: you must already have defined the type size_t,
00061  * (which is defined include "basics.h") before you include this.
00062  */
00063 
00064 #ifdef __GNUG__
00065 #pragma interface
00066 #endif
00067 
00068 #define CADDR_T const unsigned char *
00069 #define MAX_SMALL_VEC_SIZE 8
00070 
00071 /*
00072  * Newer c++ compilers require
00073  * that copy constructors be available for classes which use anonymous
00074  * temporary variables.  However, vec_t are non-copyable, so you
00075  * must create named temporaries of these structures.
00076  */
00077 
00078 /**\brief A helper class for VEC_t
00079  */
00080 struct vec_pair_t {
00081     CADDR_T        ptr;
00082     size_t         len;
00083 };
00084 
00085 /**\brief A base class for vec_t.
00086  */
00087 struct VEC_t {
00088     int                _cnt;
00089     size_t             _size;
00090     vec_pair_t*        _base;        // pointer to beginning of _pair or malloced
00091                         // space
00092     vec_pair_t         _pair[MAX_SMALL_VEC_SIZE];
00093 };
00094 
00095 /**\brief A constant vec_t  (meaning things pointed to cannot be changed).
00096  */
00097 class cvec_t : protected VEC_t {
00098     friend class vec_t; // so vec_t can look at VEC_t
00099 protected:
00100     static        CADDR_T  zero_location; // see zvec_t, which is supposed
00101                                     // to be for the server-side only
00102 public:
00103     enum dummy_enumid { max_small = MAX_SMALL_VEC_SIZE };
00104 public:
00105     cvec_t() {
00106         _cnt = 0;
00107         _size = 0;
00108         _base = &_pair[0];
00109     }
00110     cvec_t(const cvec_t& v1, const cvec_t& v2) {
00111         _base= &_pair[0];
00112         set(v1, v2);
00113     }
00114     cvec_t(const void* p, size_t l) {
00115         _base = &_pair[0];
00116         set(p, l);
00117     }
00118     cvec_t(const cvec_t& v, size_t offset, size_t limit) {
00119         _base = &_pair[0];
00120         set(v, offset, limit);
00121     }
00122     ~cvec_t();
00123 
00124     void split(size_t l1, cvec_t& v1, cvec_t& v2) const;
00125     /// append {p,l} pairs from vector v, (first ptr is v + offset),
00126     ///  as needed to append at most nbytes
00127     cvec_t& put(const cvec_t& v, size_t offset, size_t nbytes);
00128     /// append { p, l } pair to this vector.
00129     cvec_t& put(const void* p, size_t l);
00130     /// append { p, l } pairs from v to this vector.
00131     cvec_t& put(const cvec_t& v);
00132 
00133     /// Clear this vector.
00134     cvec_t& reset()  {
00135         _cnt = _size = 0;
00136         return *this;
00137     }
00138     /// reset, then copy over all {p,l} pairs from v1 and v2
00139     cvec_t& set(const cvec_t& v1, const cvec_t& v2)  {
00140         return reset().put(v1).put(v2);
00141     }
00142     /// reset, then copy over all {p,l} pairs from v
00143     cvec_t& set(const cvec_t& v) {
00144         return reset().put(v);
00145     }
00146 
00147     /// reset, then install {p,l} pair
00148     cvec_t& set(const void* p, size_t l)  {
00149         return reset().put(p, l);
00150     }
00151 
00152     /// reset, then install {p,l} pairs as needed to capture limit 
00153     /// bytes starting at v + offset
00154     cvec_t& set(const cvec_t& v, size_t offset, size_t limit)  {
00155         return reset().put(v, offset, limit);
00156     }
00157 
00158 
00159     /// returns # bytes this vector references
00160     size_t size() const        {
00161         return _size;
00162     }
00163 
00164     /// Write from vector to p, no more than \a limit bytes
00165     size_t copy_to(void* p, size_t limit = 0x7fffffff) const;
00166     
00167     int cmp(const cvec_t& v, size_t* common_size = 0) const;
00168     int cmp(const void* s, size_t len) const;
00169 
00170     static int cmp(const cvec_t& v1,
00171                const cvec_t& v2, size_t* common_size = 0)  {
00172         return v1.cmp(v2, common_size);
00173     }
00174 
00175     /// return number of {p,l} pairs
00176     int count() const {return _cnt;}
00177 
00178     int  checksum() const;
00179     void calc_kvl(uint4_t& h) const;
00180     void init()         { _cnt = _size = 0; }  // re-initialize the vector
00181     // Creator of the vec has responsibility for delete[]ing anything that
00182     // was dynamically allocated in the array.  These are convenience methods
00183     // for holders of vec_ts that dynamically allocated all parts and want
00184     // them delete[]-ed.
00185     // vecdelparts() calls delete[] on all parts.
00186     // delparts() calls delete on all parts.
00187     // Both leave the vector re-initialized (0 parts)
00188     void vecdelparts()      {   while(_cnt-->0) { 
00189                                    delete[] _base[_cnt].ptr;
00190                                    _base[_cnt].ptr = NULL;
00191                                    _base[_cnt].len = 0;
00192                                 } 
00193                                 init();
00194                             }
00195     void delparts()         {   while(_cnt-->0) { 
00196                                    delete _base[_cnt].ptr;
00197                                    _base[_cnt].ptr = NULL;
00198                                    _base[_cnt].len = 0;
00199                                 } 
00200                                 init();
00201                             }
00202 
00203     bool is_pos_inf() const        { return this == &pos_inf; }
00204     bool is_neg_inf() const        { return this == &neg_inf; }
00205     bool is_null() const        { return size() == 0; }
00206 
00207     friend inline bool operator<(const cvec_t& v1, const cvec_t& v2);
00208     friend inline bool operator<=(const cvec_t& v1, const cvec_t& v2);
00209     friend inline bool operator>=(const cvec_t& v1, const cvec_t& v2);
00210     friend inline bool operator>(const cvec_t& v1, const cvec_t& v2);
00211     friend inline bool operator==(const cvec_t& v1, const cvec_t& v2);
00212     friend inline bool operator!=(const cvec_t& v1, const cvec_t& v2);
00213 
00214     friend ostream& operator<<(ostream&, const cvec_t& v);
00215     friend istream& operator>>(istream&, cvec_t& v);
00216 
00217     static cvec_t pos_inf;
00218     static cvec_t neg_inf;
00219 
00220 private:
00221     // disabled
00222     cvec_t(const cvec_t& v);
00223     // determine if this is a large vector (one where extra space
00224     // had to be malloc'd 
00225     bool _is_large() const {return _base != &_pair[0];}
00226 
00227     // determine max number of elements in the vector
00228     int  _max_cnt() const {
00229         return (int)(_is_large() ? _pair[0].len : (int)max_small);
00230     }
00231     // grow vector to have total_cnt elements
00232     void _grow(int total_cnt);
00233 
00234     // disabled
00235     //    cvec_t(const cvec_t& v);
00236     cvec_t& operator=(cvec_t);
00237 
00238     size_t recalc_size() const;
00239     bool   check_size() const;
00240 
00241 public:
00242     bool is_zvec() const { 
00243 #if W_DEBUG_LEVEL > 2
00244         if(count()>0) {
00245             if(_pair[0].ptr == zero_location) {
00246                 w_assert3(count() == 1);
00247             }
00248         }
00249 #endif
00250         return (count()==0)
00251                 ||
00252                 (count() == 1 && _pair[0].ptr == zero_location);
00253     }
00254 };
00255 
00256 /**\brief  Vector: a set of {pointer,length} pairs for memory manipulation.
00257  *
00258  * This class is used throughout the storage manager and in its API
00259  * for copy-in and copy-out. 
00260  */
00261 class vec_t : public cvec_t {
00262 public:
00263     /// Construct empty vector.
00264     vec_t() : cvec_t()        {};
00265     /// Construct a vector that combines two others.
00266     vec_t(const cvec_t& v1, const cvec_t& v2) : cvec_t(v1, v2)  {};
00267     /// Construct a vector from a memory location and a length.
00268     vec_t(const void* p, size_t l) : cvec_t(p, l)        {};
00269     /// Construct a vector from a memory location + offset and a length.
00270     vec_t(const vec_t& v, size_t offset, size_t limit)
00271         : cvec_t(v, offset, limit)        {};
00272 
00273 
00274     /**\brief Overwrites the data area to which the vector points.
00275      *
00276      * Scatter limit bytes of data from the location at p
00277      * into the locations identified by this vector.
00278      */
00279     const vec_t& copy_from(
00280         const void* p,
00281         size_t limit,
00282         size_t offset = 0) const;        // offset tells where
00283                                 //in the vec to begin to copy
00284     
00285     /**\brief Overwrites the data area to which the vector points.
00286      *
00287      * Write data from the vector v
00288      * into the locations identified by this vector.
00289      */
00290     vec_t& copy_from(const cvec_t& v);
00291 
00292     /**\brief Overwrites the data area to which the vector points.
00293      *
00294      * Write data from the vector v, starting at the given offset
00295      * from the start of vector v,
00296      * into the locations identified by this vector.
00297      */
00298     vec_t& copy_from(
00299         const cvec_t& v,
00300         size_t offset,                // offset in v
00301         size_t limit,                // # bytes
00302         size_t myoffset = 0);        // offset in this
00303 
00304     /// Return the pointer from the {pointer, length} pair at the given index.
00305     CADDR_T       ptr(int index) const { return (index >= 0 && index < _cnt) ? 
00306                                         _base[index].ptr : (CADDR_T) NULL; }
00307     /// Return the length from the {pointer, length} pair at the given index.
00308     size_t        len(int index) const { return (index >= 0 && index < _cnt) ? 
00309                                         _base[index].len : 0; }
00310 
00311     /**\cond skip */
00312     /// Lets you reformat the vector into "result" with maximum-sized
00313     // chunks.
00314     void mkchunk( int maxsize, // max size of result vec
00315                 int skip,                 // # skipped in *this
00316                 vec_t        &result      // provided by the caller
00317     ) const;
00318     /**\endcond skip */
00319 
00320     /// A constant vector representing infinity. Used for key-value pairs, scans.
00321     static vec_t& pos_inf;
00322     /// A constant vector representing negative infinity. Used for key-value pairs, scans.
00323     static vec_t& neg_inf;
00324 
00325  private:
00326     // disabled
00327     vec_t(const vec_t&) : cvec_t()  {
00328       cerr << "vec_t: disabled member called" << endl;
00329       cerr << "failed at \"" << __FILE__ << ":" << __LINE__ << "\"" << endl;
00330       W_FATAL (fcINTERNAL);
00331     }
00332  private:
00333     // disabled
00334     vec_t& operator=(vec_t);
00335 
00336 };
00337 
00338 inline bool operator<(const cvec_t& v1, const cvec_t& v2)
00339 {
00340     return v1.cmp(v2) < 0;
00341 }
00342 
00343 inline bool operator<=(const cvec_t& v1, const cvec_t& v2)
00344 {
00345     return v1.cmp(v2) <= 0;
00346 }
00347 
00348 inline bool operator>=(const cvec_t& v1, const cvec_t& v2)
00349 {
00350     return v1.cmp(v2) >= 0;
00351 }
00352 
00353 inline bool operator>(const cvec_t& v1, const cvec_t& v2)
00354 {
00355     return v1.cmp(v2) > 0;
00356 }
00357 
00358 inline bool operator==(const cvec_t& v1, const cvec_t& v2)
00359 {
00360     return (&v1==&v2) || v1.cmp(v2) == 0;
00361 }
00362 
00363 inline bool operator!=(const cvec_t& v1, const cvec_t& v2)
00364 {
00365     return ! (v1 == v2);
00366 }
00367 
00368 
00369 /**\brief A vec_t that represents a batch of zeros.
00370  *
00371  * This is used when we know we need only a (read-only) vector
00372  * of zeroes because it's a one-time constructed vector pointing
00373  * to a fixed-location at "zero_location".
00374  * It doesn't require any real zeroes at that location; it behaves
00375  * as if it really were a vector.
00376  */
00377 class zvec_t : public vec_t {
00378 public:
00379     zvec_t() : vec_t(zero_location,0)        {};
00380     zvec_t(size_t l) : vec_t(zero_location, l)        {};
00381     zvec_t &put(size_t l) { reset().put(zero_location,l); return *this; }
00382 private:
00383     // disabled
00384     zvec_t(const zvec_t&) :vec_t(zero_location, 0)  {}
00385     zvec_t &operator=(zvec_t);
00386     // disabled other constructors from vec_t
00387     zvec_t(const cvec_t& v1, const cvec_t& v2);/* {} */
00388     zvec_t(const void* p, size_t l); // {}
00389     zvec_t(const vec_t& v, size_t offset, size_t limit); // {}
00390 };
00391 
00392 /*<std-footer incl-file-exclusion='VEC_T_H'>  -- do not edit anything below this line -- */
00393 
00394 #endif          /*</std-footer>*/

Generated on Wed Jul 7 17:22:32 2010 for Shore Storage Manager by  doxygen 1.4.7