Chapter 6. Searching in a database

Table of Contents

Search modes
Cursors

The Database interface has several methods for searching:

get(key)

Inherited from the Map interface. This method returns the value stored for a specific key in the database.

find(key)

Returns a Cursor positioned at the database record with the specified key.

find(key, SearchMode)

Returns a Cursor positioned at the database record matching the key and the SearchMode. The natural ordering of the database keys is used to find closest matches. This requires that the keys in the database are Comparable.

find(key, SearchMode, Comparator)

Returns a Cursor positioned at the database record matching the key and the SearchMode. The supplied Comparator is used to find closest matches.

firstRecord()

Returns a Cursor positioned at the "first" database record. What "first" means depends on the search order of the database's DatabaseBackend.

lastRecord()

Returns a Cursor positioned at the "last" database record. What "last" means depends on the search order of the database's DatabaseBackend. This method is only supported by DatabaseBackend:s that support backwards iteration.

There are four standard search modes that all databases and database backends support:

SearchMode.EXACT_MATCH

The find method will only return a Cursor if the key supplied to it exists in the database.

SearchMode.CLOSEST_ABOVE

Return a Cursor pointing to the database record with the closest larger key value than the supplied search key if no exact key match is found.

SearchMode.CLOSEST_BELOW

Return a Cursor pointing to the database record with the closest smaller key value than the supplied search key if no exact key match is found.

SearchMode.CLOSEST_MATCH

Return a Cursor pointing to the database record with the smallest absolute difference in key value compared with the supplied search key if no exact key match is found. If there are two records with the same key distance from the search key, any of those may be returned.

A database backend may also define its own, custom search modes.

By default, when used with any of the CLOSEST_X search modes, the find method iterates through the entire backend to find the closest match. However, if the backend has sorted keys (such as the ConstantRecordSizeBPlusTreeBackend) or has an index that sorts the keys (such as the BPlusTreeIndexBackend), find may use the sort order to find matches faster if it is called with the same Comparator that is used by the database backend (or with no Comparator if the backend uses the keys' natural ordering).

A Cursor is a pointer to a record in the database. It can be used to navigate through the database records[2]. In the example below, a Cursor is used to find all records with key values between 40 and 50 in a database. For this to work, the database backend must be one with sorted keys[3], for instance a heap backend with a B+ Tree index.

Example 6.1. Using a cursor to find records to process

// db is a Database<Integer, String>
//
// Find the record with the key that has the closest larger value than 40
Cursor<Integer,String> c = db.find(40, SearchMode.CLOSEST_ABOVE);

// Maybe there is no such key in the database
if (c == null)
{
  System.out.println("Nothing found");
  return;
}

while(c.getKey() < 50)
{
  // Print the record
  System.out.println(c.getKey() + ": " + c.getValue());

  // Move to the next record
  c.next();
}



[2] Unlike most other databases where cursors are used to navigate through result sets from queries, HeliDB Cursor:s are used for navigating through the entire database.

[3] If the backend was not sorted, the Cursor.next() call could return any record from the database.