In Parts 2 and 3 of this series we discussed basic ways of mapping data to and from byte arrays in order to store them in record stores managed by the Record Management System (RMS). Reading and writing data is always the first obstacle to overcome, but finding the data you need is just as important, and to do that you need to be able to navigate the record store, sort records into a useful order, and use filters to extract wanted records. This article explores the different strategies for performing these chores; Part 5 will build on what you learn here, and show you how to search for records that meet criteria you specify. A Record ID Is Not an Index
To read or write a record you need to know its record ID. In Part 1 you learned that a record ID is an integer that uniquely identifies a record within the record store - and that it is not an index into the record store. This difference has some vital implications. If a store of N records were indexed, each would have an index in either the range 0 to N-1 or the range 1 to N, depending on whether the range started with 0 or 1. Each time a record was removed or inserted, indexes of records later in the store would change accordingly. The range would shrink or grow, but remain continuous.
Unlike an index, a record ID does not change, no matter how many other records are inserted or removed before it in the record store. The first record added to a record store is given a record ID of 1, the next a record ID of 2, and so on. If you delete a record, its record ID is invalidated and any attempt to access that record throws Because they uniquely identify records, you can use record IDs to link two or more records together, by storing the ID of one record as a data value in another. You can also use record IDs to synchronize data with external applications, as you'll see in Part 6. The main disadvantage of record IDs is that they complicate record store traversal; you can't just iterate through a set of indexes as you can through an array. You must use one of two traversal techniques: brute force or enumeration. Brute-Force Traversal
With the brute-force approach, you simply fetch records one by one, starting with the first record, skipping invalid records, and continuing until you've fetched all records:
This code calls The brute-force method is simple to understand and works well if there are few missing records, but the preferred approach is to use an enumeration. Enumerating Records
Instead of checking each record ID to see which ones are valid, which is essentially what the brute-force approach does, you can ask the RMS to return you an enumeration of valid record IDs, using the
You obtain an enumeration by calling the enume
For simplicity, exception handling has been omitted from this code snippet, but be aware that
The first two parameters to
When you're done with an enumeration, you must invoke its
Use
You can also move backward, using The order in which an unsorted enumeration returns its records is implementation-specific, so don't make any assumptions based on that order.
For convenience, you can use
You will not, however, know the ID of the record in question or be able to read the data directly into a byte array that you've allocated. If you're filtering or sorting the enumeration, however, the data may be cached in memory, so obtaining it from the enumeration instead of the underlying record store may be more efficient.
A call to
Use
Use Filtering Enumerated Records
Interested in only a subset of the data in a record store? You can have an enumeration skip unwanted records by using a filter, an object that implements the
Ideally, the information you need to do the filtering is at the beginning of the array - you want to determine a match as quickly as possible. To use a filter, pass it as the first parameter to
The record ID is not passed to the filter, only the byte array containing the record data. If you absolutely must know which record ID is being matched, you'll need to store the ID in the record itself or use some other way to identify the record from its data. In Part 3, for example, we used the first record in a record store to hold information about the fields in the remaining records - obviously you'd want to filter this record out of any enumeration. Sorting Enumerated Records
To guarantee that records are returned in a consistent, predictable order, you must sort the enumeration. You supply the enumeration with a comparator, an object that implements the
Note the use of the constants
As with filters, no record identifiers are ever passed to the comparator, just the raw record data. You can supply both a filter and a comparator when you create an enumeration. If you do, the filter is applied before the data is sorted. What's Next
Now that you know how to traverse the record store, and how to sort and filter records, you're ready for Part 5, which will describe strategies for searching a record store for objects that meet specified criteria. Eric Giguere is a software developer for iAnywhere Solutions, a subsidiary of Sybase, where he works on Java technologies for handheld and wireless computing. He holds BMath and MMath degrees in Computer Science from the University of Waterloo and has written extensively on computing topics. | |||||||||||||||||||||||
|
| ||||||||||||