Keeping track of such changes is not difficult as long as we always use the standard method of finding the address of an item: look it up in the IRA to get its quantum number and item nu
Trang 1|| + -+ |
|+ -+ | |
+- + -+ | | |
| + -+ +-+ -+ -+
Quantum | | 11510NYBaldwinSteve Heller|
Data | + -+
+-
+-
Quantum | 333333333222222222211111111110000000000
Offset | 876543210987654321098765432109876543210
+-
Note that we set the offset value of the deleted item equal to the offset of the item before it so that its length can be calculated as zero Now let us add a new street address of "123 Main Street" After this change, our data structures look like those in Figure itemref3 Sample IRA, item index, and data, after field change (Figure itemref3) +-
| Quantum Item
| Index Number Number
| + -+
Item | 0 | 3 1 + -+
Reference | 1 | 3 2 + -+-+
Array | 2 | 3 3 + -+-+ +
(IRA) | 3 | 3 4 + -+-+ +-+
| 4 | 3 5 + -+-+ +-+-+
| + -+ | | | | |
+- | | | | |
| | | | |
+- | | | | |
|Item # Offset Type Index | | | | |
| + -+ | | | | |
| 1 | 12 -+ VARSTRING 0 |± + | | | |
| 2 | 27 +| VARSTRING 1 |± + | | |
Item | 3 | +-34 || VARSTRING 2 |± -+ | |
Index | 4 | ++-36 || VARSTRING 3 |± -+ |
for | 5 +-+-++-41 || VARSTRING 4 |± -+
Quantum | 6 | | || 38 || UNUSED 0 |
3 | 7 | | || 38 || UNUSED 0 |
Trang 2| 8 | | || 38 || UNUSED 0 |
| 9 | | || 38 || UNUSED 0 |
| 10 | | || 38 || UNUSED 0 |
| | +-++ ++ -+
+- | || |+ -+
| || + -+ |
| |+-+ | |
+- | ++ | | |
| ++ +-+ -+ -+ -+
Quantum | |11510NYBaldwin123 Main StreetSteve Heller|
Data | + -+
+-
+-
Quantum | 443333333333222222222211111111110000000000
Offset | 109876543210987654321098765432109876543210
+-
This is the actual mechanism used to change the value of an item: we delete the old item and add the new one Of course, an item that increases in size may no longer fit in the same quantum, in which case we have to move it to a different quantum Keeping track of such changes is not difficult as long as we always use the
standard method of finding the address of an item: look it up in the IRA to get its quantum number and item number, then use its quantum number and item number
to look it up in the item index This allows us to move the item to a new quantum and change only its entries in the IRA and affected item indexes
For example, if an item was originally in quantum 3 but now no longer fits there,
we might move it to quantum 6 In order to do this, we first delete it from quantum
3 and then add it to quantum 6 As before, all the other IRA entries for items in quantum 3 still refer to the same data items as before, after we have adjusted the item index to account for the removed data
Of course, the deleted item still takes up a slot in the item index of the old
quantum; in our implementation this requires 10 bytes of storage.9 We need a method of reclaiming that space, so that we do not gradually fill our quanta with indexes pointing to nothing We have already seen part of the solution to this
problem: whenever we are adding an item to a quantum, we search for an unused item index entry rather than simply adding a new entry at the end
Trang 3This mechanism alone would only slow the growth of the item indexes; actually reducing the size of an index requires us to check for empty entries at the end of the item index after deleting an item If such excess entries exist, we reclaim the space they occupy by reducing the entry count in the item index header to the number actually in use This reduces wasted space in the item index without
affecting entries in the IRA Since we remove unused item index entries only when they are at the end of the index, no IRA entries can refer to items later in the same quantum
A Large Array
Our records are stored in the quanta pointed to by our IRA The IRA will be stored
in its own quanta, which allows us to make it as large as needed However, this means that we can't allocate the IRA in one piece Since a quantum has a fixed size, we will have to break up our IRA into segments that will fit in a quantum;
these segments will be collectively referred to as the little pointer array We'll
also need some way to find the segment that we need for a particular element in the
IRA, which will be the responsibility of the big pointer array
Figure bigpointer shows the relationship between the big pointer array and the IRA segments
From the big pointer array to the IRA (Figure bigpointer)
+ -+
| +- |
| Big | element_count = 8000 |
| Pointer | last_quantum_added_to = 3 |
| Array | |
| Header | |
| +- |
| +- |
| | Quantum | Quantum
| | Index Number | 5
| | + -+ |
| Big | 0 | 2 + -+ -+
| Pointer | 1 | 10 + -+ -+-+
| Array | 2 | 12 + -+ -+-+ +
| | 3 | 14 + -+ -+-+ ++
| | 4 | 11 + -+ -+-+ +++
| | + -+ | | | |||
Trang 4| +- | | | |||
| | | | |||
+ -+ | | |||
+ -+ | | |||
| |± -+ | |||
| +- | Quantum | |||
| | Quantum Item | 2 | |||
| | Index Number Number | | |||
| Item | + -+ | | |||
| Reference | 0 | 3 2 | | | |||
| Array | 1 | 3 4 | | | |||
| (IRA) | 2 | 3 5 | | | |||
| segment | 3 | 3 3 | | | |||
| 0 | 4 | 3 1 | | | |||
| | + -+ | | |||
| +- | | |||
+ -+ | |||
+ -+ | |||
| |± -+ |||
| +- | Quantum |||
| | Quantum Item | 10 |||
| | Index Number Number | |||
| Item | + -+ | |||
| Reference | 0 | 3 12 | | |||
| Array | 1 | 4 6 | | |||
| (IRA) | 2 | 4 1 | | |||
| segment | 3 | 4 2 | | |||
| 1 | 4 | 4 3 | | ²²²
| | + -+ |
| +- |
+ -+
Each IRA segment in the real program, of course, holds more than five entries: with a 16 KB quantum, about 4000 entries will fit in one quantum However, the segmentation of the IRA works in the same way as this example The segment number can be determined by dividing the element number by the number of elements in each IRA segment; the index into the IRA segment is the remainder of that division
Trang 5The big pointer array sets a limit on the number of elements referenced by an IRA, since that array has to fit in one quantum However, this is not a very restrictive limit, since one big pointer array can contain about 4000 elements, using a 16 KB quantum Each of these elements points to a little pointer array, which contains pointers to about 4000 entries, as mentioned above Therefore, we could
theoretically create an array with about 16,000,000 items in it
Because our ArrayIndex type is defined as an unsigned long, which is usually 4 bytes, we can actually create arrays of that size.10
Many Large Arrays
There is one more generalization of the quantum file access method that will make
it more generally useful: the ability to create more than one array of variable-length items
The mechanism by which we will accomplish this goal is called the "main object index", which contains the quantum number of the big pointer array for each
object; the number of an object is set when the object is created, by a directory facility which we will examine later
Figure mainindex shows the path from the main object index through the big
pointer array, the IRA segment, and the item index, to finally arrive at the data
From the main object index to the data (Figure mainindex)
+-
| Index Quantum Number
| + -+
Main | 0 |NO_QUANTUM|
Object| 1 | 5 + -+
Index | 2 | 9 | |
| 3 | 1 | |
| 4 | 7 | |
+- + -+ |
+ -+ |
|Big +- |± +
|Pointer | element_count = 8000 |
|Array | last_quantum_added_to = 3 |
|Header +- |
| +- |