Chapter 8: Using Multiple Databases

8.1 Child Databases

So far, we have assumed that only one database is being used. In fact, it is possible, and often useful, to create and use multiple databases. New databases are created using PolyML.make_database. A full path name must be used for the database name on the command line so that the child database can use the same full path name to locate its parent database in future sessions. For example:

unix% poly /usr/staff/john/john_dbase
> PolyML.make_database "child_dbase";
val it = () : unit
> PolyML.quit();

will create a new Unix file, child_dbase. You can now run ML using the new database by entering:

unix% poly child_dbase

at the Unix prompt. The new database, child_dbase, is initially empty except that it 'inherits' all the definitions contained in its parent database (here john dbase). New objects are created in the heap as usual and, if the database is committed, will be saved in child_dbase. For example:

> val demo = "demo";
val demo = "demo" : string
> PolyML.commit();
val it = () : unit

will add the string "demo" to the child database. If an object from the parent database is changed, the heap will contain the updated object. PolyML.commit() will nor update the parent database, however. Poly/ML will only update the database named on the Unix command line (here child_dbase). This means that any change to an object in a parent database will not persist between ML sessions.

The child database is not accessible from the parent database. For example:

unix% poly john_dbase
> demo;
Error- Value or constructor (demo) has not been declared
Found near demo
Exception static-errors raised
>

The distributed database for the current version of the system is several megabytes large. Giving each person their own copy of this database would use a lot of disk space. A better solution is to give each person a different child of the distributed database. For example, assuming the distributed database is named ML_dbase, then typing

unix% poly /usr/share/ML_dbase
> PolyML.make_database "/usr/staff/john/john_dbase";
val it = () :...
> PolyML.make_database "/usr/staff/mary/mary_dbase";
> val it = () :...

would create a child database called /usr/staff/john/john_dbase and another child database called /usr/staff/mary/mary_dbase. After all users have been given child databases, the parent database (ML_dbase) should be made read-only. (The parent database must be made readable by all users of the system, as this database contains the actual code for the ML compiler.) In this way, the database containing the system will be shared, economising on disk space, but each person will have their own database for their own particular work.

8.2 Copying Linked Databases

Suppose John has a database called john_dbase which is a child database of the main Poly/ML database, ML_dbase. In addition, he has created a child database of his own called child_dbase.

Mary has no databases, and wishes to copy John's. She can copy the database files with the following commands.

unix% cp /usr/staff/john/john_dbase /usr/staff/mary/mary_dbase
unix% cp /usr/staff/john/child_dbase /usr/staff/mary/child_dbase

Unfortunately, this does not adjust the full pathnames inside the databases that point upwards to parent databases - Mary's child_dbase still points to john_dbase. Mary can correct this using changeParent.

The program changeParent takes two arguments. The first is the child database that contains a parent pointer, and the second is the new parent name.

unix% changeParent child_dbase /usr/staff/mary/mary_dbase

This has made the new child_dbase point to mary_dbase. Note that full pathnames must be used for parent names.

8.3 Database and Heap Limits

Do not run discgarb on a parent database because this rearranges all the objects in that database without updating the references held in its child databases. You can add extra bindings into a parent database safely, as long as none of its children are in use.

Poly/ML can create up to 3 levels of database hierarchy, but there is no limit on the number of child databases at each level.

In ML, most objects that are created in the heap or in a database are immutable, that is they cannot be changed once they have been created. The only mutable objects, that is objects that can have their contents changed, are refs. Mutable objects rarely account for more than 25% of the objects in a database.

A database may grow to a total of 36Mb, where 32Mb is reserved for immutable objects, and 4Mb is reserved for mutable objects.

The maximum size of the local heap is set by the -h flag but may not exceed an architecturally-imposed limit.

Copyright (c) 2000 CUTS and contributers.  Last updated: 15 January 2002 by David Matthews.