home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / yacl-012.zip / io / slotfile.h < prev   
C/C++ Source or Header  |  1995-04-08  |  13KB  |  330 lines

  1.  
  2. #ifndef _slotfile_h_
  3. #define _slotfile_h_
  4.  
  5.  
  6.  
  7. /*
  8.  *
  9.  *          Copyright (C) 1994, M. A. Sridhar
  10.  *  
  11.  *
  12.  *     This software is Copyright M. A. Sridhar, 1994. You are free
  13.  *     to copy, modify or distribute this software  as you see fit,
  14.  *     and to use  it  for  any  purpose, provided   this copyright
  15.  *     notice and the following   disclaimer are included  with all
  16.  *     copies.
  17.  *
  18.  *                        DISCLAIMER
  19.  *
  20.  *     The author makes no warranties, either expressed or implied,
  21.  *     with respect  to  this  software, its  quality, performance,
  22.  *     merchantability, or fitness for any particular purpose. This
  23.  *     software is distributed  AS IS.  The  user of this  software
  24.  *     assumes all risks  as to its quality  and performance. In no
  25.  *     event shall the author be liable for any direct, indirect or
  26.  *     consequential damages, even if the  author has been  advised
  27.  *     as to the possibility of such damages.
  28.  *
  29.  */
  30.  
  31.  
  32.  
  33. // This is  a binary  file that manages   fixed-length records, called {\it
  34. // slots.} Each slot contains  a fixed-length byte  string, whose length is
  35. // determined  the  first  time  the  file  is  created.  Also, each   slot
  36. // associated with a distinct file-specific {\it  handle\/} (a long value).
  37. // {\tt SlottedFile} is an abstract class, and particular concrete versions
  38. // of it may be constructed; {\tt PrivateSlottedFile} is one such.
  39. // 
  40. // The SlottedFile class provides for adding  and deleting records, as well
  41. // as storing and retrieving the associated  data.  When a record is added,
  42. // a file-specific  handle is  returned which  can  be used for  subsequent
  43. // reference to that record. The returned handle is always nonzero.
  44. //
  45. // The class also provides methods for access and modification of a
  46. // header area in the file  where a client of this class may maintain
  47. // data. The size of this header area is determined by the derived
  48. // class, such as {\tt PrivateSlottedFile}.
  49. //
  50. // A    user  of this   object  may   delete  a  record,   thus freeing the
  51. // corresponding slot;  when this is done,  the  handle associated with the
  52. // slot is invalid, but this does not affect the handles of other allocated
  53. // slots. Once a slot  is freed, however,  it is illegal  to attempt to use
  54. // its handle.
  55. // 
  56. // The implementation    uses a 2-level   bitmap-based  representation, and
  57. // therefore  limits  the total  number of  records  that a SlottedFile can
  58. // contain to  about   768,000,000. This   representation   is designed  to
  59. // minimize I/O  on  the stream; it  guarantees  that every  method of this
  60. // class requires  at most two  read and three write  operations (including
  61. // read/write of  the record itself), regardless  of file  size.  For small
  62. // files (with  fewer than 4096 records),  each method requires at most one
  63. // read and two write operations. This class is  therefore  well suited for
  64. // storing large tables in relational databases.
  65. //
  66. //    The implementation also  ensures  that the  file occupies  as  little
  67. // additional  space  as  possible, by  truncating   the  file  after every
  68. // deletion so that there is no unused space at its end.
  69.  
  70.  
  71.  
  72.  
  73.  
  74. #if defined(__GNUC__)
  75. #pragma interface
  76. #endif
  77.  
  78.  
  79. #include "io/binfile.h"
  80. #include "base/bitset.h"
  81.  
  82.  
  83. typedef ulong CL_SlottedFileHandle;
  84. class CL_EXPORT CL_SlottedFileHeader;
  85.  
  86. class CL_EXPORT CL_SlottedFile: public CL_Object {
  87.  
  88. public:
  89.     
  90.     CL_SlottedFile (CL_Stream& data_store, bool report_errors = TRUE);
  91.     // Constructor: specifies the stream to use. This stream must
  92.     // exist at the time this constructor is executed. The second
  93.     // parameter specifies whether errors should be reported via the
  94.     // {\tt CL_Error} class.
  95.  
  96.     ~CL_SlottedFile ();
  97.     
  98.  
  99.     // ---------------------- Querying --------------------------
  100.     
  101.     virtual long SlotSize () const
  102.         {return _slotSize;};
  103.     // Return the slot size for this slotted file, in bytes.
  104.  
  105.     virtual bool IsValid (CL_SlottedFileHandle h) const;
  106.     // Is the given handle a valid (allocated) one?
  107.  
  108.     virtual long SlotsAllocated () const;
  109.     // Return the total number of slots currently allocated.
  110.  
  111.     short HeaderSize () const {return _userHeaderSize;};
  112.     // Return the size (in bytes) of the user-defined header segment.
  113.     
  114.     // --------------------- Slot manipulation --------------------
  115.  
  116.     virtual CL_SlottedFileHandle AllocateSlot ();
  117.     // Allocate a slot, and return its handle. The contents of the slot
  118.     // are undefined.
  119.     
  120.     virtual CL_SlottedFileHandle AddRecord (uchar* record);
  121.     // Allocate a slot, copy the given record into the slot, and return
  122.     // the handle for the slot. Return a zero handle on error, e.g. I/O error
  123.     // or unavailability of slots. 
  124.  
  125.     virtual bool RetrieveRecord (CL_SlottedFileHandle handle,
  126.                                  uchar* record) const;
  127.     // Retrieve the record at the given handle, and return it in the second
  128.     // parameter; the latter is assumed to point to a byte block of size
  129.     // at least as large as the record length. The function returns TRUE on
  130.     // success and FALSE if an invalid handle was specified or an I/O error
  131.     // occurred.
  132.  
  133.     virtual bool ModifyRecord (CL_SlottedFileHandle handle, uchar* record);
  134.     // Overwrite the record at the given handle with the value specified in
  135.     // the second parameter; the latter is assumed to point to a byte block
  136.     // of size at least as large as the record length. The function returns
  137.     // TRUE on success and FALSE if an invalid handle was specified or an
  138.     // I/O error occurred.
  139.     
  140.     virtual bool DeleteRecord (CL_SlottedFileHandle handle);
  141.     // Delete the record at the given handle. The handle must be currently
  142.     // allocated. Return TRUE on success, FALSE on error (e.g., I/O error or
  143.     // invalid handle). After the deletion, the handle becomes available for
  144.     // allocation to a subsequent {\tt AddRecord} or {\tt AllocateSlot}
  145.     // request.
  146.  
  147.     // ------------------- Manipulating user headers ------------------
  148.  
  149.     virtual bool ReadHeader (uchar* header) const;
  150.     // Read and return the user-defined header in the file. The
  151.     // parameter must point to a large-enough segment of memory. Returns
  152.     // TRUE on success, FALSE on i/o error.
  153.  
  154.     virtual bool WriteHeader (uchar* header);
  155.     // Write the parameter into the user-defined header. Returns
  156.     // TRUE on success, FALSE on i/o error.
  157.  
  158.     // ------------------------ Iteration ---------------------------
  159.     
  160.     virtual CL_SlottedFileHandle FirstRecord (uchar* record) const;
  161.     // Return the first record in series, and its handle.
  162.  
  163.     virtual CL_SlottedFileHandle NextRecord (CL_SlottedFileHandle h,
  164.                                              uchar* record) const;
  165.     // Return the next record in series after the one with the given handle,
  166.     // in the parameter, and
  167.     // return its handle as the function value. Return 0 when there are no
  168.     // more records. 
  169.  
  170.     // ------------------------ Static functions -----------------------
  171.  
  172.     static long Valid (const char* path);
  173.     // Determine whether the given path specifies a valid slotted file,
  174.     // and if so, return its slot size; if not, return 0.
  175.     
  176.  
  177.     // ------------------ Basic functions ------------------------------
  178.     
  179.     const char* ClassName () const {return "CL_SlottedFile";};
  180.  
  181.     CL_ClassId ClassId () const { return _CL_SlottedFile_CLASSID;};
  182.  
  183.     // ------------------- End public protocol ------------------------ 
  184.  
  185.  
  186. protected:
  187.  
  188.     // ----- Instance variables -------
  189.     
  190.     CL_SlottedFileHeader* _header;
  191.     CL_Stream&            _file;           // The file we use
  192.     long                  _slotSize;       // Slot size: set by derived class
  193.     short                 _userHeaderSize; // User-defined header's size:
  194.                                            // set by derived class
  195.     bool                  _reportErrors;
  196.  
  197.     
  198.     // ------ Protected methods ----
  199.     
  200.     CL_Offset             _BlockBitmapOffset (ushort index) const;
  201.  
  202.     CL_Offset             _RecordOffset (CL_SlottedFileHandle) const;
  203.  
  204.     CL_SlottedFileHandle  _GetSlot();
  205.  
  206.     void                  _DoError (const char*,
  207.                                     CL_SlottedFileHandle h = 0) const;
  208.  
  209.     virtual bool         _ReadHeader  (CL_SlottedFileHeader& hdr) const = 0;
  210.     // Read and write the header: for derived classes to override. These are
  211.     // const methods because they are used in most methods, but do not
  212.     // affect the abstract object's state, since they are only used for
  213.     // bookkeeping.
  214.  
  215.     virtual bool         _WriteHeader (const CL_SlottedFileHeader&) const = 0;
  216.     
  217.     friend class CL_SlottedFileIterator;
  218. };
  219.  
  220.  
  221.  
  222. // SlottedFileIterator allows iteration over the given file.
  223.  
  224. class CL_SlottedFileIterator {
  225.  
  226. public:
  227.     CL_SlottedFileIterator (const CL_SlottedFile& file);
  228.     // Constructor: tell which SlottedFile to inspect.
  229.  
  230.     CL_SlottedFileIterator (const CL_SlottedFileIterator& iter);
  231.     // Copy constructor.
  232.  
  233.     ~CL_SlottedFileIterator ();
  234.     // Destructor.
  235.     
  236.     virtual void Reset ();
  237.     // Reset the iteration to the beginning of the file.
  238.  
  239.     virtual CL_SlottedFileHandle Next (uchar* record);
  240.     // Return the next record in sequence, in the parameter, and
  241.     // return its handle as the function value. Return 0 when there are no
  242.     // more records. The records are returned in order of their occurrence
  243.     // in the file.
  244.  
  245. protected:
  246.     CL_BitSet               _root, _block;
  247.     CL_BitSetIterator       _rootIter, _blockIter;
  248.     short                   _blockIndex;
  249.     const CL_SlottedFile&   _sfile;
  250.     CL_SlottedFileHeader*   _header;
  251.  
  252. };
  253.  
  254.  
  255.  
  256. // The PrivateSlottedFile is an implementation of the SlottedFile that
  257. // assumes that the file will be used exclusively by one process and not
  258. // shared by multiple processes.
  259.  
  260. class CL_EXPORT CL_PrivateSlottedFile: public CL_SlottedFile {
  261.  
  262. public:
  263.     // ---------------- Construction and destruction -------------------
  264.     
  265.     CL_PrivateSlottedFile (const char* path, bool report_errors = TRUE);
  266.     // Open an existing slotted file with the given path name. This
  267.     // constructor exits with a fatal error if either the file does not
  268.     // exist or does not contain the correct headers; therefore, it is
  269.     // advisable to use the {\tt Valid()} method before invoking it.
  270.     //
  271.     //     The second parameter specifies what to to do in case of I/O
  272.     // errors. The default is to use the {\tt CL_Error::Warning} call to issue
  273.     // error messages; if reportErrors is FALSE, such warnings will not
  274.     // be issued.
  275.  
  276.     CL_PrivateSlottedFile (const char* path, long record_size,
  277.                            short user_header_size = 0,
  278.                            bool report_errors = TRUE);
  279.     // Create a new slotted file with specified path name and
  280.     // record size. Overwrite any existing file with the same path name.
  281.     // The third parameter specifies the size of the user header area to
  282.     // be set apart in the file.
  283.  
  284.     CL_PrivateSlottedFile (CL_Stream& file, bool report_errors = TRUE);
  285.     // Alternate constructors: similar to the above, except that the given
  286.     // stream is used as data repository; this stream is {\it not\/}
  287.     // owned by the SlottedFile, and will not be destroyed by the
  288.     // SlottedFile's destructor.
  289.  
  290.     CL_PrivateSlottedFile (CL_Stream& file, long record_size,
  291.                            short user_header_size = 0,
  292.                            bool report_errors = TRUE);
  293.  
  294.     virtual ~CL_PrivateSlottedFile();
  295.     // Destructor.
  296.  
  297.  
  298. protected:
  299.     CL_BinaryFile*        _ourFile; // Created by the first two constructors
  300.     bool                  _weOwnIt; // TRUE if one of the first two
  301.                                     // constructors was used
  302.  
  303.     bool _ReadHeader  (CL_SlottedFileHeader&) const;
  304.  
  305.     bool _WriteHeader (const CL_SlottedFileHeader&) const;
  306.  
  307. };
  308.  
  309.  
  310.  
  311.  
  312. // class CL_SharedSlottedFile:  public CL_SlottedFile {
  313. // 
  314. // public:
  315. //     CL_SharedSlottedFile () {NotImplemented ("SharedSlottedFile");};
  316. // 
  317. //     ~CL_SharedSlottedFile ();
  318. // 
  319. //     char* ClassName () const {return "CL_SharedSlottedFile";};
  320. //     
  321. // protected:
  322. //     bool _ReadHeader  () const;
  323. // 
  324. //     bool _WriteHeader () const;
  325. // 
  326. // };
  327.  
  328.     
  329. #endif
  330.