Access Methods
Chapter One Hundred
Syllabus topic Module 2, "File System Interface - Access Methods"
Pages 402 to 405 of 452
In one line
Read it from the beginning, jump straight to the record you want, or look the key up in an index first.
Sequential access
Read or write the next record, in order. It is the commonest pattern by a wide margin, and it is what every editor, compiler and command does unless it says otherwise.
| Operation | What it does |
|---|---|
| read next | read the record at the current position, then advance |
| write next | write at the end, and advance |
| reset, or rewind | go back to the beginning |
| skip forward n records | some systems offer it: n read next operations, done cheaply |
It is the model a magnetic tape forces, and that is where it comes from: on a tape there is nothing else you can do. A file on disk can be read sequentially just as well, and reading in block order is exactly what Chapter ninety two measured as seventy times cheaper than scattered reading.
Direct access, also called relative access
Read or write record n, for any n, in any order, with no cost for skipping.
| Operation | What it does |
|---|---|
| read n | read record number n |
| write n | write record number n |
| position to n, then read next | the same thing in two steps: this is what lseek and a read do |
It needs fixed length records, and the reason is the arithmetic.
byte position of record n = n × record length
That single multiplication is what direct access is. Records of different lengths would mean the position of record n could not be worked out without reading every record before it, which is sequential access again.
Note the word relative: the record numbers are relative to the start of the file, and the first is usually 0. The program never deals in disk block numbers, so the file system is free to put the blocks anywhere, which is Chapter one hundred seven's business.
Worked
A file of 80 byte records. Where does record 1000 begin, and which block of a 4096 byte block file system is it in?
byte position = 1000 × 80 = 80,000
block = 80,000 / 4096 = 19, remainder 2176
Byte 80,000, which is block 19, at offset 2,176 inside it. And since 2176 + 80 is less than 4096, the record does not span two blocks, so reading it costs one block access.
The follow-up a question likes: which record is the first to span two blocks? A record spans a boundary when its offset plus 80 passes 4096. With 51 records in a block, 51 × 80 = 4080, so record 51 starts at 4080 and runs to 4160, crossing the boundary at 4096.
51 × 80 = 4080
4080 + 80 = 4160
Access Methods
So record 51 spans two blocks and costs two accesses, and so does every 51st record after it. That is the reason a system may pad records to divide the block evenly, wasting 16 bytes in each block to save the second access.
Demonstrated on the lab machine
$ for i in $(seq 0 99); do printf 'record %03d %-68s\n' "$i" "of a file of fixed length records"; done > records.dat
$ echo "$(stat -c %s records.dat) bytes for 100 records, so $(( $(stat -c %s records.dat) / 100 )) bytes each"
8000 bytes for 100 records, so 80 bytes each
$ dd if=records.dat bs=80 skip=42 count=1 status=none
record 042 of a file of fixed length records
$ echo "record 42 begins at byte $(( 42 * 80 ))"
record 42 begins at byte 3360
$ dd if=records.dat bs=1 skip=3360 count=10 status=none; echo
record 042Record 42 was read without reading records 0 to 41, twice over: once by asking for the 42nd block of 80 bytes, and once by asking for byte 3,360 directly. 3,360 is 42 × 80, which is the formula above doing the work.
Indexed access
Keep an index: a table of keys, each with the record number the key is at. Search the index, then use direct access.
| Step | What happens |
|---|---|
| 1 | search the index for the key |
| 2 | the index gives a record number or a byte position |
| 3 | one direct access fetches the record |
The index is itself a file, and if it is large it gets an index of its own: a multi level index. The scheme a question names is ISAM, indexed sequential access method, where a small master index in memory names blocks of a secondary index on disk, which names the records.
| Level | Size | Where it lives |
|---|---|---|
| master index | small | memory |
| secondary index | larger | disk, one access |
| the data records | the whole file | disk, one access |
So a lookup costs two disk accesses however large the file is, which is why the scheme was worth inventing. The cost is that the index must be kept up to date: every insertion changes it, and a file whose records are inserted often spends its time maintaining indexes.
Note that the index makes access by key possible. Direct access needs the record number, which a program using names or account codes does not have; the index is the translation.
Simulating one with another
A favourite question: which can be built on which, and at what cost.
| Wanted | Built on | How | Cost |
|---|---|---|---|
| sequential | direct | keep a counter and read record cp, then cp + 1 | none: it is the natural use |
| direct | sequential | read forward, discarding records, until record n is reached | ruinous: n reads to get one record |
Access Methods
Direct access cannot be built usefully on sequential access, and that is the whole reason the distinction exists. A tape file is sequential and nothing can be done about it; a disk file can be either.
Distinctions that carry marks
| Sequential | Direct | Indexed | |
|---|---|---|---|
| Order of access | in order only | any order | any, and by key |
| Needs fixed length records | no | yes | usually |
| Cost of getting record n | n reads | one, by multiplication | two: the index, then the record |
| Given by the file system as | read and write | seek and read | the program's own, or a database's |
| Natural on | tape and disk | disk | disk |
| Relative record number | Disk block number | |
|---|---|---|
| Counted from | the start of the file | the start of the device |
| Known to | the program | the file system |
| Changes if the file moves on the disk | no | yes |
What it does not mean
Sequential access is not slow. It is the fastest way to read a whole file, because the blocks are in order.
Direct access does not need the blocks to be contiguous. It needs fixed length records; the file system finds the block.
An index is not part of the file system. In these schemes the program or the database keeps it, in a file of its own.
Indexed access is not a third kind of hardware operation. It is an index lookup followed by a direct access.
A relative record number is not an address. It is a count, and the file system turns it into a block number.
Quick revision
- Sequential: read next, write next, reset. The tape model, the commonest pattern, and the
cheapest way to read a whole file.
- Direct, or relative: read or write record n in any order. It needs fixed length records
because position = n × record length.
- Worked: 80 byte records, record 1000 starts at 1000 × 80 = 80,000, which is block 19
offset 2,176 in a 4096 byte block system, and does not span blocks.
- Record 51 is the first to span a 4096 byte block: 51 × 80 = 4080 and
4080 + 80 = 4160.
- Measured: a file of 100 records of 80 bytes, and record 42 read directly at byte 3,360,
which is 42 × 80.
- Indexed: search an index of keys for a record number, then one direct access. ISAM
keeps a master index in memory and a secondary index on disk, so a lookup is two accesses; the cost is keeping the index current.
- Sequential can be built on direct at no cost; direct on sequential costs n reads and is
Access Methods
not worth having.
Test yourself
- Name the three access methods. Sequential, direct or relative, and indexed.
- What operations does sequential access offer? Read next, write next and reset, and on some
systems skipping forward by n records.
- Why does direct access need fixed length records? Because the position of record n is
found by multiplying n by the record length; with variable lengths it could not be calculated without reading everything before it.
- A file has 80 byte records and 4096 byte blocks. Where does record 1000 begin? At byte
1000 × 80 = 80,000, which is block 19 at offset 2,176, and it does not cross into block 20.
- Which is the first record to span two blocks, and why does it matter? Record 51:
51 × 80 = 4080 and it runs to 4160, past the 4096 boundary, so reading it costs two block accesses instead of one.
- Describe indexed access and the ISAM scheme. An index of keys gives the record number,
then one direct access fetches the record; ISAM keeps a small master index in memory pointing at blocks of a secondary index on disk, so a lookup costs two disk accesses.
- What does indexed access add that direct access lacks? Access by key rather than by record
number.
- Can direct access be built on sequential access? Only by reading and discarding every
record before the one wanted, which costs n reads for one record, so in practice no.
The rest of this subject
These notes are cut from the University's printed syllabus. Open the syllabus itself, or the past papers, for the same subject.