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:
Return the contents of filename F
, if it exists,
or an empty string.
HashDir
is expected to contain relatively small files.
Update the contents of the file F
, or remove
it.
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.
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.