###

Berkeley DB Reference Guide:
  Access Methods

# Logically renumbering records

Records stored in the Queue and Recno access methods are accessed by logical record number. Invariably in Queue databases, and by default in Recno databases, these record numbers are not mutable. That is to say, if you delete record number 5, record number 6 is not automatically renumbered to be record number 5 and 7 renumbered to be record number 6 and so on. For this same reason, new records cannot be inserted between already-existing records.

Record numbers in Btree databases are always mutable, and as records are deleted or inserted, the logical record number for other records in the database can change.

In Recno databases, it is possible to make the logical record numbers mutable by calling the DB->set_flags function with the DB_RENUMBER flag. This means that the record numbers may change as records are added to and deleted from the database. When record numbers are mutable, cursors behave quite a bit differently than usual.

For example, the deletion of record number 4 causes records numbered 5 and greater to be renumbered downward by 1. If a cursor is positioned at a record less than 4 before the deletion, it will be unchanged. If a cursor is positioned at a record greater than 4 before the deletion, it will be shifted downward 1 logical record number, continuing to reference the same record as it did before.

If a cursor was positioned at record 4 when it was deleted, one of two things happens: if there were records greater than 4 when the delete happened, the cursor will suddenly reference what was previously record 5 and is now record number 4. If there were no records greater than 4 when the delete happened, the cursor will suddenly reference record 3, that is, the largest record in the database that exists. When a delete removes the single remaining record from a database, any open cursors will reference an invalid record number, and operations relative to the current cursor position, e.g., DBcursor->c_put with the DB_BEFORE flag, will fail.

Similarly, if a created record is not at the end of the database, all records following the new record will be automatically renumbered upward by 1. For example, the creation of a new record numbered 8 causes records numbered 8 and greater to be renumbered upward by 1. If a cursor was positioned to record number 8 or greater before the insertion, it will be shifted upward 1 logical record, continuing to reference the same record as it did before.

For these reasons, concurrent access to a Recno database with the DB_RENUMBER flag specified is rarely useful (because threads of control may renumber records being accessed by other threads of control), although it is supported.

In the case of Queue and Recno databases where record numbers are not mutable, any attempt to retrieve deleted records will result in a special error return, DB_KEYEMPTY.

When using both mutable and immutable record numbers, creating new records will cause the creation of multiple records if the record number is more than one greater than the largest record currently in the database. For example, creating record number 28, when record 25 was previously the last record in the database, will implicitly create records 26 and 27 as well as 28.

First, last, next and previous cursor operations will automatically skip over implicitly created records. For example, if record number 5 is the only record the application has created, implicitly creating records 1 through 4, the DBcursor->c_get interface with the DB_FIRST flag will return record number 5, not record number 1. Attempts to explicitly retrieve records that were created in this manner will result in a special error return, DB_KEYEMPTY.

Copyright Sleepycat Software