14.9. Indexed Sequential Access Method (ISAM)

Two operations in the previous version of the direct access Rolodex program conflict. Assuming a large, authentic database file, inserting records randomly is difficult and prohibitively time-consuming. Although programs can sort or reorganize small files (as was done in the b-rolodex example), sorting long files of large records is infeasible. Consequently, authentic database programs append new records at the file's end, leaving a linear search as the only way to locate a given record. However, a linear search through a large file is also a prohibitively lengthy process. Programmers resolve this conflict with the Indexed Sequential Access Method (ISAM), the final access method the text covers.

ISAM allows programs to access specific records in large data files directly. In addition to the data file, the method also requires at least one index file. Index files are also called key files, so the access method is also known as the Keyed Sequential Access Method (KSAM). Programmers implement an ISAM system using the block I/O and direct access functions described previously. Familiarity with the roles that each file plays in an ISAM system makes it easier to understand and discuss.

Data FileIndex Files
  • consists of fixed-length records (instances of structures or classes)
  • each data record consists of many different fields
  • the file is very large:
    • each data record is large
    • the file contains many records
  • the file is too large to fit in memory, making it impractical to reorganize
  • new data records are appended at the end of the data file
  • consist of records with two fields
    • a key duplicating one data record field
    • the record number of a data record with a field matching the key
  • index files may support a fast-search algorithm (e.g., B-trees, hashing, etc.)
  • each index file allows searching the data file on one data record field
  • implement an associative search
ISAM file roles and operation. An ISAM system allows programs to locate a specific data record quickly or access them sequentially in index file order..

Data records often contain many fields, and programs may use any field as a key for an associative search. Each designated key field requires a dedicated index file, binding a key to a record number, and facilitating searching for specific data records in large data files. The following figure illustrates the relationship between the data and index files and outlines the ISAM operations.

The relationship between an index and a data file. The data file with three records is detailed. One field in each record is a person's name. 'Dilbert' is in record 1, 'Wally' is in record 4, and 'Alice' is in record 5. The index file records have two fields: a person's name and a data file record number. The records in the index file are arranged alphabetically by name: Alice:5, Dilbert:1, and Wally:4.
ISAM files and operations. This example continues storing Rolodex cards as records in the data file but adds an index file, forming a simple ISAM system. The index file stores and organizes records, treating contact names as keys. If the index records are small enough to sort easily, they define a fast mapping between the keys and data records. To focus on the ISAM operations, the example makes a few simplifying assumptions:

Add A Data Record

  1. Move to the end of the data file: data.seekp(0, ios::end);
  2. Save the position: pos = data.tellp();
  3. Write the data record:
    data.write((char *) &c, sizeof(chunk));
  4. Create an index record: key k(name, pos);
  5. Move to the end of index file: index.seekp(0, ios::end);
  6. Write the index record:
    index.write((char *) &i, sizeof(key));

Search For A Data Record

  1. Search the index file for the contact's name. This step assumes there is a method for quickly searching through the relatively small index records.
  2. If the search finds the key, get the record number, R, saved with it.
  3. Move to the data record corresponding to R:
    data.seekg(R * sizeof(card));
  4. Read the data record:
    data.read((char *) c, sizeof(card));
Conceptually, the program finds "Alice" in the index file and gets the position 5. It moves the read pointer in the data file to position 5 and reads the complete Alice record.