-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathcursor_ops.html
319 lines (319 loc) · 36.4 KB
/
cursor_ops.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<title>WiredTiger: Cursor operations</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
$(document).ready(initResizable);
$(window).load(resizeHeight);
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="wiredtiger.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><a href="http://wiredtiger.com/"><img alt="Logo" src="LogoFinal-header.png" alt="WiredTiger" /></a></td>
<td style="padding-left: 0.5em;">
<div id="projectname">
 <span id="projectnumber">Version 2.8.0</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="banner">
<a href="https://github.com/wiredtiger/wiredtiger">Fork me on GitHub</a>
<a class="last" href="http://groups.google.com/group/wiredtiger-users">Join my user group</a>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.9.1 -->
<div id="navrow1" class="tabs">
<ul class="tablist">
<li><a href="index.html"><span>Main Page</span></a></li>
<li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
<li><a href="modules.html"><span>Modules</span></a></li>
<li><a href="examples.html"><span>Examples</span></a></li>
<li><a href="community.html"><span>Community</span></a></li>
<li><a href="license.html"><span>License</span></a></li>
</ul>
</div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('cursor_ops.html','');});
</script>
<div id="doc-content">
<div class="header">
<div class="headertitle">
<div class="title">Cursor operations </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>Common operations in WiredTiger are performed using <a class="el" href="struct_w_t___c_u_r_s_o_r.html" title="A WT_CURSOR handle is the interface to a cursor. ">WT_CURSOR</a> handles. A cursor includes:</p>
<ul>
<li>a position within a data source</li>
<li>getter/setters for key and value fields</li>
<li>encoding of fields to store in the data source</li>
<li>methods to navigate within and iterate through the data</li>
</ul>
<h1><a class="anchor" id="cursor_opening"></a>
Opening a cursor</h1>
<p>Cursors are created using the <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#afb5b4a69c2c5cafe411b2b04fdc1c75d" title="Open a new cursor on a data source or duplicate an existing cursor. ">WT_SESSION::open_cursor</a> method. For example, from the program <a class="el" href="ex_cursor_8c-example.html">ex_cursor.c</a>:</p>
<div class="fragment"><div class="line"> ret = session-><a class="code" href="struct_w_t___s_e_s_s_i_o_n.html#afb5b4a69c2c5cafe411b2b04fdc1c75d">open_cursor</a>(session, <span class="stringliteral">"table:world"</span>, NULL, NULL, &cursor);</div>
</div><!-- fragment --><p> Another example from the same program:</p>
<div class="fragment"><div class="line"> ret = session-><a class="code" href="struct_w_t___s_e_s_s_i_o_n.html#afb5b4a69c2c5cafe411b2b04fdc1c75d">open_cursor</a>(session,</div>
<div class="line"> <span class="stringliteral">"table:world(country,population)"</span>, NULL, NULL, &cursor);</div>
</div><!-- fragment --><p> In addition to traditional data sources, cursors in WiredTiger are used to access projections and even created data sources such as the run-time statistics:</p>
<div class="fragment"><div class="line"> ret = session-><a class="code" href="struct_w_t___s_e_s_s_i_o_n.html#afb5b4a69c2c5cafe411b2b04fdc1c75d">open_cursor</a>(session, <span class="stringliteral">"statistics:"</span>, NULL, NULL, &cursor);</div>
</div><!-- fragment --><p> See <a class="el" href="cursors.html">Cursors</a> for more information on available cursor types.</p>
<h1><a class="anchor" id="cursor_closing"></a>
Closing a cursor</h1>
<p>Cursors remain open until either <a class="el" href="struct_w_t___c_u_r_s_o_r.html#aeea071f192cab12245a50fbe71c3460b" title="Close the cursor. ">WT_CURSOR::close</a> is called or the cursor's session is closed, which may either be in <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#a96f25dfa6447034aea1f67ab02ab5698" title="Close the session handle. ">WT_SESSION::close</a> or <a class="el" href="struct_w_t___c_o_n_n_e_c_t_i_o_n.html#af535c517df851eeac8ebf3594d40b545" title="Close a connection. ">WT_CONNECTION::close</a>.</p>
<h1><a class="anchor" id="cursor_position"></a>
Positioning a cursor</h1>
<p>Cursors may be positioned at the beginning of the data source, the end of the data source, at an exact key within the data source, and near a key within the data source.</p>
<p>To invalidate the position of a cursor so that subsequent iterations start from the beginning or end of the data source, use the <a class="el" href="struct_w_t___c_u_r_s_o_r.html#afc1b42c22c9c85e1ba08ce3b34437565" title="Reset the cursor. ">WT_CURSOR::reset</a> method:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span></div>
<div class="line">cursor_reset(<a class="code" href="struct_w_t___c_u_r_s_o_r.html">WT_CURSOR</a> *cursor)</div>
<div class="line">{</div>
<div class="line"> <span class="keywordflow">return</span> (cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#afc1b42c22c9c85e1ba08ce3b34437565">reset</a>(cursor));</div>
<div class="line">}</div>
</div><!-- fragment --><p> To move a cursor forward in the data source, use the cursor <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a0503f16bd8f3d05aa3552f229b3a8e1b" title="Return the next record. ">WT_CURSOR::next</a> method:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span></div>
<div class="line">cursor_forward_scan(<a class="code" href="struct_w_t___c_u_r_s_o_r.html">WT_CURSOR</a> *cursor)</div>
<div class="line">{</div>
<div class="line"> <span class="keyword">const</span> <span class="keywordtype">char</span> *key, *value;</div>
<div class="line"> <span class="keywordtype">int</span> ret;</div>
<div class="line"></div>
<div class="line"> <span class="keywordflow">while</span> ((ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#a0503f16bd8f3d05aa3552f229b3a8e1b">next</a>(cursor)) == 0) {</div>
<div class="line"> ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#af19f6f9d9c7fc248ab38879032620b2f">get_key</a>(cursor, &key);</div>
<div class="line"> ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#af85364a5af50b95bbc46c82e72f75c01">get_value</a>(cursor, &value);</div>
<div class="line"> }</div>
<div class="line"> <span class="keywordflow">return</span> (ret);</div>
<div class="line">}</div>
</div><!-- fragment --><p> If the <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a0503f16bd8f3d05aa3552f229b3a8e1b" title="Return the next record. ">WT_CURSOR::next</a> method is called on a cursor without a position in the data source, it is positioned at the beginning of the data source.</p>
<p>To move a cursor backward in the data source, use the cursor <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a43d6664d2f68902aa63f933864242e76" title="Return the previous record. ">WT_CURSOR::prev</a> method:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span></div>
<div class="line">cursor_reverse_scan(<a class="code" href="struct_w_t___c_u_r_s_o_r.html">WT_CURSOR</a> *cursor)</div>
<div class="line">{</div>
<div class="line"> <span class="keyword">const</span> <span class="keywordtype">char</span> *key, *value;</div>
<div class="line"> <span class="keywordtype">int</span> ret;</div>
<div class="line"></div>
<div class="line"> <span class="keywordflow">while</span> ((ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#a43d6664d2f68902aa63f933864242e76">prev</a>(cursor)) == 0) {</div>
<div class="line"> ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#af19f6f9d9c7fc248ab38879032620b2f">get_key</a>(cursor, &key);</div>
<div class="line"> ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#af85364a5af50b95bbc46c82e72f75c01">get_value</a>(cursor, &value);</div>
<div class="line"> }</div>
<div class="line"> <span class="keywordflow">return</span> (ret);</div>
<div class="line">}</div>
</div><!-- fragment --><p> If the <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a43d6664d2f68902aa63f933864242e76" title="Return the previous record. ">WT_CURSOR::prev</a> method is called on a cursor without a position in the data source, it is positioned at the end of the data source.</p>
<p>To position a cursor at a specific location in the data source, use the <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a7e25b2ced2cf3ec68bd5429bf921c79f" title="Return the record matching the key. ">WT_CURSOR::search</a> method:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span></div>
<div class="line">cursor_search(<a class="code" href="struct_w_t___c_u_r_s_o_r.html">WT_CURSOR</a> *cursor)</div>
<div class="line">{</div>
<div class="line"> <span class="keyword">const</span> <span class="keywordtype">char</span> *value;</div>
<div class="line"> <span class="keywordtype">int</span> ret;</div>
<div class="line"></div>
<div class="line"> cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#ad1088d719df40babc1f57d086691ebdc">set_key</a>(cursor, <span class="stringliteral">"foo"</span>);</div>
<div class="line"></div>
<div class="line"> <span class="keywordflow">if</span> ((ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#a7e25b2ced2cf3ec68bd5429bf921c79f">search</a>(cursor)) == 0)</div>
<div class="line"> ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#af85364a5af50b95bbc46c82e72f75c01">get_value</a>(cursor, &value);</div>
<div class="line"></div>
<div class="line"> <span class="keywordflow">return</span> (ret);</div>
<div class="line">}</div>
</div><!-- fragment --><p> To position a cursor at or near a location in the data source, use the <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a8068ddce20d0775f26f6dac6e5eb209c" title="Return the record matching the key if it exists, or an adjacent record. ">WT_CURSOR::search_near</a> method:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span></div>
<div class="line">cursor_search_near(<a class="code" href="struct_w_t___c_u_r_s_o_r.html">WT_CURSOR</a> *cursor)</div>
<div class="line">{</div>
<div class="line"> <span class="keyword">const</span> <span class="keywordtype">char</span> *key, *value;</div>
<div class="line"> <span class="keywordtype">int</span> exact, ret;</div>
<div class="line"></div>
<div class="line"> cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#ad1088d719df40babc1f57d086691ebdc">set_key</a>(cursor, <span class="stringliteral">"foo"</span>);</div>
<div class="line"></div>
<div class="line"> <span class="keywordflow">if</span> ((ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#a8068ddce20d0775f26f6dac6e5eb209c">search_near</a>(cursor, &exact)) == 0) {</div>
<div class="line"> <span class="keywordflow">switch</span> (exact) {</div>
<div class="line"> <span class="keywordflow">case</span> -1: <span class="comment">/* Returned key smaller than search key */</span></div>
<div class="line"> ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#af19f6f9d9c7fc248ab38879032620b2f">get_key</a>(cursor, &key);</div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> <span class="keywordflow">case</span> 0: <span class="comment">/* Exact match found */</span></div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> <span class="keywordflow">case</span> 1: <span class="comment">/* Returned key larger than search key */</span></div>
<div class="line"> ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#af19f6f9d9c7fc248ab38879032620b2f">get_key</a>(cursor, &key);</div>
<div class="line"> <span class="keywordflow">break</span>;</div>
<div class="line"> }</div>
<div class="line"></div>
<div class="line"> ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#af85364a5af50b95bbc46c82e72f75c01">get_value</a>(cursor, &value);</div>
<div class="line"> }</div>
<div class="line"></div>
<div class="line"> <span class="keywordflow">return</span> (ret);</div>
<div class="line">}</div>
</div><!-- fragment --><p> Cursor positions do not survive transactions: cursors that are open during <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#a7e26b16b26b5870498752322fad790bf" title="Start a transaction in this session. ">WT_SESSION::begin_transaction</a>, <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#a712226eca5ade5bd123026c624468fa2" title="Commit the current transaction. ">WT_SESSION::commit_transaction</a> or <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#ab45f521464ad9e54d9b15efc2ffe20a1" title="Roll back the current transaction. ">WT_SESSION::rollback_transaction</a> will lose their position as if <a class="el" href="struct_w_t___c_u_r_s_o_r.html#afc1b42c22c9c85e1ba08ce3b34437565" title="Reset the cursor. ">WT_CURSOR::reset</a> was called.</p>
<p>Cursors can be configured to move to a random position with <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a0503f16bd8f3d05aa3552f229b3a8e1b" title="Return the next record. ">WT_CURSOR::next</a> is called, see <a class="el" href="cursor_random.html">Cursor random</a> for details.</p>
<h1><a class="anchor" id="cursor_writes"></a>
Inserting and updating</h1>
<p>To insert new data, and optionally update existing data, using a cursor, use the <a class="el" href="struct_w_t___c_u_r_s_o_r.html#aac90d9fbcc031570f924db55f8a1cee3" title="Insert a record and optionally update an existing record. ">WT_CURSOR::insert</a> method:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span></div>
<div class="line">cursor_insert(<a class="code" href="struct_w_t___c_u_r_s_o_r.html">WT_CURSOR</a> *cursor)</div>
<div class="line">{</div>
<div class="line"> cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#ad1088d719df40babc1f57d086691ebdc">set_key</a>(cursor, <span class="stringliteral">"foo"</span>);</div>
<div class="line"> cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#a27f7cbd0cd3e561f6a145704813ad64c">set_value</a>(cursor, <span class="stringliteral">"bar"</span>);</div>
<div class="line"></div>
<div class="line"> <span class="keywordflow">return</span> (cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#aac90d9fbcc031570f924db55f8a1cee3">insert</a>(cursor));</div>
<div class="line">}</div>
</div><!-- fragment --><p> To update existing data using a cursor, use the <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a444cdc0952e7f8d55d23173516c7037f" title="Update an existing record and optionally insert a record. ">WT_CURSOR::update</a> method:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span></div>
<div class="line">cursor_update(<a class="code" href="struct_w_t___c_u_r_s_o_r.html">WT_CURSOR</a> *cursor)</div>
<div class="line">{</div>
<div class="line"> cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#ad1088d719df40babc1f57d086691ebdc">set_key</a>(cursor, <span class="stringliteral">"foo"</span>);</div>
<div class="line"> cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#a27f7cbd0cd3e561f6a145704813ad64c">set_value</a>(cursor, <span class="stringliteral">"newbar"</span>);</div>
<div class="line"></div>
<div class="line"> <span class="keywordflow">return</span> (cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#a444cdc0952e7f8d55d23173516c7037f">update</a>(cursor));</div>
<div class="line">}</div>
</div><!-- fragment --><p> To remove existing data using a cursor, use the <a class="el" href="struct_w_t___c_u_r_s_o_r.html#abbba24fe607fee519c4c9c4669cd4455" title="Remove a record. ">WT_CURSOR::remove</a> method:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span></div>
<div class="line">cursor_remove(<a class="code" href="struct_w_t___c_u_r_s_o_r.html">WT_CURSOR</a> *cursor)</div>
<div class="line">{</div>
<div class="line"> cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#ad1088d719df40babc1f57d086691ebdc">set_key</a>(cursor, <span class="stringliteral">"foo"</span>);</div>
<div class="line"> <span class="keywordflow">return</span> (cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#abbba24fe607fee519c4c9c4669cd4455">remove</a>(cursor));</div>
<div class="line">}</div>
</div><!-- fragment --><p> The <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#afb5b4a69c2c5cafe411b2b04fdc1c75d" title="Open a new cursor on a data source or duplicate an existing cursor. ">WT_SESSION::open_cursor</a> <code>overwrite</code> configuration is <code>true</code> by default, causing <a class="el" href="struct_w_t___c_u_r_s_o_r.html#aac90d9fbcc031570f924db55f8a1cee3" title="Insert a record and optionally update an existing record. ">WT_CURSOR::insert</a>, <a class="el" href="struct_w_t___c_u_r_s_o_r.html#abbba24fe607fee519c4c9c4669cd4455" title="Remove a record. ">WT_CURSOR::remove</a> and <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a444cdc0952e7f8d55d23173516c7037f" title="Update an existing record and optionally insert a record. ">WT_CURSOR::update</a> to ignore the current state of the record, and these methods will succeed regardless of whether or not the record previously exists.</p>
<p>When an application configures <code>overwrite</code> to <code>false</code>, <a class="el" href="struct_w_t___c_u_r_s_o_r.html#aac90d9fbcc031570f924db55f8a1cee3" title="Insert a record and optionally update an existing record. ">WT_CURSOR::insert</a> will fail with <a class="el" href="group__wt.html#gaeca1f3c4a70b8b71b56d2c2fc99a469c" title="Attempt to insert an existing key. ">WT_DUPLICATE_KEY</a> if the record previously exists, and <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a444cdc0952e7f8d55d23173516c7037f" title="Update an existing record and optionally insert a record. ">WT_CURSOR::update</a> and <a class="el" href="struct_w_t___c_u_r_s_o_r.html#abbba24fe607fee519c4c9c4669cd4455" title="Remove a record. ">WT_CURSOR::remove</a> will fail with <a class="el" href="group__wt.html#ga3c9e1b494d95cf34404ab7a974af6bf8" title="Item not found. ">WT_NOTFOUND</a> if the record does not previously exist.</p>
<h1><a class="anchor" id="cursor_error"></a>
Cursor position after error</h1>
<p>After any cursor handle method failure, the cursor's position is undetermined. For cursor operations that expect a key to be set before the operation begins (including <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a7e25b2ced2cf3ec68bd5429bf921c79f" title="Return the record matching the key. ">WT_CURSOR::search</a>, <a class="el" href="struct_w_t___c_u_r_s_o_r.html#aac90d9fbcc031570f924db55f8a1cee3" title="Insert a record and optionally update an existing record. ">WT_CURSOR::insert</a>, <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a444cdc0952e7f8d55d23173516c7037f" title="Update an existing record and optionally insert a record. ">WT_CURSOR::update</a> and <a class="el" href="struct_w_t___c_u_r_s_o_r.html#abbba24fe607fee519c4c9c4669cd4455" title="Remove a record. ">WT_CURSOR::remove</a>), the application's key and value will not be cleared by an error.</p>
<p>Applications that cannot re-position the cursor after failure must duplicate the cursor by calling <a class="el" href="struct_w_t___s_e_s_s_i_o_n.html#afb5b4a69c2c5cafe411b2b04fdc1c75d" title="Open a new cursor on a data source or duplicate an existing cursor. ">WT_SESSION::open_cursor</a> and passing the cursor as the <code>to_dup</code> parameter before calling a cursor method that will attempt to re-position the cursor. Cursor duplication is not supported for the backup, config and statistics cursor types.</p>
<h1><a class="anchor" id="cursor_memory_scoping"></a>
Cursor key/value memory scoping</h1>
<p>When applications pass a pointer (either to a <a class="el" href="group__wt.html#struct_w_t___i_t_e_m" title="A raw item of data to be managed, including a pointer to the data and a length. ">WT_ITEM</a> or a string), to <a class="el" href="struct_w_t___c_u_r_s_o_r.html#ad1088d719df40babc1f57d086691ebdc" title="Set the key for the next operation. ">WT_CURSOR::set_key</a> or <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a27f7cbd0cd3e561f6a145704813ad64c" title="Set the value for the next operation. ">WT_CURSOR::set_value</a>, WiredTiger does not copy the memory referenced by the pointer. For this reason, the application must keep the referenced memory unchanged and valid until the next operation that successfully positions the cursor, modifies the underlying data, or the cursor is reset or closed (discarding its resources). The operations that position the cursor are <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a0503f16bd8f3d05aa3552f229b3a8e1b" title="Return the next record. ">WT_CURSOR::next</a>, <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a43d6664d2f68902aa63f933864242e76" title="Return the previous record. ">WT_CURSOR::prev</a>, <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a7e25b2ced2cf3ec68bd5429bf921c79f" title="Return the record matching the key. ">WT_CURSOR::search</a> and <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a8068ddce20d0775f26f6dac6e5eb209c" title="Return the record matching the key if it exists, or an adjacent record. ">WT_CURSOR::search_near</a>; the operations that modify the underlying data are <a class="el" href="struct_w_t___c_u_r_s_o_r.html#aac90d9fbcc031570f924db55f8a1cee3" title="Insert a record and optionally update an existing record. ">WT_CURSOR::insert</a>, <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a444cdc0952e7f8d55d23173516c7037f" title="Update an existing record and optionally insert a record. ">WT_CURSOR::update</a> and <a class="el" href="struct_w_t___c_u_r_s_o_r.html#abbba24fe607fee519c4c9c4669cd4455" title="Remove a record. ">WT_CURSOR::remove</a>.</p>
<p>If a cursor operation fails (for example, due to a <a class="el" href="group__wt.html#ga5ee3c6fcd074e11efd118f3e68e91db8" title="Conflict between concurrent operations. ">WT_ROLLBACK</a> error), it may be retried without calling <a class="el" href="struct_w_t___c_u_r_s_o_r.html#ad1088d719df40babc1f57d086691ebdc" title="Set the key for the next operation. ">WT_CURSOR::set_key</a> or <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a27f7cbd0cd3e561f6a145704813ad64c" title="Set the value for the next operation. ">WT_CURSOR::set_value</a> again. That is, the cursor may still reference the application-supplied memory until the cursor is successfully positioned, underlying data is modified, or the cursor is closed or reset.</p>
<p>Any pointers returned by <a class="el" href="struct_w_t___c_u_r_s_o_r.html#af19f6f9d9c7fc248ab38879032620b2f" title="Get the key for the current record. ">WT_CURSOR::get_key</a> or <a class="el" href="struct_w_t___c_u_r_s_o_r.html#af85364a5af50b95bbc46c82e72f75c01" title="Get the value for the current record. ">WT_CURSOR::get_value</a> are only valid until a subsequent cursor call that successfully positions the cursor, modifies the underlying data, or the cursor is reset or closed. These pointers may reference private WiredTiger data structures that may not be modified or freed by the application. If a longer scope is required, the application must make a copy of the memory before the cursor is re-used, closed or reset.</p>
<p>The comments in this example code explain when the application can safely modify memory passed to <a class="el" href="struct_w_t___c_u_r_s_o_r.html#ad1088d719df40babc1f57d086691ebdc" title="Set the key for the next operation. ">WT_CURSOR::set_key</a> or <a class="el" href="struct_w_t___c_u_r_s_o_r.html#a27f7cbd0cd3e561f6a145704813ad64c" title="Set the value for the next operation. ">WT_CURSOR::set_value</a>:</p>
<div class="fragment"><div class="line"> (void)snprintf(keybuf, <span class="keyword">sizeof</span>(keybuf), <span class="stringliteral">"%s"</span>, op->key);</div>
<div class="line"> cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#ad1088d719df40babc1f57d086691ebdc">set_key</a>(cursor, keybuf);</div>
<div class="line"> (void)snprintf(valuebuf, <span class="keyword">sizeof</span>(valuebuf), <span class="stringliteral">"%s"</span>, op->value);</div>
<div class="line"> cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#a27f7cbd0cd3e561f6a145704813ad64c">set_value</a>(cursor, valuebuf);</div>
<div class="line"></div>
<div class="line"> <span class="comment">/*</span></div>
<div class="line"><span class="comment"> * The application must keep key and value memory valid until</span></div>
<div class="line"><span class="comment"> * the next operation that positions the cursor, modifies the</span></div>
<div class="line"><span class="comment"> * data, or resets or closes the cursor.</span></div>
<div class="line"><span class="comment"> *</span></div>
<div class="line"><span class="comment"> * Modifying either the key or value buffers is not permitted.</span></div>
<div class="line"><span class="comment"> */</span></div>
<div class="line"></div>
<div class="line"> <span class="comment">/* Apply the operation (insert, update, search or remove). */</span></div>
<div class="line"> <span class="keywordflow">if</span> ((ret = op->apply(cursor)) != 0) {</div>
<div class="line"> fprintf(stderr,</div>
<div class="line"> <span class="stringliteral">"%s: error performing the operation: %s\n"</span>,</div>
<div class="line"> op->op, session-><a class="code" href="struct_w_t___s_e_s_s_i_o_n.html#abe03ccb716e097ed1bb4d42eb733c1f9">strerror</a>(session, ret));</div>
<div class="line"> <span class="keywordflow">return</span> (ret);</div>
<div class="line"> }</div>
<div class="line"></div>
<div class="line"> <span class="comment">/*</span></div>
<div class="line"><span class="comment"> * The cursor no longer references application memory, so</span></div>
<div class="line"><span class="comment"> * application buffers can be safely overwritten.</span></div>
<div class="line"><span class="comment"> */</span></div>
<div class="line"> strcpy(keybuf, <span class="stringliteral">"no key"</span>);</div>
<div class="line"> strcpy(valuebuf, <span class="stringliteral">"no value"</span>);</div>
<div class="line"></div>
<div class="line"> <span class="comment">/*</span></div>
<div class="line"><span class="comment"> * Check that get_key/value behave as expected after the</span></div>
<div class="line"><span class="comment"> * operation.</span></div>
<div class="line"><span class="comment"> */</span></div>
<div class="line"> <span class="keywordflow">if</span> (op->apply == cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#aac90d9fbcc031570f924db55f8a1cee3">insert</a>) {</div>
<div class="line"> <span class="comment">/*</span></div>
<div class="line"><span class="comment"> * WT_CURSOR::insert no longer references application</span></div>
<div class="line"><span class="comment"> * memory, but as it does not position the cursor, it</span></div>
<div class="line"><span class="comment"> * doesn't reference memory owned by the cursor, either.</span></div>
<div class="line"><span class="comment"> */</span></div>
<div class="line"> <span class="keywordflow">if</span> ((ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#af19f6f9d9c7fc248ab38879032620b2f">get_key</a>(cursor, &key)) == 0 ||</div>
<div class="line"> (ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#af85364a5af50b95bbc46c82e72f75c01">get_value</a>(cursor, &value)) == 0) {</div>
<div class="line"> fprintf(stderr,</div>
<div class="line"> <span class="stringliteral">"%s: error in s get_key/value: %s\n"</span>,</div>
<div class="line"> op->op, session-><a class="code" href="struct_w_t___s_e_s_s_i_o_n.html#abe03ccb716e097ed1bb4d42eb733c1f9">strerror</a>(session, ret));</div>
<div class="line"> <span class="keywordflow">return</span> (ret);</div>
<div class="line"> }</div>
<div class="line"> <span class="keywordflow">continue</span>;</div>
<div class="line"> }</div>
<div class="line"> <span class="keywordflow">if</span> (op->apply == cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#abbba24fe607fee519c4c9c4669cd4455">remove</a>) {</div>
<div class="line"> <span class="comment">/*</span></div>
<div class="line"><span class="comment"> * WT_CURSOR::remove no longer references application</span></div>
<div class="line"><span class="comment"> * memory; as it does not position the cursor, it will</span></div>
<div class="line"><span class="comment"> * reference key memory owned by the cursor, but has no</span></div>
<div class="line"><span class="comment"> * value.</span></div>
<div class="line"><span class="comment"> */</span></div>
<div class="line"> <span class="keywordflow">if</span> ((ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#af19f6f9d9c7fc248ab38879032620b2f">get_key</a>(cursor, &key)) != 0 ||</div>
<div class="line"> (ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#af85364a5af50b95bbc46c82e72f75c01">get_value</a>(cursor, &value)) == 0) {</div>
<div class="line"> fprintf(stderr,</div>
<div class="line"> <span class="stringliteral">"%s: error in get_key/value: %s\n"</span>,</div>
<div class="line"> op->op, session-><a class="code" href="struct_w_t___s_e_s_s_i_o_n.html#abe03ccb716e097ed1bb4d42eb733c1f9">strerror</a>(session, ret));</div>
<div class="line"> <span class="keywordflow">return</span> (ret);</div>
<div class="line"> }</div>
<div class="line"> } <span class="keywordflow">else</span> <span class="comment">/* search, update */</span>{</div>
<div class="line"> <span class="comment">/*</span></div>
<div class="line"><span class="comment"> * WT_CURSOR::search and WT_CURSOR::update no longer</span></div>
<div class="line"><span class="comment"> * reference application memory; as they position the</span></div>
<div class="line"><span class="comment"> * cursor, they will reference key/value memory owned</span></div>
<div class="line"><span class="comment"> * by the cursor.</span></div>
<div class="line"><span class="comment"> */</span></div>
<div class="line"> <span class="keywordflow">if</span> ((ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#af19f6f9d9c7fc248ab38879032620b2f">get_key</a>(cursor, &key)) != 0 ||</div>
<div class="line"> (ret = cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#af85364a5af50b95bbc46c82e72f75c01">get_value</a>(cursor, &value)) != 0) {</div>
<div class="line"> fprintf(stderr,</div>
<div class="line"> <span class="stringliteral">"%s: error in get_key/value: %s\n"</span>,</div>
<div class="line"> op->op, session-><a class="code" href="struct_w_t___s_e_s_s_i_o_n.html#abe03ccb716e097ed1bb4d42eb733c1f9">strerror</a>(session, ret));</div>
<div class="line"> <span class="keywordflow">return</span> (ret);</div>
<div class="line"> }</div>
<div class="line"> }</div>
<div class="line"></div>
<div class="line"> <span class="comment">/*</span></div>
<div class="line"><span class="comment"> * Modifying the memory referenced by either key or value is</span></div>
<div class="line"><span class="comment"> * not permitted.</span></div>
<div class="line"><span class="comment"> *</span></div>
<div class="line"><span class="comment"> * Check that the cursor's key and value are what we expect.</span></div>
<div class="line"><span class="comment"> */</span></div>
<div class="line"> <span class="keywordflow">if</span> (key == keybuf ||</div>
<div class="line"> (op->apply != cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#abbba24fe607fee519c4c9c4669cd4455">remove</a> && value == valuebuf)) {</div>
<div class="line"> fprintf(stderr,</div>
<div class="line"> <span class="stringliteral">"%s: cursor points at application memory!\n"</span>,</div>
<div class="line"> op->op);</div>
<div class="line"> <span class="keywordflow">return</span> (EINVAL);</div>
<div class="line"> }</div>
<div class="line"></div>
<div class="line"> <span class="keywordflow">if</span> (strcmp(key, op->key) != 0 ||</div>
<div class="line"> (op->apply != cursor-><a class="code" href="struct_w_t___c_u_r_s_o_r.html#abbba24fe607fee519c4c9c4669cd4455">remove</a> &&</div>
<div class="line"> strcmp(value, op->value) != 0)) {</div>
<div class="line"> fprintf(stderr,</div>
<div class="line"> <span class="stringliteral">"%s: unexpected key / value!\n"</span>, op->op);</div>
<div class="line"> <span class="keywordflow">return</span> (EINVAL);</div>
<div class="line"> }</div>
</div><!-- fragment --></div></div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="navelem"><a class="el" href="index.html">Reference Guide</a></li><li class="navelem"><a class="el" href="programming.html">Writing WiredTiger applications</a></li><li class="navelem"><a class="el" href="cursors.html">Cursors</a></li>
<li class="footer">Copyright (c) 2008-2016 MongoDB, Inc. All rights reserved. Contact <a href="mailto:[email protected]">[email protected]</a> for more information.</li>
</ul>
</div>
</body>
</html>