1<!--$Id: logrec.so,v 10.31 2004/08/05 14:16:56 bostic Exp $--> 2<!--Copyright (c) 1997,2008 Oracle. All rights reserved.--> 3<!--See the file LICENSE for redistribution information.--> 4<html> 5<head> 6<title>Berkeley DB Reference Guide: Logical record numbers</title> 7<meta name="description" content="Berkeley DB: An embedded database programmatic toolkit."> 8<meta name="keywords" content="embedded,database,programmatic,toolkit,btree,hash,hashing,transaction,transactions,locking,logging,access method,access methods,Java,C,C++"> 9</head> 10<body bgcolor=white> 11<a name="2"><!--meow--></a> 12<table width="100%"><tr valign=top> 13<td><b><dl><dt>Berkeley DB Reference Guide:<dd>Access Methods</dl></b></td> 14<td align=right><a href="/am_conf/select.html"><img src="/images/prev.gif" alt="Prev"></a><a href="/toc.html"><img src="/images/ref.gif" alt="Ref"></a><a href="/am_conf/pagesize.html"><img src="/images/next.gif" alt="Next"></a> 15</td></tr></table> 16<p align=center><b>Logical record numbers</b></p> 17<p>The Berkeley DB Btree, Queue and Recno access methods can operate on logical 18record numbers. Record numbers are 1-based, not 0-based, that is, the 19first record in a database is record number 1.</p> 20<p>In all cases for the Queue and Recno access methods, and when calling 21the Btree access method using the <a href="/api_c/db_get.html">DB->get</a> and <a href="/api_c/dbc_get.html">DBcursor->get</a> methods 22with the <a href="/api_c/db_get.html#DB_SET_RECNO">DB_SET_RECNO</a> flag specified, the <b>data</b> field of 23the key <a href="/api_c/dbt_class.html">DBT</a> must be a pointer to a memory location of type 24<b>db_recno_t</b>, as typedef'd in the standard Berkeley DB include file. 25The <b>size</b> field of the key <a href="/api_c/dbt_class.html">DBT</a> should be the size of that 26type (for example, "sizeof(db_recno_t)" in the C programming language). 27The <b>db_recno_t</b> type is a 32-bit unsigned type, which limits the 28number of logical records in a Queue or Recno database, and the maximum 29logical record which may be directly retrieved from a Btree database, 30to 4,294,967,295.</p> 31<p>Record numbers in Recno databases can be configured to run in either 32mutable or fixed mode: mutable, where logical record numbers change as 33records are deleted or inserted, and fixed, where record numbers never 34change regardless of the database operation. Record numbers in Queue 35databases are always fixed, and never change regardless of the database 36operation. Record numbers in Btree databases are always mutable, and 37as records are deleted or inserted, the logical record number for other 38records in the database can change. See 39<a href="/ref/am_conf/renumber.html">Logically renumbering records</a> 40for more information.</p> 41<p>When appending new data items into Queue databases, record numbers wrap 42around. When the tail of the queue reaches the maximum record number, 43the next record appended will be given record number 1. If the head of 44the queue ever catches up to the tail of the queue, Berkeley DB will return 45the system error EFBIG. Record numbers do not wrap around when appending 46new data items into Recno databases.</p> 47<p>Configuring Btree databases to support record numbers can severely limit 48the throughput of applications with multiple concurrent threads writing 49the database, because locations used to store record counts often become 50hot spots that many different threads all need to update. In the case 51of a Btree supporting duplicate data items, the logical record number 52refers to a key and all of its data items, as duplicate data items are 53not individually numbered.</p> 54<p>The following is an example function that reads records from standard 55input and stores them into a Recno database. The function then uses a 56cursor to step through the database and display the stored records.</p> 57<blockquote><pre>int 58recno_build(dbp) 59 DB *dbp; 60{ 61 DBC *dbcp; 62 DBT key, data; 63 db_recno_t recno; 64 u_int32_t len; 65 int ret; 66 char buf[1024]; 67<p> 68 /* Insert records into the database. */ 69 memset(&key, 0, sizeof(DBT)); 70 memset(&data, 0, sizeof(DBT)); 71 for (recno = 1;; ++recno) { 72 printf("record #%lu> ", (u_long)recno); 73 fflush(stdout); 74 if (fgets(buf, sizeof(buf), stdin) == NULL) 75 break; 76 if ((len = strlen(buf)) <= 1) 77 continue; 78<p> 79 key.data = &recno; 80 key.size = sizeof(recno); 81 data.data = buf; 82 data.size = len - 1; 83<p> 84 switch (ret = dbp->put(dbp, NULL, &key, &data, 0)) { 85 case 0: 86 break; 87 default: 88 dbp->err(dbp, ret, "DB->put"); 89 break; 90 } 91 } 92 printf("\n"); 93<p> 94 /* Acquire a cursor for the database. */ 95 if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0) { 96 dbp->err(dbp, ret, "DB->cursor"); 97 return (1); 98 } 99<p> 100 /* Re-initialize the key/data pair. */ 101 memset(&key, 0, sizeof(key)); 102 memset(&data, 0, sizeof(data)); 103<p> 104 /* Walk through the database and print out the key/data pairs. */ 105 while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0) 106 printf("%lu : %.*s\n", 107 *(u_long *)key.data, (int)data.size, (char *)data.data); 108 if (ret != DB_NOTFOUND) 109 dbp->err(dbp, ret, "DBcursor->get"); 110<p> 111 /* Close the cursor. */ 112 if ((ret = dbcp->c_close(dbcp)) != 0) { 113 dbp->err(dbp, ret, "DBcursor->close"); 114 return (1); 115 } 116 return (0); 117}</pre></blockquote> 118<table width="100%"><tr><td><br></td><td align=right><a href="/am_conf/select.html"><img src="/images/prev.gif" alt="Prev"></a><a href="/toc.html"><img src="/images/ref.gif" alt="Ref"></a><a href="/am_conf/pagesize.html"><img src="/images/next.gif" alt="Next"></a> 119</td></tr></table> 120<p><font size=1>Copyright (c) 1996,2008 Oracle. All rights reserved.</font> 121</body> 122</html> 123