1<?xml version="1.0" encoding="UTF-8" standalone="no"?> 2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 3<html xmlns="http://www.w3.org/1999/xhtml"> 4 <head> 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 6 <title>Retrieving records in bulk</title> 7 <link rel="stylesheet" href="gettingStarted.css" type="text/css" /> 8 <meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /> 9 <link rel="start" href="index.html" title="Berkeley DB Programmer's Reference Guide" /> 10 <link rel="up" href="am_misc.html" title="Chapter��4.�� Access Method Wrapup" /> 11 <link rel="prev" href="am_misc.html" title="Chapter��4.�� Access Method Wrapup" /> 12 <link rel="next" href="am_misc_partial.html" title="Partial record storage and retrieval" /> 13 </head> 14 <body> 15 <div class="navheader"> 16 <table width="100%" summary="Navigation header"> 17 <tr> 18 <th colspan="3" align="center">Retrieving records in bulk</th> 19 </tr> 20 <tr> 21 <td width="20%" align="left"><a accesskey="p" href="am_misc.html">Prev</a>��</td> 22 <th width="60%" align="center">Chapter��4.�� 23 Access Method Wrapup 24 </th> 25 <td width="20%" align="right">��<a accesskey="n" href="am_misc_partial.html">Next</a></td> 26 </tr> 27 </table> 28 <hr /> 29 </div> 30 <div class="sect1" lang="en" xml:lang="en"> 31 <div class="titlepage"> 32 <div> 33 <div> 34 <h2 class="title" style="clear: both"><a id="am_misc_get_bulk"></a>Retrieving records in bulk</h2> 35 </div> 36 </div> 37 </div> 38 <p>When retrieving large numbers of records from the database, the number 39of method calls can often dominate performance. Berkeley DB offers bulk get 40interfaces which can significantly increase performance for some 41applications. To retrieve records in bulk, an application buffer must 42be specified to the <a href="../api_reference/C/dbget.html" class="olink">DB->get()</a> or <a href="../api_reference/C/dbcget.html" class="olink">DBC->get()</a> methods. This is done 43in the C API by setting the <span class="bold"><strong>data</strong></span> and <span class="bold"><strong>ulen</strong></span> fields of the 44<span class="bold"><strong>data</strong></span> <a href="../api_reference/C/dbt.html" class="olink">DBT</a> to reference an application buffer, and the 45<span class="bold"><strong>flags</strong></span> field of that structure to <a href="../api_reference/C/dbt.html#dbt_DB_DBT_USERMEM" class="olink">DB_DBT_USERMEM</a>. In 46the Berkeley DB C++ and Java APIs, the actions are similar, although there 47are API-specific methods to set the <a href="../api_reference/C/dbt.html" class="olink">DBT</a> values. Then, the 48<a href="../api_reference/C/dbcget.html#dbcget_DB_MULTIPLE" class="olink">DB_MULTIPLE</a> or <a href="../api_reference/C/dbcget.html#dbcget_DB_MULTIPLE_KEY" class="olink">DB_MULTIPLE_KEY</a> flags are specified to 49the <a href="../api_reference/C/dbget.html" class="olink">DB->get()</a> or <a href="../api_reference/C/dbcget.html" class="olink">DBC->get()</a> methods, which cause multiple records 50to be returned in the specified buffer.</p> 51 <p>The difference between <a href="../api_reference/C/dbcget.html#dbcget_DB_MULTIPLE" class="olink">DB_MULTIPLE</a> and <a href="../api_reference/C/dbcget.html#dbcget_DB_MULTIPLE_KEY" class="olink">DB_MULTIPLE_KEY</a> 52is as follows: <a href="../api_reference/C/dbcget.html#dbcget_DB_MULTIPLE" class="olink">DB_MULTIPLE</a> returns multiple data items for a 53single key. For example, the <a href="../api_reference/C/dbcget.html#dbcget_DB_MULTIPLE" class="olink">DB_MULTIPLE</a> flag would be used to 54retrieve all of the duplicate data items for a single key in a single 55call. The <a href="../api_reference/C/dbcget.html#dbcget_DB_MULTIPLE_KEY" class="olink">DB_MULTIPLE_KEY</a> flag is used to retrieve multiple 56key/data pairs, where each returned key may or may not have duplicate 57data items.</p> 58 <p>Once the <a href="../api_reference/C/dbget.html" class="olink">DB->get()</a> or <a href="../api_reference/C/dbcget.html" class="olink">DBC->get()</a> method has returned, the 59application will walk through the buffer handling the returned records. 60This is implemented for the C and C++ APIs using four macros: 61<a href="../api_reference/C/DB_MULTIPLE_INIT.html" class="olink">DB_MULTIPLE_INIT</a>, <a href="../api_reference/C/DB_MULTIPLE_NEXT.html" class="olink">DB_MULTIPLE_NEXT</a>, <a href="../api_reference/C/DB_MULTIPLE_KEY_NEXT.html" class="olink">DB_MULTIPLE_KEY_NEXT</a>, and <a href="../api_reference/C/DB_MULTIPLE_RECNO_NEXT.html" class="olink">DB_MULTIPLE_RECNO_NEXT</a>. 62 63For the Java API, this is implemented as three iterator classes: 64<a class="ulink" href="../../java/com/sleepycat/db/MultipleDataEntry.html" target="_top">MultipleDataEntry</a>, 65<a class="ulink" href="../../java/com/sleepycat/db/MultipleKeyDataEntry.html" target="_top">MultipleKeyDataEntry</a>, and 66<a class="ulink" href="../../java/com/sleepycat/db/MultipleRecnoDataEntry.html" target="_top">MultipleRecnoDataEntry</a>.</p> 67 <p>The <a href="../api_reference/C/DB_MULTIPLE_INIT.html" class="olink">DB_MULTIPLE_INIT</a> macro is always called first. It 68initializes a local application variable and the <span class="bold"><strong>data</strong></span> 69<a href="../api_reference/C/dbt.html" class="olink">DBT</a> for stepping through the set of returned records. Then, 70the application calls one of the remaining three macros: 71<a href="../api_reference/C/DB_MULTIPLE_NEXT.html" class="olink">DB_MULTIPLE_NEXT</a>, <a href="../api_reference/C/DB_MULTIPLE_KEY_NEXT.html" class="olink">DB_MULTIPLE_KEY_NEXT</a>, and <a href="../api_reference/C/DB_MULTIPLE_RECNO_NEXT.html" class="olink">DB_MULTIPLE_RECNO_NEXT</a>. 72</p> 73 <p>If the <a href="../api_reference/C/dbcget.html#dbcget_DB_MULTIPLE" class="olink">DB_MULTIPLE</a> flag was specified to the <a href="../api_reference/C/dbget.html" class="olink">DB->get()</a> or <a href="../api_reference/C/dbcget.html" class="olink">DBC->get()</a> 74method, the application will always call the <a href="../api_reference/C/DB_MULTIPLE_NEXT.html" class="olink">DB_MULTIPLE_NEXT</a> macro. If 75the <a href="../api_reference/C/dbcget.html#dbcget_DB_MULTIPLE_KEY" class="olink">DB_MULTIPLE_KEY</a> flag was specified to the <a href="../api_reference/C/dbget.html" class="olink">DB->get()</a> or <a href="../api_reference/C/dbcget.html" class="olink">DBC->get()</a> method, and the 76underlying database is a Btree or Hash database, the application will 77always call the <a href="../api_reference/C/DB_MULTIPLE_KEY_NEXT.html" class="olink">DB_MULTIPLE_KEY_NEXT</a> macro. If the 78<a href="../api_reference/C/dbcget.html#dbcget_DB_MULTIPLE_KEY" class="olink">DB_MULTIPLE_KEY</a> flag was specified to the <a href="../api_reference/C/dbget.html" class="olink">DB->get()</a> or 79<a href="../api_reference/C/dbcget.html" class="olink">DBC->get()</a> method, and the underlying database is a Queue or Recno 80database, the application will always call the 81<a href="../api_reference/C/DB_MULTIPLE_RECNO_NEXT.html" class="olink">DB_MULTIPLE_RECNO_NEXT</a> macro. The <a href="../api_reference/C/DB_MULTIPLE_NEXT.html" class="olink">DB_MULTIPLE_NEXT</a>, <a href="../api_reference/C/DB_MULTIPLE_KEY_NEXT.html" class="olink">DB_MULTIPLE_KEY_NEXT</a>, 82and <a href="../api_reference/C/DB_MULTIPLE_RECNO_NEXT.html" class="olink">DB_MULTIPLE_RECNO_NEXT</a> macros 83are called repeatedly, until the end of the returned records is reached. 84The end of the returned records is detected by the application's local 85pointer variable being set to NULL.</p> 86 <p>The following is an example of a routine that displays the contents of 87a Btree database using the bulk return interfaces.</p> 88 <pre class="programlisting">int 89rec_display(dbp) 90 DB *dbp; 91{ 92 DBC *dbcp; 93 DBT key, data; 94 size_t retklen, retdlen; 95 char *retkey, *retdata; 96 int ret, t_ret; 97 void *p; 98 99 memset(&key, 0, sizeof(key)); 100 memset(&data, 0, sizeof(data)); 101 102 /* Review the database in 5MB chunks. */ 103#define BUFFER_LENGTH (5 * 1024 * 1024) 104 if ((data.data = malloc(BUFFER_LENGTH)) == NULL) 105 return (errno); 106 data.ulen = BUFFER_LENGTH; 107 data.flags = DB_DBT_USERMEM; 108 109 /* Acquire a cursor for the database. */ 110 if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0) { 111 dbp->err(dbp, ret, "DB->cursor"); 112 free(data.data); 113 return (ret); 114 } 115 116 for (;;) { 117 /* 118 * Acquire the next set of key/data pairs. This code does 119 * not handle single key/data pairs that won't fit in a 120 * BUFFER_LENGTH size buffer, instead returning DB_BUFFER_SMALL 121 * to our caller. 122 */ 123 if ((ret = dbcp->c_get(dbcp, 124 &key, &data, DB_MULTIPLE_KEY | DB_NEXT)) != 0) { 125 if (ret != DB_NOTFOUND) 126 dbp->err(dbp, ret, "DBcursor->c_get"); 127 break; 128 } 129 130 for (DB_MULTIPLE_INIT(p, &data);;) { 131 DB_MULTIPLE_KEY_NEXT(p, 132 &data, retkey, retklen, retdata, retdlen); 133 if (p == NULL) 134 break; 135 printf("key: %.*s, data: %.*s\n", 136 (int)retklen, retkey, (int)retdlen, retdata); 137 } 138 } 139 140 if ((t_ret = dbcp->c_close(dbcp)) != 0) { 141 dbp->err(dbp, ret, "DBcursor->close"); 142 if (ret == 0) 143 ret = t_ret; 144 } 145 146 free(data.data); 147 148 return (ret); 149}</pre> 150 </div> 151 <div class="navfooter"> 152 <hr /> 153 <table width="100%" summary="Navigation footer"> 154 <tr> 155 <td width="40%" align="left"><a accesskey="p" href="am_misc.html">Prev</a>��</td> 156 <td width="20%" align="center"> 157 <a accesskey="u" href="am_misc.html">Up</a> 158 </td> 159 <td width="40%" align="right">��<a accesskey="n" href="am_misc_partial.html">Next</a></td> 160 </tr> 161 <tr> 162 <td width="40%" align="left" valign="top">Chapter��4.�� 163 Access Method Wrapup 164 ��</td> 165 <td width="20%" align="center"> 166 <a accesskey="h" href="index.html">Home</a> 167 </td> 168 <td width="40%" align="right" valign="top">��Partial record storage and retrieval</td> 169 </tr> 170 </table> 171 </div> 172 </body> 173</html> 174