Chapter 21. Massiv Filesystem

The Massiv filesystem is a concept that enables to store many streams of data in a single file (managed by a host filesystem such as Fat32, NTFS, etc.). Each such file is called an instance of the Massiv filesystem or simply a volume. The streams inside a volume are managed the similar way as in some of the "real" (native) filesystems, but using the Massiv filesystem is likely to be more efficient than storing each stream of data in a separate file on the host filesystem.

There are two types of volumes - either a standard Massiv::Core::Volume or Massiv::Core::CompactVolume. The later stores the streams in a compressed form (using the same method as gzip).

In the Massiv the volumes are used for several purposes. For example, the compressed volumes are utilized for archivation (more described in Chapter 23, Archivation and Startup), whereas uncompressed ones are useful as swap files (to store managed objects that has been swapped out of RAM because they had been unused too long).

The Massiv provides an unique interface that enables to access streams on all volumes and the host filesystem (or any other "real" one) the same way. Moreover this interface is platform independend. It is implemented by Massiv::Core::VolumeManager. Only one instance of the volume manager is permitted. Nevertheless, you never need to access the instance explicitly, because almost all its methods are declared static. Volume manager works with special streams that are derived from the standard iostreams ones and that are defined inside the Massiv::Core::VolumeManager streams. See below for a self-explanatory example.

[Note]Note

You can use the Massiv::Core::FileSystem interface not only to open streams, but also to work with the directory structure (create or remove directories, etc.) See the Massiv Core Reference Guide for the complete information.

Before the volume manager can take any volume into account, it must have been mounted. The manager virtually creates a single filesystem that encapsulates the native filesystem and all mounted volumes (all of them are mounted always to the root of the volume manager filesystem). When requested to open some stream, the manager searches the native filesystem first and then all volumes in the same order as they have been mounted. To force it to ignore all filesystems/volumes except for one, prefix the stream name with either volume_name:// (for the mounted volumes, replace volume_name with the actual name of the relevant volume) or native:// for the native filesystem.

[Note]Note

Each volume has an associated name that is specified when the volume is created. This name can be different from the volume image file and represents the volume in the volume manager's virtual filesystem.

The following example shows the basic usage of the volume manager, streams and the FileSystem interface. You should prefer this interace from the standard C++ API, because it is more general and platform independent.

Example 21.1. Volume manager usage
VolumeManager::mount( "volume1_image" );  1
VolumeManager::mount( "volume2_image" );
VolumeManager::format( "volume3_image", "volume3" );  2

VolumeManager::IFStream   ifs( "stream_path/stream_name" );  3
  ...work with the stream the same way as with a iostream...
ifs.close();  4

VolumeManager::OFStream   ofs( "native://stream_path/stream_name" );  5
  ...work with the stream the same way as with a iostreams...
ofs.close();

VolumeManager::OFStream   ofs( "volume1://stream_path/stream_name" );  6
  ...work with the stream the same way as with a iostreams...
ofs.close();

FileSystem &  fs = VolumeManager::file_system();  7
fs.create_directory( "the/directory/path" );  8

...

VolumeManager::dismount( "volume1_image" );  9
VolumeManager::dismount( "volume2_image" );
1

These lines mount two volumes, the first stored in volume1_image and the second in volume2_image files on the host filesystem. Let's suppose that the first volume has name volume1 and the second volume2.

2

This way you can create a new empty volume that would be stored in the volume3_image file.

3

This line shows how a stream can be opened. A general stream name is given here. Thus, more volumes can be potentially searched for it. The order is: the native filesystem first, volume1 second, volume2 third and finally volume3.

5

Here the same stream is opened for writing. It will be searched for only on the native filesystem; all volumes will be ignored.

6

This will open the stream on volume1 and ignore all other volumes and the native filesystem. Note that the volume name must be given, not the image file name.

7

fs will contain a reference to the volume manager's filesystem interface that provides access to all mounted volumes as well as to the native filesystem.

8

This is only a small example of what you can do using the FileSystem interface. Note that even the create_directory() is more powerful than most of OS API equivalents, because it enables to create more nested directories using a single call.

This specific call creates a new directory on the volume3 volume.

9

This dismounts the volume from volume manager. It won't be taken into account any more.

You can also handle (pack, unpack, list) volumes manually using some extern utilities. See Chapter 25, Auxiliary Utilities for complete information.