2. HashDir

A HashDir is a subclass of a FileStore, and is a fundamental object that's used as a building block for the system repository. A HashDir object provides access to a list of files in a predefined directory. The directory where the list of files are kept is provided to HashDir's constructor. This directory is called the base directory.

The files are not saved directly in the base directory. The filesnames are hashed by a hash function, which is defined by HashDir's subclass. As an example, consider a simple hash function that returns the first letter of the file's name. In this case, the file rosebud would be saved in basedir/r/rosebud.

The HashDir objects implements the following methods:

These methods merely pass through the filename (which cannot contain the / character) to the underlying FileStore's methods. HashDir implements the fget method by invoking the hash function on the filename, adding the base directory, then opening the indicated file. HashDir implements the fenumerate by reading all the subdirectories of the base directories, then the contents of each subdirectory.

2.1. Commit

HashDir also implements one more, and the most important, function: commit, which saves all changes accumulated by the underlying FileStore object.

commit does not update the actual files. Instead, commit takes all changes from FileStore cache, and passes them to a FileInstall object, which is described in Chapter 15, Installing files and packages. As described in that chapter, FileInstall implements atomic filesystem updates. commit takes all new and updated files in FileStore's internal cache, and uses FileInstall's addEntry method (described in Section 3, “Installing files”) to create any necessary subdirectories in the base directory, and the files themselves. Removed files are similarly passed to FileInstall, and any newly empty hash subdirectories are removed (in reality, commit attempts to remove every subdirectory that contains a removed file, if the subdirectory still contains other files then the request to remove the subdirectory will be quietly ignored by FileInstall).

In short, commit receives a FileInstall object as an argument, then takes the list of changes recorded in FileStore's cached, and passes it to the FileInstall object.