casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SSMStringHandler.h
Go to the documentation of this file.
00001 //# SSMStringHandler.h: Store strings in the Standard Storage Manager
00002 //# Copyright (C) 2000
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: SSMStringHandler.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $
00027  
00028 #ifndef TABLES_SSMSTRINGHANDLER_H
00029 #define TABLES_SSMSTRINGHANDLER_H
00030  
00031  
00032 //# Includes
00033 #include <casa/aips.h>
00034 #include <casa/OS/Conversion.h>
00035 #include <casa/BasicSL/String.h>
00036 #include <casa/Arrays/Array.h>
00037 
00038 namespace casa { //# NAMESPACE CASA - BEGIN
00039 
00040 //# Forward Declarations.
00041 class SSMBase;
00042 
00043 
00044 // <summary>
00045 // Store strings in the Standard Storage Manager.
00046 // </summary>
00047 
00048 // <use visibility=local>
00049 
00050 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tSSMStringHandler.cc">
00051 // </reviewed>
00052 
00053 // <prerequisite>
00054 //# Classes you should understand before using this one.
00055 //   <li> <linkto class=SSMBase>SSMBase</linkto>
00056 // </prerequisite>
00057 
00058 // <etymology>
00059 // SSMStringHandler handles strings for the Standard Storage Manager.
00060 // </etymology>
00061 
00062 // <synopsis>
00063 // Variable length strings cannot be stored in the data bucket.
00064 // Only short (<8 characters) strings can be stored directly.
00065 // Class SSMStringhandler is used by the SSM to store strings in
00066 // so-called string buckets.
00067 // A string bucket has the following layout:
00068 // <ul>
00069 //  <li> The first Int is reserved to be used for the free bucket list.
00070 //  <li> <src>itsUsedLength</src> tells how many bytes have been used.
00071 //       Thus it tells the next free byte in the string part.
00072 //       In principle it always increases. Only if data are removed
00073 //       from the last part of the string part, it is decreased, thus
00074 //       the deleted part can be reused again.
00075 //  <li> <src>itsNDeleted</src> tells how many bytes of the string part
00076 //       are deleted (i.e. not used). Initially it is the length of the
00077 //       string part of the bucket (i.e. bucketsize minus 4 Ints).
00078 //       When a string is stored, its length is subtracted from itsNDeleted.
00079 //       When a string is removed, its length is added again.
00080 //       When the string part is deleted, the bucket is added to the
00081 //       free bucket list.
00082 //  <li> <src>itsNextBucket</src> tells the next bucket if the last
00083 //       entry in the bucket is continued in another bucket.
00084 //       Normally this field is -1 (meaning not continued), but long
00085 //       strings or string arrays might be continued in another bucket
00086 //       (and continued from there again).
00087 //  <li> The string part is a sequence of bytes containing the string
00088 //       data. When a value is to be stored, it will replace the current
00089 //       value if the new value is not longer. Otherwise the current
00090 //       value (if any) is deleted and the new value is appended to
00091 //       the end of the string part in the last bucket used.
00092 //       <p>
00093 //       For a scalar string only its characters are stored. Its length
00094 //       (and bucketnr and offset in string bucket) are stored in the data
00095 //       bucket.
00096 //       <br>
00097 //       A fixed length array is stored as an array of bytes. That byte
00098 //       array contains length-value pairs for each element of the array.
00099 //       The total length (and bucketnr and offset) are stored in the data
00100 //       bucket.
00101 //       <br>
00102 //       A variable length array is stored as the shape, a flag, optionally
00103 //       followed by the string array as length-value pairs (as above).
00104 //       The shape consists of the nr of dimensions followed by the
00105 //       length of each dimension. The flag indicates if a string array
00106 //       is actually stored. It is not if only the shape of the array
00107 //       is set, but no data put yet.
00108 // </ul>
00109 // SSMStringHandler keeps a copy of the current bucket in use to reduce
00110 // the number of accesses to the bucket cache.
00111 // <p>
00112 // It also keeps the bucket number of the last bucket where data were
00113 // added to. It tells which bucket to use when new data has to be stored.
00114 // </synopsis>
00115   
00116 //# <todo asof="$DATE:$">
00117 //# A List of bugs, limitations, extensions or planned refinements.
00118 //# </todo>
00119 
00120 class SSMStringHandler
00121 {
00122 public:
00123   // Default constructor initializes last string bucket to -1.
00124   SSMStringHandler (SSMBase* aBase);
00125 
00126   ~SSMStringHandler();
00127 
00128   // Set or get last string bucketnr.
00129   // Setting is needed when an existing table is opened.
00130   // <group>
00131   void setLastStringBucket (Int lastStringBucket);
00132   Int lastStringBucket() const;
00133   // </group>
00134 
00135   // Put a single string or an array of strings into a bucket.
00136   // If its length does not exceed the given length, it reuses
00137   // the currently used space (given by bucketnr and offset).
00138   // Otherwise it adds the data to the last string bucket.
00139   // It fills the offset and bucketnr where the data are stored and the
00140   // length occupied in the buckets.
00141   // An array of strings is flattened first (a la SSMColumn::writeString).
00142   // <br>
00143   // If <src>handleShape</src> is True (for variable shaped arrays), the
00144   // shape will be put first.
00145   // <group>
00146   void put (Int& bucketNr, Int& offset, Int& length, 
00147             const String& string);
00148   void put (Int& bucketNr, Int& offset, Int& length, 
00149             const Array<String>& string, Bool handleShape);
00150   // </group>
00151 
00152   // Put a single string or an array of strings into a bucket.
00153   // If its length does not exceed the given length, it reuses
00154   // the currently used space (given by bucketnr and offset).
00155   // Otherwise it adds the data to the last string bucket.
00156   // It fills the offset and bucketnr where stored and the
00157   // length occupied in the buckets.
00158   void putShape (Int& bucketNr, Int& offset, Int& length, 
00159                  const IPosition& aShape);
00160 
00161   // Get the shape in the given bucket and offset.
00162   // It sets the offset to the data right after the shape.
00163   // The IPosition object is resized as needed.
00164   void getShape (IPosition& aShape, Int bucket, Int& offset, Int length);
00165 
00166   // Remove data with the given length from a bucket.
00167   // If the data are continued in next bucket(s), they will be
00168   // removed there as well.
00169   void remove (Int bucketNr, Int offset, Int length);
00170 
00171   // Get a string or an array of strings.
00172   // The array must have the correct shape.
00173   // <src>handleShape</src> will be True for variable shaped arrays
00174   // indicating that the data are preceeded by the shape.
00175   // <group>
00176   void get (String& string, Int bucket, Int offset, Int length);
00177   void get (Array<String>& string, Int bucket, Int offset, 
00178             Int length, Bool handleShape);
00179   // </group>
00180 
00181   // Flush the currently used string bucket.
00182   void flush();
00183   
00184   // Initialize the StringHandler
00185   void init();
00186 
00187   // Resynchronize (after a table lock was acquired).
00188   // It clears the itsCurrentBucket variable to assure that buckets
00189   // are reread.
00190   void resync();
00191   
00192 private:
00193   // Forbid copy constructor and assignment.
00194   // <group>
00195   SSMStringHandler (const SSMStringHandler&);
00196   SSMStringHandler& operator= (const SSMStringHandler&);
00197   // </group>
00198 
00199   // Get the given bucket and make it current.
00200   // It first writes the current bucket if it has changed.
00201   // <br>
00202   // If <src>isNew</src> is True the bucket is new,
00203   // so the Ints at its beginning do not have to be interpreted.
00204   void getBucket (uInt bucketNr, Bool isNew=False);
00205 
00206   // Get a new bucket and make it current.
00207   // If <src>doConcat</src> is True, the new bucket is a continuation,
00208   // so <src>itsNextBucket</src> in the currently used bucket is filled
00209   // with the new bucket number.
00210   void getNewBucket (Bool doConcat);
00211 
00212   // Put the data with the given length at the end of the current bucket.
00213   // If they do not fit, they are continued in a new bucket.
00214   void putData (Int length, const Char* data);
00215 
00216   // Get the data with the given length from the curent bucket at the
00217   // given offset. If sets the offset to the byte after the data read.
00218   // Continuation buckets are followed (and made current).
00219   void getData (Int length, Char* data, Int& offset);
00220 
00221   // Replace the current data with the new data.
00222   // It is used by <src>put</src> after having assured that the
00223   // new length does not exceed the current one.
00224   // It follows continuation buckets as needed.
00225   // <group>
00226   void replace (Int bucketNr, Int offset, Int length, 
00227                 const String& string);
00228   void replace (Int bucketNr, Int offset, Int length, Int totalLength, 
00229                 const IPosition& aShape);
00230   void replace (Int bucketNr, Int offset, Int length, Int totalLength,
00231                 const Array<String>& string, Bool handleShape);
00232   void replaceData (Int& offset,Int length, const Char* data);
00233   // </group>
00234 
00235 
00236   SSMBase* itsSSMPtr;      // Pointer to SSMBase stucture
00237   Int   itsCurrentBucket;  // bucketnr of current string bucket (-1 is none)
00238   Int   itsLength;         // length of bucket in use (only the string part)
00239   Int   itsNDeleted;       // #bytes deleted from the string part of the bucket
00240   Int   itsUsedLength;     // #bytes used from the string part of the bucket
00241   Int   itsNextBucket;     // next bucket for long strings
00242   char* itsData;           // bucket string data
00243   char* itsIntBuf;         // buffer for initialisation params
00244   Bool  isChanged;         // has current bucket been changed?
00245   uInt  itsIntSize;        // size of integers in this system
00246   Int   itsLastBucket;     // last string bucket used
00247   uInt  itsStart;          // Start position of actual data in bucket
00248 };
00249 
00250 
00251 inline void SSMStringHandler::setLastStringBucket (Int lastStringBucket)
00252 { 
00253   itsLastBucket = lastStringBucket;
00254 }  
00255 
00256 inline Int SSMStringHandler::lastStringBucket() const
00257 { 
00258   return itsLastBucket; 
00259 }  
00260 
00261 
00262 
00263 } //# NAMESPACE CASA - END
00264 
00265 #endif