How to build a low-level database using java RandomAccessFile Part 4

RecordsFileException is a simple exception class that indicates that an error has occurred while performing an operation on the records file.

  package hamner.db;
  public class RecordsFileException extends Exception {
    public RecordsFileException (String msg) {
      super(msg);
    }
  }

Figure 7. RecordsFileException

Using the RecordsFile class

The following code creates a new RecordsFile and inserts a test record that consists of a serialized Date. The records file is created with an initial capacity of 64. We can use this code in any application that needs to persistently store the last time that a particular resource was accessed.

RecordsFile recordsFile = new RecordsFile("testDatabase.jdb", 64);
RecordWriter rw = new RecordWriter("foo.lastAccessTime");
rw.writeObject(new Date());
recordsFile.insertRecord(rw);

Later in our application, when we wish to retrieve the record, the code would be as follows:

RecordReader rr = recordsFile.readRecord("foo.lastAccessTime");
Date d = (Date)rr.readObject();
System.out.println("last access was at: " + d.toString());

With this small amount of code, we have accomplished a rather important task: we have inserted an arbitrarily sized object into our file, and then retrieved it again.

When a new access to the resource takes place at a later time, we can update the contents of the record as follows:

RecordWriter rw = new RecordWriter("foo.lastAccessTime");
rw.writeObject(new Date());
recordsFile.updateRecord(rw);

Finally, if we need to remove the record from the database, we can use the deleteRecord() method:

recordsFile.deleteRecord("foo.lastAccessTime");

To see this code in action, check out the TestRecords class provided in the source distribution for this example.

Possible additions and optimizations

You could improve on our example in several ways. To improve performance you could restructure the operations that depend on iterating over the entire in-memory index by keeping a datastructure that holds pointers to the free space in the record heap. Another optimization would be to add a "quick insert" that always appends the record to the end of the file. This approach would be useful when an entire database is being constructed from scratch; that is, when there is never free space between record data.

Other improvements to reduce the number of file accesses and, hence, improve performance include caching recently accessed records, and using a buffer to load and store index entries as a single unit, rather than calling separate reads and writes for each field in the entry.

Conclusion

This example has shown that we can design and implement our own low-level file format to store records. Although it was designed as a means of illustrating the uses of the RandomAccessFile class, it has practical applications in a wide range of programming situations.

Here are a few possible examples that come to mind:

  • A persistent data cache: A RecordsFile could be used to cache arbitrary data in a file for applications such as Web browsers, Web servers, and proxy servers, among others.

  • A "properties" file for arbitrary objects: The Java properties file format, provided by class java.util.Properties is a very useful means of storing and retrieving name/value pairs. This example provides the same basic functionality, but allows the user to store binary data.

  • Any application where the data model is too simple to justify the use of a heavyweight database API such as JDBC.

Derek Hamner has extensive experience designing and implementing collaborative systems in Java. He is president of CSR Inc., a North Carolina startup that creates Internet classroom applications for distance learning and corporate training. Derek is also coauthor of Java Network Programming, Second Edition, which covers many related networking and I/O issues, including the Java 2 platform (formerly known as JDK 1.2), and is due for release January 1999.
loading...

Related posts

Related posts