Bdb packages | Design docs | Source docs | Guidelines | Recent releases

Search | Site Map .

Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

/BdbBitMap/BdbDimensionContext.cc

Go to the documentation of this file.
00001 //------------------------------------------------------------------------------
00002 // File:
00003 //      BdbDimensionContext.cc
00004 //
00005 // Description:
00006 //       Transient class representing one dimension context.
00007 //
00008 // Environment:
00009 //      Software developed for the BaBar Detector at the SLAC B-Factory
00010 //
00011 // Author List:
00012 //      Jacek Becla, Igor Gaponenko           Original Authors
00013 //
00014 // Copyright Information:
00015 //      Copyright (C) 1997-98      Stanford Linear Accelerator Center
00016 //
00017 //------------------------------------------------------------------------------
00018 
00019 //-----------------------
00020 // This Class's Header --
00021 //-----------------------
00022 
00023 #ifndef BDBDIMENSIONCONTEXT_HH
00024 #include "BdbBitMap/BdbDimensionContext.hh"
00025 #endif
00026 
00027 //-------------------------------
00028 // Collaborating Class Headers --
00029 //-------------------------------
00030 
00031 
00032 
00033 
00034 //---------------
00035 // C++ Headers --
00036 //---------------
00037 
00038 #include <iostream.h>
00039 
00040 //---------------------
00041 // Local definitions --
00042 //---------------------
00043 
00044 static const d_ULong BITS_31 = 0x80000000 ;
00045 static const d_ULong BITS_30 = 0x40000000 ;
00046 static const d_ULong BITS_31_30 = ( BITS_31 | BITS_30 ) ;
00047 static const d_ULong BITS_29_00 = 0x3FFFFFFF ;
00048 
00049 // =====================================================
00050 // ========                                    =========
00051 // ========    constructor(s) / destructor     =========
00052 // ========                                    =========
00053 // =====================================================
00054 
00055 /**  
00056  **  Default Constructor
00057  **/
00058 
00059 BdbDimensionContext::BdbDimensionContext()
00060 {
00061     _isInitialized = false ;
00062     _numBins = 0 ;
00063     _isCompressed = false ;
00064 }
00065 
00066 
00067 /**  
00068  **  Destructor
00069  **/
00070 
00071 BdbDimensionContext::~BdbDimensionContext()
00072 {
00073   // Flash the vectors if the context was initialized
00074   // and the vectors are not empty.
00075 
00076     if ( _isInitialized ) {
00077 
00078       // If we use compressing then we have to flash compressed
00079       // vectors first.
00080 
00081         if ( _isCompressed ) {
00082             flashComprVectors() ;
00083         }
00084 
00085       // And after that we will flush the information
00086       // remaining in tempoary vectors.
00087 
00088         if ( _countTmpVector32 ) {
00089             flashTmpVectors() ;
00090         }
00091     }
00092 }
00093 
00094 /**
00095  **  Initialize context object.
00096  **/
00097 
00098 BdbStatus
00099 BdbDimensionContext::init(BdbRef(BdbBMDimension)& dimRef, d_Boolean isCompressed)
00100 {
00101     BdbStatus status ;
00102     d_ULong i ;
00103 
00104   // Check if not initialized yet.
00105 
00106     if ( _isInitialized ) {
00107         return BdbcError ;
00108     }
00109 
00110   // Initialize some context variables.
00111 
00112     _dimRef       = dimRef ;
00113     _numBins      = _dimRef->getNumBins() ;
00114     _isCompressed = isCompressed ;
00115 
00116   // Set proper size of the bins' references array,
00117   // then set the values of references.
00118 
00119     status = _binRef.resize(_numBins) ;
00120     if ( status != BdbcSuccess ) {
00121         return status ;
00122     }
00123 
00124     for ( i = 0 ; i < _numBins ; i++ ) {
00125         status = _dimRef->getBin(i, _binRef[i], BdbcUpdate) ;
00126         if ( status != BdbcSuccess ) {
00127             return BdbcError ;
00128         }
00129     }
00130 
00131   // Set the proper size of temporary vectors.
00132 
00133     status = _tmpVector32.resize(_numBins) ;
00134     if ( status != BdbcSuccess ) {
00135         return status ;
00136     }
00137     status = _comprInProgress.resize(_numBins) ;
00138     if ( status != BdbcSuccess ) {
00139         return status ;
00140     }
00141     status = _comprZeroes.resize(_numBins) ;
00142     if ( status != BdbcSuccess ) {
00143         return status ;
00144     }
00145     status = _comprCounter.resize(_numBins) ;
00146     if ( status != BdbcSuccess ) {
00147         return status ;
00148     }
00149 
00150   // Clear the contens of temporary and compressing
00151   // vectors before to be sure that the context is successfuly
00152   // initialized.
00153 
00154     clearTmpVectors() ;
00155     clearComprVectors() ;
00156 
00157   // Done.
00158 
00159     _isInitialized = true ;
00160 
00161     return BdbcSuccess ;
00162 }
00163 
00164 
00165 /**
00166  **  Find a proper bin number.
00167  **/
00168 
00169 d_ULong
00170 BdbDimensionContext::findBinNumber(d_Float value) const
00171 {
00172     d_ULong bin = -1 ;
00173 
00174     // -- For the beginning just check for underflow/overflow
00175     //    condition. In this case we should assign the neares
00176     //    (border) bin.
00177 
00178     if ( value <= _dimRef->getMinValue()) {
00179         return 0 ;
00180     }
00181     if ( value >= _dimRef->getMaxValue()) {
00182         return _numBins - 1 ;
00183     }
00184 
00185     // -- For more complicated situation we scan through the
00186 
00187     for ( d_ULong i = 0 ; i < _numBins ; i++ ) {
00188         if (( value >= _binRef[i]->getMinValue())&&( value < _binRef[i]->getMaxValue())) {
00189           bin = i ;
00190           break ;
00191         }
00192     }
00193 
00194     return bin ;
00195 }
00196 
00197 /**
00198  **  Initialize the contents of the temporary and
00199  **  compressing vectors by zeroes.
00200  **/
00201 
00202 void
00203 BdbDimensionContext::clearTmpVectors()
00204 {
00205     for ( d_ULong i = 0 ; i < _numBins ; i++ ) {
00206         _tmpVector32[i] = 0 ;
00207     }
00208     _countTmpVector32 = 0 ;
00209 }
00210 
00211 void
00212 BdbDimensionContext::clearComprVectors()
00213 {
00214     for ( d_ULong i = 0 ; i < _numBins ; i++ ) {
00215         _comprInProgress[i] = false ;
00216     }
00217 }
00218 
00219 /**
00220  **  Flash the contents of the compressed vector
00221  **  into bits array.
00222  **/
00223 
00224 BdbStatus
00225 BdbDimensionContext::flashComprVector(d_ULong bin)
00226 {
00227     BdbStatus status ;
00228     d_ULong data = ( BITS_29_00 & _comprCounter[bin] ) ;
00229 
00230   // Check for consistency.
00231 
00232     if ( ! _comprInProgress[bin] ) {
00233         cout << "BdbDimensionContext::flashComprVector - unexpected internal error." << endl ;
00234         return BdbcError ;
00235     }
00236 
00237   // Set the higher bits (31,30) into proper state.
00238 
00239     if ( _comprZeroes[bin] ) {
00240         data = BITS_31    | data ;
00241     } else {
00242         data = BITS_31_30 | data ;
00243     }
00244                                      
00245   // Uppend new value by the end of the bit string.
00246 
00247     status = _binRef[bin]->extendBy(data, 0) ;
00248     if ( BdbcSuccess != status ) {
00249         return status ;
00250     }
00251 
00252     _comprInProgress[bin] = false ;
00253 
00254     return BdbcSuccess ;
00255 }
00256 
00257 BdbStatus
00258 BdbDimensionContext::flashComprVectors()
00259 {
00260     d_ULong i ;
00261     BdbStatus status ;
00262 
00263     for ( i = 0 ; i < _numBins ; i++ ) {
00264 
00265         if ( _comprInProgress[i] ) {
00266 
00267             status = flashComprVector(i) ;
00268             if ( BdbcSuccess != status ) {
00269                 return status ;
00270             }
00271         }
00272     }
00273 
00274     return BdbcSuccess ;
00275 }
00276 
00277 /**
00278  **  Flash the contents of the temporary
00279  **  into bits arrays.
00280  **/
00281 
00282 BdbStatus
00283 BdbDimensionContext::flashTmpVector(d_ULong bin)
00284 {
00285     return _binRef[bin]->extendBy(_tmpVector32[bin], _countTmpVector32) ;
00286 }
00287 
00288 BdbStatus
00289 BdbDimensionContext::flashTmpVectors()
00290 {
00291     BdbStatus status ;
00292     d_ULong i ;
00293 
00294   // The flashing procedure depends on if we are doing
00295   // or not doing the vectors compression:
00296 
00297     if ( _isCompressed ) {
00298 
00299       // COMPRESSING:
00300 
00301         for ( i = 0 ; i < _numBins ; i++ ) {
00302 
00303           // Possible to compress?
00304           // Here we check if we have 30 "0"-es or "1"-s.
00305 
00306             if (( _countTmpVector32 == 30 ) &&
00307                 (( BITS_29_00 == ( BITS_29_00 & _tmpVector32[i] )) || ( ! _tmpVector32[i] ))) {
00308 
00309               // OK. We can compress this word.
00310               // Now we have to understand whether the compressing
00311               // is already in progress.
00312 
00313                 if ( _comprInProgress[i] ) {
00314 
00315                   // Are we compressing the same ("0" or "1")?
00316 
00317                     if (((   _comprZeroes[i] ) && ( ! _tmpVector32[i] ))
00318                                                ||
00319                         (( ! _comprZeroes[i] ) && (   _tmpVector32[i] ))) {
00320 
00321                       // Yes. We are already compressing the same.
00322                       // Here we just update the compression counter.
00323 
00324                         _comprCounter[i] += 30 ;
00325 
00326                     } else {
00327 
00328                       // Since we were compressing "something" different,
00329                       // first we have to flash it and then start
00330                       // compressing new stuff.
00331 
00332                         status = flashComprVector(i) ;
00333                         if ( status != BdbcSuccess ) {
00334                             return status ;
00335                         }
00336 
00337                         _comprInProgress[i] = true ;
00338                         _comprZeroes[i]     = ! _tmpVector32[i] ;
00339                         _comprCounter[i]    = 30 ;
00340 
00341                     }
00342 
00343                 } else {
00344 
00345                   // NO compressing in progress. We start the
00346                   // new one.
00347 
00348                     _comprInProgress[i] = true ;
00349                     _comprZeroes[i]     = ! _tmpVector32[i] ;
00350                     _comprCounter[i]    = 30 ;
00351                 }
00352 
00353             } else {
00354 
00355               //  Compressing is not possible.
00356               //  If we are already compressing somthing, we should
00357               //  flash compression buffer before to flush the temporary one.
00358 
00359                 if ( _comprInProgress[i] ) {
00360                     status = flashComprVector(i) ;
00361                     if ( status != BdbcSuccess ) {
00362                         return status ;
00363                     }
00364                 }
00365 
00366                 status = flashTmpVector(i) ;
00367                 if ( status != BdbcSuccess ) {
00368                     return status ;
00369                 }
00370             }
00371         }
00372     } else {
00373 
00374       // NOT COMPRESSING:
00375       //
00376       //   the contents of the temporary vectors is directly uppended
00377       //   to the end of variable sized bits array of their bin.
00378 
00379         for ( i = 0 ; i < _numBins ; i++ ) {
00380 
00381             status = flashTmpVector(i) ;
00382             if ( status != BdbcSuccess ) {
00383                 return status ;
00384             }
00385         }
00386     }
00387 
00388   // Clear contents of the temporary vectors in order
00389   // to prepare them for next bits.
00390 
00391     clearTmpVectors() ;
00392 
00393     return BdbcSuccess ;
00394 }
00395 
00396 /**
00397  **  Add next value to the index database through context
00398  **/
00399 
00400 BdbStatus
00401 BdbDimensionContext::add(d_Float value)
00402 {
00403     BdbStatus status ;
00404     d_ULong i ;
00405 
00406     // -- Check if initialized.
00407 
00408     if ( ! _isInitialized ) {
00409         return BdbcError ;
00410     }
00411 
00412     // -- Find a proper bin.
00413 
00414     d_ULong bin = findBinNumber(value) ;
00415 
00416     if ( bin == -1 ) {
00417         return BdbcError ;
00418     }
00419 
00420     // -- Add the bits to the temporary cache vectors.
00421 
00422     for ( i = 0 ; i < _numBins ; i++ ) {
00423 
00424         d_ULong mask = ( 1 & ( i == bin )) << _countTmpVector32 ;
00425 
00426         _tmpVector32[i] = _tmpVector32[i] | mask ;
00427     }
00428     _countTmpVector32++ ;
00429 
00430     // -- Flash the cache vectors if they are full.
00431 
00432     if ( _countTmpVector32 >= 30 ) {
00433         status = flashTmpVectors() ;
00434         if ( status != BdbcSuccess ) {
00435             return status ;
00436         }
00437     }
00438 
00439     return BdbcSuccess ;
00440 }
00441 
00442 /////////////////
00443 // End Of File //
00444 /////////////////

 


BaBar Public Site | SLAC | News | Links | Who's Who | Contact Us

Page Owner: Jacek Becla
Last Update: October 04, 2002