Rogue Wave banner
Previous fileTop of DocumentContentsIndex pageNext file
Essential Tools Module User's Guide

11.3 RWFileManager

Class RWFileManager allocates, deallocates, and coalesces free space in a disk file. This is done internally by maintaining on disk a linked-list of free space blocks. Two typedefs are used:

The type RWoffset is used for the offset within the file to the start of a storage space; RWspace is the amount of storage space required. The actual typedef may vary depending on the system you are using.

Class RWFile is a public base class of class RWFileManager; therefore, the public member functions of class RWFile are available to class RWFileManager.

11.3.1 Construction

The RWFileManager constructor has the prototype:

The argument is the name of the file that the RWFileManager is to manage. If it exists, it must contain a valid RWFileManager; otherwise, one will be created.

11.3.2 Member Functions

The class RWFileManager adds four additional member functions to those of class RWFile. They are:

  1. RWoffset allocate(RWspace s);

  2. Allocates s bytes of storage in the file, returning the offset to the start of the allocation.

  3. void deallocate(RWoffset t);

  4. Deallocates (frees) the storage space starting at offset t. This space must have been previously allocated by the function allocate().

  5. RWOffset endData();

  6. Returns the offset to the last data in the file.

  7. RWoffset start();

  8. Returns the offset from the start of the file to the first space ever allocated by RWFileManager, or returns RWNIL if no space has been allocated, which implies that this is a new file. RWNIL is a macro whose actual value is system dependent. Typically, it is -1L.

The statement:

uses F of RWFileManager to allocate the space required to store an object with the size of a double, and returns the offset to that space. To write the object to the disk file, you should seek to the allocated location and use Write(). It is an error to read or write to an unallocated location in the file.

It is your responsibility to maintain a record of the offsets necessary to read the stored object. To help you do this, the first allocation ever made by an RWFileManager is considered special and can be returned by member function start() at any time. The RWFileManager will not allow you to deallocate it. This first block will typically hold information necessary to read the remaining data, perhaps the offset of a root node, or the head of a linked-list.

11.3.3 Example

The following example shows the use of class RWFileManager to construct a linked-list of int s on disk. The source code is included in the buildspace\examples\tools directory as fmgrsave.cpp and fmgrrtrv.cpp. When using this example, you must type a carriage return after the last item you want to insert in order to guarantee that it will be added to the list. This is because different compilers handle the occurrence of an EOF on the cin stream differently.

Here is a line-by-line description of the program:

//1 Include the declarations for the class RWFileManager.
//2 The struct DiskNode is a link in the linked-list. It contains:
//3 the data (an int), and:
//4 the offset to the next link. RWoffset is typically typedef `d to a long int.
//5 This is the constructor for an RWFileManager. It will create a new file, called linklist.dat.
//6 Allocate space on the file to store the offset to the first link. This first allocation is considered special and will be saved by the RWFileManager. It can be retrieved at any time by using the member function start().
//7 Allocate space to store the first link. The member function allocate() returns the offset to this space. Since each DiskNode needs the offset to the next DiskNode, space for the next link must be allocated before the current link is written.
//8 Seek to the position to write the offset to the first link. Note that the offset to this position is returned by the member function start(). Note also that fm has access to public member functions of class RWFile, since class RWFileManager is derived from class RWFile.
//9 Write the offset to the first link.
//10 A loop to read integers and store them in a linked-list.
//11 Allocate space for the next link, storing the offset to it in the nextNode field of this link.
//12 Seek to the proper offset to store this link
//13 Write this link.
//14 Since we allocate the next link before we write the current link, the final link in the list has an offset to an allocated block that is not used. It must be handled as a special case.
//15 First, deallocate the final unused block.
//16 Next, reassign the offset of the final link to be RWNIL. When the list is read, this will indicate the end of the linked list. Finally, rewrite the final link with the correct information.
//17 The destructor for class RWFileManager, which closes the file, will be called here.

Having created the linked-list on disk, how might you read it? Here is a program that reads the list and prints the stored integer field:

And this is a line-by-line description of the program:

//1 The RWFileManager has been constructed with an old File.
//2 The member function start() returns the offset to the first space ever allocated in the file. In this case, that space will contain an offset to the start of the linked-list.
//3 Read the offset to the first link.
//4 A loop to read through the linked-list and print each entry.
//5 Seek to the next link.
//6 Read the next link.
//7 Print the integer.
//8 Get the offset to the next link.
//9 The destructor for class RWFileManager, which closes the file, will be called here.

Previous fileTop of DocumentContentsIndex pageNext file

©2004 Copyright Quovadx, Inc. All Rights Reserved.
Rogue Wave and SourcePro are registered trademarks of Quovadx, Inc. in the United States and other countries. All other trademarks are the property of their respective owners.
Contact Rogue Wave about documentation or support issues.