Git init
[pkgs/e/elektra.git] / doc / elektra-api / html / group__keyset.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 <html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
3 <title>Elektra Projekt: KeySet :: Class Methods</title>
4 <link href="doxygen.css" rel="stylesheet" type="text/css">
5 <link href="tabs.css" rel="stylesheet" type="text/css">
6 </head><body>
7 <!-- Generated by Doxygen 1.5.6 -->
8 <div class="navigation" id="top">
9   <div class="tabs">
10     <ul>
11       <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
12       <li><a href="pages.html"><span>Related&nbsp;Pages</span></a></li>
13       <li><a href="modules.html"><span>Modules</span></a></li>
14     </ul>
15   </div>
16 </div>
17 <div class="contents">
18 <h1>KeySet :: Class Methods</h1>Methods to manipulate KeySets.  
19 <a href="#_details">More...</a><table border="0" cellpadding="0" cellspacing="0">
20 <tr><td></td></tr>
21 <tr><td colspan="2"><br><h2>Functions</h2></td></tr>
22 <tr><td class="memItemLeft" nowrap align="right" valign="top">KeySet *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__keyset.html#g671e1aaee3ae9dc13b4834a4ddbd2c3c">ksNew</a> (size_t alloc,...)</td></tr>
23
24 <tr><td class="memItemLeft" nowrap align="right" valign="top">KeySet *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__keyset.html#gc59e4b328245463f1451f68d5106151c">ksDup</a> (const KeySet *source)</td></tr>
25
26 <tr><td class="memItemLeft" nowrap align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__keyset.html#gba1f1dbea191f4d7e7eb3e4296ae7d5e">ksCopy</a> (KeySet *dest, const KeySet *source)</td></tr>
27
28 <tr><td class="memItemLeft" nowrap align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel</a> (KeySet *ks)</td></tr>
29
30 <tr><td class="memItemLeft" nowrap align="right" valign="top">void&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__keyset.html#g023554d395ccf2319a3807b8b5d2530c">ksSort</a> (KeySet *ks)</td></tr>
31
32 <tr><td class="memItemLeft" nowrap align="right" valign="top">ssize_t&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__keyset.html#g7474ad6b0a0fa969dbdf267ba5770eee">ksGetSize</a> (const KeySet *ks)</td></tr>
33
34 <tr><td class="memItemLeft" nowrap align="right" valign="top">ssize_t&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__keyset.html#ga5a1d467a4d71041edce68ea7748ce45">ksAppendKey</a> (KeySet *ks, Key *toAppend)</td></tr>
35
36 <tr><td class="memItemLeft" nowrap align="right" valign="top">ssize_t&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__keyset.html#g21eb9c3a14a604ee3a8bdc779232e7b7">ksAppend</a> (KeySet *ks, const KeySet *toAppend)</td></tr>
37
38 <tr><td class="memItemLeft" nowrap align="right" valign="top">Key *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__keyset.html#ge42530b04defb772059de0600159cf69">ksPop</a> (KeySet *ks)</td></tr>
39
40 <tr><td class="memItemLeft" nowrap align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind</a> (KeySet *ks)</td></tr>
41
42 <tr><td class="memItemLeft" nowrap align="right" valign="top">Key *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__keyset.html#g317321c9065b5a4b3e33fe1c399bcec9">ksNext</a> (KeySet *ks)</td></tr>
43
44 <tr><td class="memItemLeft" nowrap align="right" valign="top">Key *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent</a> (const KeySet *ks)</td></tr>
45
46 <tr><td class="memItemLeft" nowrap align="right" valign="top">Key *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__keyset.html#ge7dbf3aef70e67b5328475eb3d1f92f5">ksHead</a> (const KeySet *ks)</td></tr>
47
48 <tr><td class="memItemLeft" nowrap align="right" valign="top">Key *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__keyset.html#gdca442c4ab43cf532b15091d7711559e">ksTail</a> (const KeySet *ks)</td></tr>
49
50 <tr><td class="memItemLeft" nowrap align="right" valign="top">cursor_t&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__keyset.html#gffe507ab9281c322eb16c3e992075d29">ksGetCursor</a> (const KeySet *ks)</td></tr>
51
52 <tr><td class="memItemLeft" nowrap align="right" valign="top">int&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__keyset.html#gd94c9ffaa3e8034564c0712fd407c345">ksSetCursor</a> (KeySet *ks, cursor_t cursor)</td></tr>
53
54 <tr><td class="memItemLeft" nowrap align="right" valign="top">Key *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup</a> (KeySet *ks, Key *key, option_t options)</td></tr>
55
56 <tr><td class="memItemLeft" nowrap align="right" valign="top">Key *&nbsp;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__keyset.html#gd2e30fb6d4739d917c5abb2ac2f9c1a1">ksLookupByName</a> (KeySet *ks, const char *name, option_t options)</td></tr>
57
58 </table>
59 <hr><a name="_details"></a><h2>Detailed Description</h2>
60 Methods to manipulate KeySets. 
61 <p>
62 A KeySet is a unsorted set of keys.<p>
63 Terminate with ksNew(0) or ksNew(20, ..., KS_END) This is because there is a list of Key* required and KS_END has the length of (Key*).<p>
64 It can be implemented in various ways like a linked list or with a dynamically allocated array.<p>
65 With <a class="el" href="group__keyset.html#g671e1aaee3ae9dc13b4834a4ddbd2c3c">ksNew()</a> you can create a new KeySet.<p>
66 You can add keys with <a class="el" href="group__keyset.html#ga5a1d467a4d71041edce68ea7748ce45">ksAppendKey()</a> in the keyset. <a class="el" href="group__keyset.html#g7474ad6b0a0fa969dbdf267ba5770eee">ksGetSize()</a> tells you the current size of the keyset.<p>
67 With <a class="el" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind()</a> and <a class="el" href="group__keyset.html#g317321c9065b5a4b3e33fe1c399bcec9">ksNext()</a> you can navigate through the keyset. Don't expect any particular order, but it is assured that you will get every key of the set.<p>
68 KeySets have an <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">internal cursor </a>. This is used for <a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a> and <a class="el" href="group__kdb.html#g953cf29721e6000c2516cd6b5d36f571">kdbSet()</a>.<p>
69 KeySet has a fundamental meaning inside elektra. It makes it possible to get and store many keys at once inside the database. In addition to that the class can be used as high level datastructure in applications. With <a class="el" href="group__keyset.html#gd2e30fb6d4739d917c5abb2ac2f9c1a1">ksLookupByName()</a> it is possible to fetch easily specific keys out of the list of keys.<p>
70 You can easily create and iterate keys: <div class="fragment"><pre class="fragment"><span class="preprocessor">#include &lt;kdb.h&gt;</span>
71
72 <span class="comment">// create a new keyset with 3 keys</span>
73 <span class="comment">// with a hint that about 20 keys will be inside</span>
74 KeySet *myConfig = <a class="code" href="group__keyset.html#g671e1aaee3ae9dc13b4834a4ddbd2c3c">ksNew</a>(20,
75         <a class="code" href="group__key.html#gf6893c038b3ebee90c73a9ea8356bebf">keyNew</a> (<span class="stringliteral">"user/name1"</span>, 0),
76         <a class="code" href="group__key.html#gf6893c038b3ebee90c73a9ea8356bebf">keyNew</a> (<span class="stringliteral">"user/name2"</span>, 0),
77         <a class="code" href="group__key.html#gf6893c038b3ebee90c73a9ea8356bebf">keyNew</a> (<span class="stringliteral">"user/name3"</span>, 0),
78         KS_END);
79 <span class="comment">// append a key in the keyset</span>
80 <a class="code" href="group__keyset.html#ga5a1d467a4d71041edce68ea7748ce45">ksAppendKey</a>(myConfig, <a class="code" href="group__key.html#gf6893c038b3ebee90c73a9ea8356bebf">keyNew</a>(<span class="stringliteral">"user/name4"</span>, 0));
81
82 Key *current;
83 <a class="code" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind</a>(myConfig);
84 <span class="keywordflow">while</span> ((current=<a class="code" href="group__keyset.html#g317321c9065b5a4b3e33fe1c399bcec9">ksNext</a>(myConfig))!=0) {
85         printf(<span class="stringliteral">"Key name is %s.\n"</span>, <a class="code" href="group__keyname.html#g8e805c726a60da921d3736cda7813513">keyName</a> (current));
86 }
87 <a class="code" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel</a> (myConfig); <span class="comment">// delete keyset and all keys appended</span>
88 </pre></div> <hr><h2>Function Documentation</h2>
89 <a class="anchor" name="g21eb9c3a14a604ee3a8bdc779232e7b7"></a><!-- doxytag: member="keyset.c::ksAppend" ref="g21eb9c3a14a604ee3a8bdc779232e7b7" args="(KeySet *ks, const KeySet *toAppend)" -->
90 <div class="memitem">
91 <div class="memproto">
92       <table class="memname">
93         <tr>
94           <td class="memname">ssize_t ksAppend           </td>
95           <td>(</td>
96           <td class="paramtype">KeySet *&nbsp;</td>
97           <td class="paramname"> <em>ks</em>, </td>
98         </tr>
99         <tr>
100           <td class="paramkey"></td>
101           <td></td>
102           <td class="paramtype">const KeySet *&nbsp;</td>
103           <td class="paramname"> <em>toAppend</em></td><td>&nbsp;</td>
104         </tr>
105         <tr>
106           <td></td>
107           <td>)</td>
108           <td></td><td></td><td></td>
109         </tr>
110       </table>
111 </div>
112 <div class="memdoc">
113
114 <p>
115 Append all <code>toAppend</code> contained keys to the end of the <code>ks</code>.<p>
116 <code>toAppend</code> KeySet will be left unchanged.<p>
117 Makes the keyset dirty, see <a class="el" href="group__keyset.html#g023554d395ccf2319a3807b8b5d2530c">ksSort()</a>.<p>
118 <dl class="return" compact><dt><b>Returns:</b></dt><dd>the size of the KeySet after transfer <p>
119 -1 on NULL pointers </dd></dl>
120 <dl compact><dt><b>Parameters:</b></dt><dd>
121   <table border="0" cellspacing="2" cellpadding="0">
122     <tr><td valign="top"></td><td valign="top"><em>ks</em>&nbsp;</td><td>the KeySet that will receive the keys </td></tr>
123     <tr><td valign="top"></td><td valign="top"><em>toAppend</em>&nbsp;</td><td>the KeySet that provides the keys that will be transfered </td></tr>
124   </table>
125 </dl>
126 <dl class="see" compact><dt><b>See also:</b></dt><dd><a class="el" href="group__keyset.html#ga5a1d467a4d71041edce68ea7748ce45">ksAppendKey()</a>, ksInsert(), ksInsertKeys() </dd></dl>
127
128 </div>
129 </div><p>
130 <a class="anchor" name="ga5a1d467a4d71041edce68ea7748ce45"></a><!-- doxytag: member="keyset.c::ksAppendKey" ref="ga5a1d467a4d71041edce68ea7748ce45" args="(KeySet *ks, Key *toAppend)" -->
131 <div class="memitem">
132 <div class="memproto">
133       <table class="memname">
134         <tr>
135           <td class="memname">ssize_t ksAppendKey           </td>
136           <td>(</td>
137           <td class="paramtype">KeySet *&nbsp;</td>
138           <td class="paramname"> <em>ks</em>, </td>
139         </tr>
140         <tr>
141           <td class="paramkey"></td>
142           <td></td>
143           <td class="paramtype">Key *&nbsp;</td>
144           <td class="paramname"> <em>toAppend</em></td><td>&nbsp;</td>
145         </tr>
146         <tr>
147           <td></td>
148           <td>)</td>
149           <td></td><td></td><td></td>
150         </tr>
151       </table>
152 </div>
153 <div class="memdoc">
154
155 <p>
156 Appends a Key to the end of <code>ks</code>.<p>
157 A pointer to the key will be stored, and not a private copy. So a future <a class="el" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel()</a> on <code>ks</code> may <a class="el" href="group__key.html#g3df95bbc2494e3e6703ece5639be5bb1">keyDel()</a> the <code>toAppend</code> object, see <a class="el" href="group__key.html#g4aabc4272506dd63161db2bbb42de8ae">keyGetRef()</a>.<p>
158 The reference counter of the key will be incremented, and thus toAppend is not const.<p>
159 The KeySet internal cursor is not moved.<p>
160 Makes the keyset dirty, see <a class="el" href="group__keyset.html#g023554d395ccf2319a3807b8b5d2530c">ksSort()</a>.<p>
161 <dl class="return" compact><dt><b>Returns:</b></dt><dd>the size of the KeySet after insertion <p>
162 -1 on NULL pointers </dd></dl>
163 <dl compact><dt><b>Parameters:</b></dt><dd>
164   <table border="0" cellspacing="2" cellpadding="0">
165     <tr><td valign="top"></td><td valign="top"><em>ks</em>&nbsp;</td><td>KeySet that will receive the key </td></tr>
166     <tr><td valign="top"></td><td valign="top"><em>toAppend</em>&nbsp;</td><td>Key that will be appended to ks </td></tr>
167   </table>
168 </dl>
169 <dl class="see" compact><dt><b>See also:</b></dt><dd>ksInsert(), ksInsertKeys(), <a class="el" href="group__keyset.html#g21eb9c3a14a604ee3a8bdc779232e7b7">ksAppend()</a>, <a class="el" href="group__key.html#gf6893c038b3ebee90c73a9ea8356bebf">keyNew()</a>, <a class="el" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel()</a> <p>
170 <a class="el" href="group__key.html#g6970a6f254d67af7e39f8e469bb162f1">keyIncRef()</a> </dd></dl>
171
172 </div>
173 </div><p>
174 <a class="anchor" name="gba1f1dbea191f4d7e7eb3e4296ae7d5e"></a><!-- doxytag: member="keyset.c::ksCopy" ref="gba1f1dbea191f4d7e7eb3e4296ae7d5e" args="(KeySet *dest, const KeySet *source)" -->
175 <div class="memitem">
176 <div class="memproto">
177       <table class="memname">
178         <tr>
179           <td class="memname">int ksCopy           </td>
180           <td>(</td>
181           <td class="paramtype">KeySet *&nbsp;</td>
182           <td class="paramname"> <em>dest</em>, </td>
183         </tr>
184         <tr>
185           <td class="paramkey"></td>
186           <td></td>
187           <td class="paramtype">const KeySet *&nbsp;</td>
188           <td class="paramname"> <em>source</em></td><td>&nbsp;</td>
189         </tr>
190         <tr>
191           <td></td>
192           <td>)</td>
193           <td></td><td></td><td></td>
194         </tr>
195       </table>
196 </div>
197 <div class="memdoc">
198
199 <p>
200 Copy a keyset.<p>
201 Most often you may want a duplicate of a keyset, see <a class="el" href="group__keyset.html#gc59e4b328245463f1451f68d5106151c">ksDup()</a> or append keys, see <a class="el" href="group__keyset.html#g21eb9c3a14a604ee3a8bdc779232e7b7">ksAppend()</a>. But in some situations you need to copy a keyset to a existing keyset, for that this function exists.<p>
202 You can also use it to clear a keyset when you pass a NULL pointer as <code>source</code>.<p>
203 Note that all keys in <code>dest</code> will be deleted. Afterwards the content of the source will be added to the destination and the <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a> is set properly in <code>dest</code>.<p>
204 A flat copy is made, so the keys will not be duplicated, but there reference counter is updated, so both keysets need to be <a class="el" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel()</a>.<p>
205 <div class="fragment"><pre class="fragment"><span class="keywordtype">int</span> f (KeySet *ks)
206 {
207         KeySet *c = <a class="code" href="group__keyset.html#g671e1aaee3ae9dc13b4834a4ddbd2c3c">ksNew</a> (20, ..., KS_END);
208         <span class="comment">// c receives keys</span>
209         <a class="code" href="group__keyset.html#gba1f1dbea191f4d7e7eb3e4296ae7d5e">ksCopy</a> (ks, c); <span class="comment">// pass the keyset to the caller</span>
210
211         <a class="code" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel</a> (c);
212 }       <span class="comment">// caller needs to ksDel (ks)</span>
213 </pre></div><p>
214 <dl compact><dt><b>Parameters:</b></dt><dd>
215   <table border="0" cellspacing="2" cellpadding="0">
216     <tr><td valign="top"></td><td valign="top"><em>source</em>&nbsp;</td><td>has to be an initialized source KeySet or NULL </td></tr>
217     <tr><td valign="top"></td><td valign="top"><em>dest</em>&nbsp;</td><td>has to be an initialized KeySet where to write the keys </td></tr>
218   </table>
219 </dl>
220 <dl class="return" compact><dt><b>Returns:</b></dt><dd>1 on success <p>
221 0 if dest was cleared successfully (source is NULL) <p>
222 -1 on NULL pointer </dd></dl>
223 <dl class="see" compact><dt><b>See also:</b></dt><dd><a class="el" href="group__keyset.html#g671e1aaee3ae9dc13b4834a4ddbd2c3c">ksNew()</a>, <a class="el" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel()</a>, <a class="el" href="group__keyset.html#gc59e4b328245463f1451f68d5106151c">ksDup()</a> <p>
224 <a class="el" href="group__key.html#g6a12cbbe656a1ad9f41b8c681d7a2f92">keyCopy()</a> for copying keys </dd></dl>
225
226 </div>
227 </div><p>
228 <a class="anchor" name="g4287b9416912c5f2ab9c195cb74fb094"></a><!-- doxytag: member="keyset.c::ksCurrent" ref="g4287b9416912c5f2ab9c195cb74fb094" args="(const KeySet *ks)" -->
229 <div class="memitem">
230 <div class="memproto">
231       <table class="memname">
232         <tr>
233           <td class="memname">Key* ksCurrent           </td>
234           <td>(</td>
235           <td class="paramtype">const KeySet *&nbsp;</td>
236           <td class="paramname"> <em>ks</em>          </td>
237           <td>&nbsp;)&nbsp;</td>
238           <td></td>
239         </tr>
240       </table>
241 </div>
242 <div class="memdoc">
243
244 <p>
245 Return the current Key.<p>
246 The pointer is NULL if you reached the end or after <a class="el" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind()</a>.<p>
247 <dl class="note" compact><dt><b>Note:</b></dt><dd>You must not delete the key or change the key, use <a class="el" href="group__keyset.html#ge42530b04defb772059de0600159cf69">ksPop()</a> if you want to delete it.</dd></dl>
248 <dl compact><dt><b>Parameters:</b></dt><dd>
249   <table border="0" cellspacing="2" cellpadding="0">
250     <tr><td valign="top"></td><td valign="top"><em>ks</em>&nbsp;</td><td>the keyset object to work with </td></tr>
251   </table>
252 </dl>
253 <dl class="return" compact><dt><b>Returns:</b></dt><dd>pointer to the Key pointed by <code>ks's</code> cursor <p>
254 0 on NULL pointer </dd></dl>
255 <dl class="see" compact><dt><b>See also:</b></dt><dd><a class="el" href="group__keyset.html#g317321c9065b5a4b3e33fe1c399bcec9">ksNext()</a>, <a class="el" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind()</a> <p>
256 kdbMonitorKeys() for a usage example </dd></dl>
257
258 </div>
259 </div><p>
260 <a class="anchor" name="g27e5c16473b02a422238c8d970db7ac8"></a><!-- doxytag: member="keyset.c::ksDel" ref="g27e5c16473b02a422238c8d970db7ac8" args="(KeySet *ks)" -->
261 <div class="memitem">
262 <div class="memproto">
263       <table class="memname">
264         <tr>
265           <td class="memname">int ksDel           </td>
266           <td>(</td>
267           <td class="paramtype">KeySet *&nbsp;</td>
268           <td class="paramname"> <em>ks</em>          </td>
269           <td>&nbsp;)&nbsp;</td>
270           <td></td>
271         </tr>
272       </table>
273 </div>
274 <div class="memdoc">
275
276 <p>
277 A destructor for KeySet objects.<p>
278 Cleans all internal dynamic attributes, decrement all reference pointers to all keys and then <a class="el" href="group__key.html#g3df95bbc2494e3e6703ece5639be5bb1">keyDel()</a> all contained Keys, and free()s the release the KeySet object memory (that was previously allocated by <a class="el" href="group__keyset.html#g671e1aaee3ae9dc13b4834a4ddbd2c3c">ksNew()</a>).<p>
279 <dl compact><dt><b>Parameters:</b></dt><dd>
280   <table border="0" cellspacing="2" cellpadding="0">
281     <tr><td valign="top"></td><td valign="top"><em>ks</em>&nbsp;</td><td>the keyset object to work with </td></tr>
282   </table>
283 </dl>
284 <dl class="return" compact><dt><b>Returns:</b></dt><dd>0 when the keyset was freed <p>
285 -1 on null pointer </dd></dl>
286 <dl class="see" compact><dt><b>See also:</b></dt><dd><a class="el" href="group__keyset.html#g671e1aaee3ae9dc13b4834a4ddbd2c3c">ksNew()</a> </dd></dl>
287
288 </div>
289 </div><p>
290 <a class="anchor" name="gc59e4b328245463f1451f68d5106151c"></a><!-- doxytag: member="keyset.c::ksDup" ref="gc59e4b328245463f1451f68d5106151c" args="(const KeySet *source)" -->
291 <div class="memitem">
292 <div class="memproto">
293       <table class="memname">
294         <tr>
295           <td class="memname">KeySet* ksDup           </td>
296           <td>(</td>
297           <td class="paramtype">const KeySet *&nbsp;</td>
298           <td class="paramname"> <em>source</em>          </td>
299           <td>&nbsp;)&nbsp;</td>
300           <td></td>
301         </tr>
302       </table>
303 </div>
304 <div class="memdoc">
305
306 <p>
307 Return a duplicate of a keyset.<p>
308 Objects created with <a class="el" href="group__keyset.html#gc59e4b328245463f1451f68d5106151c">ksDup()</a> must be destroyed with <a class="el" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel()</a>.<p>
309 Memory will be allocated as needed for dynamic properties, so you need to <a class="el" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel()</a> the returned pointer.<p>
310 A flat copy is made, so the keys will not be duplicated, but there reference counter is updated, so both keysets need <a class="el" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel()</a>.<p>
311 <dl compact><dt><b>Parameters:</b></dt><dd>
312   <table border="0" cellspacing="2" cellpadding="0">
313     <tr><td valign="top"></td><td valign="top"><em>source</em>&nbsp;</td><td>has to be an initializised source KeySet </td></tr>
314   </table>
315 </dl>
316 <dl class="return" compact><dt><b>Returns:</b></dt><dd>a flat copy of source on success <p>
317 0 on NULL pointer </dd></dl>
318 <dl class="see" compact><dt><b>See also:</b></dt><dd><a class="el" href="group__keyset.html#g671e1aaee3ae9dc13b4834a4ddbd2c3c">ksNew()</a>, <a class="el" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel()</a> <p>
319 <a class="el" href="group__key.html#ge6ec6a60cc4b8c1463fa08623d056ce3">keyDup()</a> for <a class="el" href="group__key.html" title="Key construction and initialization methods.">Key :: Basic Methods</a> duplication </dd></dl>
320
321 </div>
322 </div><p>
323 <a class="anchor" name="gffe507ab9281c322eb16c3e992075d29"></a><!-- doxytag: member="keyset.c::ksGetCursor" ref="gffe507ab9281c322eb16c3e992075d29" args="(const KeySet *ks)" -->
324 <div class="memitem">
325 <div class="memproto">
326       <table class="memname">
327         <tr>
328           <td class="memname">cursor_t ksGetCursor           </td>
329           <td>(</td>
330           <td class="paramtype">const KeySet *&nbsp;</td>
331           <td class="paramname"> <em>ks</em>          </td>
332           <td>&nbsp;)&nbsp;</td>
333           <td></td>
334         </tr>
335       </table>
336 </div>
337 <div class="memdoc">
338
339 <p>
340 Get the KeySet internal cursor.<p>
341 Use it to get the cursor of the actual position.<p>
342 <dl class="warning" compact><dt><b>Warning:</b></dt><dd>Cursors are getting invalid when the key was <a class="el" href="group__keyset.html#ge42530b04defb772059de0600159cf69">ksPop()</a>ed or <a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a> with KDB_O_POP was used.</dd></dl>
343 <h2><a class="anchor" name="readahead">
344 Read ahead</a></h2>
345 With the cursors it is possible to read ahead in a keyset:<p>
346 <div class="fragment"><pre class="fragment">cursor_t jump;
347 <a class="code" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind</a> (ks);
348 <span class="keywordflow">while</span> ((key = keyNext (ks))!=0)
349 {
350         <span class="comment">// now mark this key</span>
351         jump = <a class="code" href="group__keyset.html#gffe507ab9281c322eb16c3e992075d29">ksGetCursor</a>(ks);
352
353         <span class="comment">//code..</span>
354         keyNext (ks); <span class="comment">// now browse on</span>
355         <span class="comment">// use ksCurrent(ks) to check the keys</span>
356         <span class="comment">//code..</span>
357
358         <span class="comment">// jump back to the position marked before</span>
359         <a class="code" href="group__keyset.html#gd94c9ffaa3e8034564c0712fd407c345">ksSetCursor</a>(ks, jump);
360 }
361 </pre></div><h2><a class="anchor" name="restore">
362 Restoring state</a></h2>
363 It can also be used to restore the state of a keyset in a function<p>
364 <div class="fragment"><pre class="fragment"><span class="keywordtype">int</span> f (KeySet *ks)
365 {
366         cursor_t state = <a class="code" href="group__keyset.html#gffe507ab9281c322eb16c3e992075d29">ksGetCursor</a>(ks);
367
368         <span class="comment">// work with keyset</span>
369
370         <span class="comment">// now bring the keyset to the state before</span>
371         <a class="code" href="group__keyset.html#gd94c9ffaa3e8034564c0712fd407c345">ksSetCursor</a> (ks, state);
372 }
373 </pre></div><p>
374 It is of course possible to make the KeySet const and cast its const away to set the cursor. Another way to achieve the same is to <a class="el" href="group__keyset.html#gc59e4b328245463f1451f68d5106151c">ksDup()</a> the keyset, but it is not as efficient.<p>
375 An invalid cursor will be returned directly after <a class="el" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind()</a>. When you set an invalid cursor <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a> is 0 and <a class="el" href="group__keyset.html#g317321c9065b5a4b3e33fe1c399bcec9">ksNext()</a> == <a class="el" href="group__keyset.html#ge7dbf3aef70e67b5328475eb3d1f92f5">ksHead()</a>.<p>
376 <dl class="note" compact><dt><b>Note:</b></dt><dd>Only use a cursor for the same keyset which it was made for.</dd></dl>
377 <dl compact><dt><b>Parameters:</b></dt><dd>
378   <table border="0" cellspacing="2" cellpadding="0">
379     <tr><td valign="top"></td><td valign="top"><em>ks</em>&nbsp;</td><td>the keyset object to work with </td></tr>
380   </table>
381 </dl>
382 <dl class="return" compact><dt><b>Returns:</b></dt><dd>a valid cursor on success <p>
383 an invalid cursor on NULL pointer or after <a class="el" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind()</a> </dd></dl>
384 <dl class="see" compact><dt><b>See also:</b></dt><dd><a class="el" href="group__keyset.html#g317321c9065b5a4b3e33fe1c399bcec9">ksNext()</a>, <a class="el" href="group__keyset.html#gd94c9ffaa3e8034564c0712fd407c345">ksSetCursor()</a> </dd></dl>
385
386 </div>
387 </div><p>
388 <a class="anchor" name="g7474ad6b0a0fa969dbdf267ba5770eee"></a><!-- doxytag: member="keyset.c::ksGetSize" ref="g7474ad6b0a0fa969dbdf267ba5770eee" args="(const KeySet *ks)" -->
389 <div class="memitem">
390 <div class="memproto">
391       <table class="memname">
392         <tr>
393           <td class="memname">ssize_t ksGetSize           </td>
394           <td>(</td>
395           <td class="paramtype">const KeySet *&nbsp;</td>
396           <td class="paramname"> <em>ks</em>          </td>
397           <td>&nbsp;)&nbsp;</td>
398           <td></td>
399         </tr>
400       </table>
401 </div>
402 <div class="memdoc">
403
404 <p>
405 Return the number of keys that <code>ks</code> contains.<p>
406 <dl compact><dt><b>Parameters:</b></dt><dd>
407   <table border="0" cellspacing="2" cellpadding="0">
408     <tr><td valign="top"></td><td valign="top"><em>ks</em>&nbsp;</td><td>the keyset object to work with </td></tr>
409   </table>
410 </dl>
411 <dl class="return" compact><dt><b>Returns:</b></dt><dd>the number of keys that <code>ks</code> contains. <p>
412 -1 on NULL pointer </dd></dl>
413 <dl class="see" compact><dt><b>See also:</b></dt><dd>ksNew(0), <a class="el" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel()</a> </dd></dl>
414
415 </div>
416 </div><p>
417 <a class="anchor" name="ge7dbf3aef70e67b5328475eb3d1f92f5"></a><!-- doxytag: member="keyset.c::ksHead" ref="ge7dbf3aef70e67b5328475eb3d1f92f5" args="(const KeySet *ks)" -->
418 <div class="memitem">
419 <div class="memproto">
420       <table class="memname">
421         <tr>
422           <td class="memname">Key* ksHead           </td>
423           <td>(</td>
424           <td class="paramtype">const KeySet *&nbsp;</td>
425           <td class="paramname"> <em>ks</em>          </td>
426           <td>&nbsp;)&nbsp;</td>
427           <td></td>
428         </tr>
429       </table>
430 </div>
431 <div class="memdoc">
432
433 <p>
434 Return the first key in the KeySet.<p>
435 The KeySets cursor will not be effected.<p>
436 If <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a>==ksHead() you know you are on the first key.<p>
437 <dl compact><dt><b>Parameters:</b></dt><dd>
438   <table border="0" cellspacing="2" cellpadding="0">
439     <tr><td valign="top"></td><td valign="top"><em>ks</em>&nbsp;</td><td>the keyset object to work with </td></tr>
440   </table>
441 </dl>
442 <dl class="return" compact><dt><b>Returns:</b></dt><dd>the first Key of a keyset <p>
443 0 on NULL pointer or empty keyset </dd></dl>
444 <dl class="see" compact><dt><b>See also:</b></dt><dd><a class="el" href="group__keyset.html#gdca442c4ab43cf532b15091d7711559e">ksTail()</a> for the last <a class="el" href="group__key.html" title="Key construction and initialization methods.">Key :: Basic Methods</a> <p>
445 <a class="el" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind()</a>, <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a> and <a class="el" href="group__keyset.html#g317321c9065b5a4b3e33fe1c399bcec9">ksNext()</a> for iterating over the <a class="el" href="group__keyset.html" title="Methods to manipulate KeySets.">KeySet :: Class Methods</a> </dd></dl>
446
447 </div>
448 </div><p>
449 <a class="anchor" name="ga34fc43a081e6b01e4120daa6c112004"></a><!-- doxytag: member="keyset.c::ksLookup" ref="ga34fc43a081e6b01e4120daa6c112004" args="(KeySet *ks, Key *key, option_t options)" -->
450 <div class="memitem">
451 <div class="memproto">
452       <table class="memname">
453         <tr>
454           <td class="memname">Key* ksLookup           </td>
455           <td>(</td>
456           <td class="paramtype">KeySet *&nbsp;</td>
457           <td class="paramname"> <em>ks</em>, </td>
458         </tr>
459         <tr>
460           <td class="paramkey"></td>
461           <td></td>
462           <td class="paramtype">Key *&nbsp;</td>
463           <td class="paramname"> <em>key</em>, </td>
464         </tr>
465         <tr>
466           <td class="paramkey"></td>
467           <td></td>
468           <td class="paramtype">option_t&nbsp;</td>
469           <td class="paramname"> <em>options</em></td><td>&nbsp;</td>
470         </tr>
471         <tr>
472           <td></td>
473           <td>)</td>
474           <td></td><td></td><td></td>
475         </tr>
476       </table>
477 </div>
478 <div class="memdoc">
479
480 <p>
481 Look for a Key contained in <code>ks</code> that matches the name of the <code>key</code>.<h2><a class="anchor" name="Introduction">
482 Introduction</a></h2>
483 <code><a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a></code> is designed to let you work with entirely pre-loaded KeySets, so instead of <a class="el" href="group__kdbhighlevel.html#ga62877888f0cad395898859395e6635f">kdbGetKey()</a>, key by key, the idea is to fully <a class="el" href="group__kdb.html#g37b44bda1b83bc0144916bf21a86c1b5">kdbGet()</a> for your application root key and process it all at once with <code><a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a></code>.<p>
484 This function is very efficient by using binary search. Together with <a class="el" href="group__kdb.html#g37b44bda1b83bc0144916bf21a86c1b5">kdbGet()</a> which can you load the whole configuration with only some communication to backends you can write very effective but short code for configuration.<h2><a class="anchor" name="Usage">
485 Usage</a></h2>
486 If found, <code>ks</code> internal cursor will be positioned in the matched key (also accessible by <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a>), and a pointer to the Key is returned. If not found, <code>ks</code> internal cursor will not move, and a NULL pointer is returned.<p>
487 Cascading is done if the first character is a /. This leads to ignoring the prefix like system/ and user/. <div class="fragment"><pre class="fragment">        <span class="keywordflow">if</span> (<a class="code" href="group__kdb.html#g37b44bda1b83bc0144916bf21a86c1b5">kdbGet</a>(handle, <span class="stringliteral">"user/myapp"</span>, myConfig, 0 ) == -1)
488                 ErrorHandler (<span class="stringliteral">"Could not get Keys"</span>);
489
490         <span class="keywordflow">if</span> (<a class="code" href="group__kdb.html#g37b44bda1b83bc0144916bf21a86c1b5">kdbGet</a>(handle, <span class="stringliteral">"system/myapp"</span>, myConfig, 0 ) == -1)
491                 ErrorHandler (<span class="stringliteral">"Could not get Keys"</span>);
492
493         <span class="keywordflow">if</span> ((myKey = <a class="code" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup</a>(myConfig, key, 0)) == NULL)
494                 ErrorHandler (<span class="stringliteral">"Could not Lookup Key"</span>);
495 </pre></div><p>
496 This is the way multi user Programs should get there configuration and search after the values. It is guaranteed that more namespaces can be added easily and that all values can be set by admin and user.<h3><a class="anchor" name="KDB_O_NOALL">
497 KDB_O_NOALL</a></h3>
498 When KDB_O_NOALL is set the keyset will be only searched from <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a> to <a class="el" href="group__keyset.html#gdca442c4ab43cf532b15091d7711559e">ksTail()</a>. You need to <a class="el" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind()</a> the keyset yourself. <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a> is always set properly after searching a key, so you can go on searching another key after the found key.<p>
499 When KDB_O_NOALL is not set the cursor will stay untouched and all keys are considered. A much more efficient binary search will be used then.<p>
500 So if you change keys, e.g. rename (<a class="el" href="group__keyname.html#g7699091610e7f3f43d2949514a4b35d9">keySetName()</a>) or remove (<a class="el" href="group__keymeta.html#g6e14e5f1de26e1318100631a149f2984">keyRemove()</a>) them make sure to sort the keyset with <a class="el" href="group__keyset.html#g023554d395ccf2319a3807b8b5d2530c">ksSort()</a>. When the keyset is dirty, see ksNeedSort() it will be sorted automatically when needed.<h3><a class="anchor" name="KDB_O_POP">
501 KDB_O_POP</a></h3>
502 When KDB_O_POP is set the key which was found will be <a class="el" href="group__keyset.html#ge42530b04defb772059de0600159cf69">ksPop()</a>ed. <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a> will not be changed, only iff <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a> is the searched key, then the keyset will be <a class="el" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind()</a>ed.<p>
503 <dl class="note" compact><dt><b>Note:</b></dt><dd>Note that <a class="el" href="group__keymeta.html#g6e14e5f1de26e1318100631a149f2984">keyRemove()</a> keys won't be found after the first time the keyset is resorted. Lookup automatically sorts the keyset, if needed, but it can't find it out when only keys are changed, not the keyset.<p>
504 Like in <a class="el" href="group__keyset.html#ge42530b04defb772059de0600159cf69">ksPop()</a> the popped key always needs to be <a class="el" href="group__key.html#g3df95bbc2494e3e6703ece5639be5bb1">keyDel()</a> afterwards, even if it is appended to another keyset.</dd></dl>
505 <dl class="warning" compact><dt><b>Warning:</b></dt><dd>All cursors on the keyset will be invalid iff you use KDB_O_POP, so don't use this if you rely on a cursor, see <a class="el" href="group__keyset.html#gffe507ab9281c322eb16c3e992075d29">ksGetCursor()</a>.</dd></dl>
506 <dl class="note" compact><dt><b>Note:</b></dt><dd>Never use <a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a> with KDB_O_POP and <a class="el" href="group__keyset.html#ga5a1d467a4d71041edce68ea7748ce45">ksAppendKey()</a> or <a class="el" href="group__keyset.html#g21eb9c3a14a604ee3a8bdc779232e7b7">ksAppend()</a> together in a loop. Otherwise <a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a> will need to resort the keyset every iteration and spend 99.96% of the time in <a class="el" href="group__keyset.html#g023554d395ccf2319a3807b8b5d2530c">ksSort()</a> (benchmarked with above 500k iterations).</dd></dl>
507 You can solve this problem by using KDB_O_NOALL, risking you have to iterate n^2 instead of n.<p>
508 The more elegant way is to separate the keyset you use for <a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a> and <a class="el" href="group__keyset.html#ga5a1d467a4d71041edce68ea7748ce45">ksAppendKey()</a>: <div class="fragment"><pre class="fragment"><span class="keywordtype">int</span> f(KeySet *iterator, KeySet *lookup)
509 {
510         KeySet *append = <a class="code" href="group__keyset.html#g671e1aaee3ae9dc13b4834a4ddbd2c3c">ksNew</a> (<a class="code" href="group__keyset.html#g7474ad6b0a0fa969dbdf267ba5770eee">ksGetSize</a>(lookup), KS_END);
511         Key *key;
512         Key *current;
513
514         <a class="code" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind</a>(iterator);
515         <span class="keywordflow">while</span> (current=<a class="code" href="group__keyset.html#g317321c9065b5a4b3e33fe1c399bcec9">ksNext</a>(iterator))
516         {
517                 key = <a class="code" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup</a> (lookup, current, KDB_O_POP);
518                 <span class="comment">// do something...</span>
519                 <a class="code" href="group__keyset.html#ga5a1d467a4d71041edce68ea7748ce45">ksAppendKey</a>(append, key); <span class="comment">// now append it to append, not lookup!</span>
520                 <a class="code" href="group__key.html#g3df95bbc2494e3e6703ece5639be5bb1">keyDel</a> (key); <span class="comment">// make sure to ALWAYS delete poped keys.</span>
521         }
522         <a class="code" href="group__keyset.html#g21eb9c3a14a604ee3a8bdc779232e7b7">ksAppend</a>(lookup, append);
523         <span class="comment">// now lookup needs to be sorted only once, append never</span>
524         <a class="code" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel</a> (append);
525 }
526 </pre></div><p>
527 <dl compact><dt><b>Parameters:</b></dt><dd>
528   <table border="0" cellspacing="2" cellpadding="0">
529     <tr><td valign="top"></td><td valign="top"><em>ks</em>&nbsp;</td><td>where to look for </td></tr>
530     <tr><td valign="top"></td><td valign="top"><em>key</em>&nbsp;</td><td>the key object you are looking for </td></tr>
531     <tr><td valign="top"></td><td valign="top"><em>options</em>&nbsp;</td><td>some <code>KDB_O_*</code> option bits:<ul>
532 <li><code>KDB_O_NOCASE</code> <br>
533  Lookup ignoring case.</li><li><code>KDB_O_WITHOWNER</code> <br>
534  Also consider correct owner.</li><li><code>KDB_O_NOALL</code> <br>
535  Only search from <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a> to end of keyset, see above text.</li><li><code>KDB_O_POP</code> <br>
536  Pop the key which was found.</li><li><code>KDB_O_SORT</code> <br>
537  Force sorting before searching, see <a class="el" href="group__keyset.html#g023554d395ccf2319a3807b8b5d2530c">ksSort()</a>. Together with KDB_O_NOALL the search will start from beginning. </li></ul>
538 </td></tr>
539   </table>
540 </dl>
541 <dl class="return" compact><dt><b>Returns:</b></dt><dd>pointer to the Key found, 0 otherwise <p>
542 0 on NULL pointers </dd></dl>
543 <dl class="see" compact><dt><b>See also:</b></dt><dd><a class="el" href="group__keyset.html#gd2e30fb6d4739d917c5abb2ac2f9c1a1">ksLookupByName()</a> to search by a name given by a string <p>
544 <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a>, <a class="el" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind()</a>, <a class="el" href="group__keyset.html#g317321c9065b5a4b3e33fe1c399bcec9">ksNext()</a> for iterating over a <a class="el" href="group__keyset.html" title="Methods to manipulate KeySets.">KeySet :: Class Methods</a> <p>
545 <a class="el" href="group__keyset.html#g023554d395ccf2319a3807b8b5d2530c">ksSort()</a> to understand how <a class="el" href="group__keyset.html" title="Methods to manipulate KeySets.">KeySet :: Class Methods</a> sort themself </dd></dl>
546
547 </div>
548 </div><p>
549 <a class="anchor" name="gd2e30fb6d4739d917c5abb2ac2f9c1a1"></a><!-- doxytag: member="keyset.c::ksLookupByName" ref="gd2e30fb6d4739d917c5abb2ac2f9c1a1" args="(KeySet *ks, const char *name, option_t options)" -->
550 <div class="memitem">
551 <div class="memproto">
552       <table class="memname">
553         <tr>
554           <td class="memname">Key* ksLookupByName           </td>
555           <td>(</td>
556           <td class="paramtype">KeySet *&nbsp;</td>
557           <td class="paramname"> <em>ks</em>, </td>
558         </tr>
559         <tr>
560           <td class="paramkey"></td>
561           <td></td>
562           <td class="paramtype">const char *&nbsp;</td>
563           <td class="paramname"> <em>name</em>, </td>
564         </tr>
565         <tr>
566           <td class="paramkey"></td>
567           <td></td>
568           <td class="paramtype">option_t&nbsp;</td>
569           <td class="paramname"> <em>options</em></td><td>&nbsp;</td>
570         </tr>
571         <tr>
572           <td></td>
573           <td>)</td>
574           <td></td><td></td><td></td>
575         </tr>
576       </table>
577 </div>
578 <div class="memdoc">
579
580 <p>
581 Look for a Key contained in <code>ks</code> that matches <code>name</code>.<p>
582 <code><a class="el" href="group__keyset.html#gd2e30fb6d4739d917c5abb2ac2f9c1a1">ksLookupByName()</a></code> is designed to let you work with entirely pre-loaded KeySets, so instead of <a class="el" href="group__kdbhighlevel.html#ga62877888f0cad395898859395e6635f">kdbGetKey()</a>, key by key, the idea is to fully <a class="el" href="group__kdbhighlevel.html#g3013d5768bbcf3c34652f489151940e2">kdbGetByName()</a> for your application root key and process it all at once with <code><a class="el" href="group__keyset.html#gd2e30fb6d4739d917c5abb2ac2f9c1a1">ksLookupByName()</a></code>.<p>
583 This function is very efficient by using binary search. Together with <a class="el" href="group__kdbhighlevel.html#g3013d5768bbcf3c34652f489151940e2">kdbGetByName()</a> which can you load the whole configuration with only some communication to backends you can write very effective but short code for configuration.<p>
584 If found, <code>ks</code> internal cursor will be positioned in the matched key (also accessible by <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a>), and a pointer to the Key is returned. If not found, <code>ks</code> internal cursor will not move, and a NULL pointer is returned.<h2><a class="anchor" name="cascading">
585 Cascading</a></h2>
586 Cascading is done if the first character is a /. This leads to ignoring the prefix like system/ and user/. <div class="fragment"><pre class="fragment">        <span class="keywordflow">if</span> (<a class="code" href="group__kdbhighlevel.html#g3013d5768bbcf3c34652f489151940e2">kdbGetByName</a>(handle, <span class="stringliteral">"/sw/myapp/current"</span>, myConfig, 0 ) == -1)
587                 ErrorHandler (<span class="stringliteral">"Could not get Keys"</span>);
588
589         <span class="keywordflow">if</span> ((myKey = <a class="code" href="group__keyset.html#gd2e30fb6d4739d917c5abb2ac2f9c1a1">ksLookupByName</a> (myConfig, <span class="stringliteral">"/myapp/current/key"</span>, 0)) == NULL)
590                 ErrorHandler (<span class="stringliteral">"Could not Lookup Key"</span>);
591 </pre></div><p>
592 This is the way multi user Programs should get there configuration and search after the values. It is guaranteed that more namespaces can be added easily and that all values can be set by admin and user.<h2><a class="anchor" name="fullsearch">
593 Full Search</a></h2>
594 When KDB_O_NOALL is set the keyset will be only searched from <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a> to <a class="el" href="group__keyset.html#gdca442c4ab43cf532b15091d7711559e">ksTail()</a>. You need to <a class="el" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind()</a> the keyset yourself. <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a> is always set properly after searching a key, so you can go on searching another key after the found key.<p>
595 When KDB_O_NOALL is not set the cursor will stay untouched and all keys are considered. A much more efficient binary search will be used then.<p>
596 <dl compact><dt><b>Parameters:</b></dt><dd>
597   <table border="0" cellspacing="2" cellpadding="0">
598     <tr><td valign="top"></td><td valign="top"><em>ks</em>&nbsp;</td><td>where to look for </td></tr>
599     <tr><td valign="top"></td><td valign="top"><em>name</em>&nbsp;</td><td>key name you are looking for </td></tr>
600     <tr><td valign="top"></td><td valign="top"><em>options</em>&nbsp;</td><td>some <code>KDB_O_*</code> option bits:<ul>
601 <li><code>KDB_O_NOCASE</code> <br>
602  Lookup ignoring case.</li><li><code>KDB_O_WITHOWNER</code> <br>
603  Also consider correct owner.</li><li><code>KDB_O_NOALL</code> <br>
604  Only search from <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a> to end of keyset, see above text.</li><li><code>KDB_O_POP</code> <br>
605  Pop the key which was found.</li><li><code>KDB_O_SORT</code> <br>
606  Force sorting before searching, see <a class="el" href="group__keyset.html#g023554d395ccf2319a3807b8b5d2530c">ksSort()</a>. Together with KDB_O_NOALL the search will start from beginning.</li></ul>
607 </td></tr>
608   </table>
609 </dl>
610 Currently no options supported. <dl class="return" compact><dt><b>Returns:</b></dt><dd>pointer to the Key found, 0 otherwise <p>
611 0 on NULL pointers </dd></dl>
612 <dl class="see" compact><dt><b>See also:</b></dt><dd>keyCompare() for very powerfull Key lookups in KeySets <p>
613 <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a>, <a class="el" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind()</a>, <a class="el" href="group__keyset.html#g317321c9065b5a4b3e33fe1c399bcec9">ksNext()</a> </dd></dl>
614
615 </div>
616 </div><p>
617 <a class="anchor" name="g671e1aaee3ae9dc13b4834a4ddbd2c3c"></a><!-- doxytag: member="keyset.c::ksNew" ref="g671e1aaee3ae9dc13b4834a4ddbd2c3c" args="(size_t alloc,...)" -->
618 <div class="memitem">
619 <div class="memproto">
620       <table class="memname">
621         <tr>
622           <td class="memname">KeySet* ksNew           </td>
623           <td>(</td>
624           <td class="paramtype">size_t&nbsp;</td>
625           <td class="paramname"> <em>alloc</em>, </td>
626         </tr>
627         <tr>
628           <td class="paramkey"></td>
629           <td></td>
630           <td class="paramtype">&nbsp;</td>
631           <td class="paramname"> <em>...</em></td><td>&nbsp;</td>
632         </tr>
633         <tr>
634           <td></td>
635           <td>)</td>
636           <td></td><td></td><td></td>
637         </tr>
638       </table>
639 </div>
640 <div class="memdoc">
641
642 <p>
643 Allocate, initialize and return a new KeySet object.<p>
644 Objects created with <a class="el" href="group__keyset.html#g671e1aaee3ae9dc13b4834a4ddbd2c3c">ksNew()</a> must be destroyed with <a class="el" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel()</a>.<p>
645 You can use a various long list of parameters to preload the keyset with a list of keys. Either your first and only parameter is 0 or your last parameter must be KEY_END.<p>
646 For most uses <div class="fragment"><pre class="fragment">KeySet *keys = <a class="code" href="group__keyset.html#g671e1aaee3ae9dc13b4834a4ddbd2c3c">ksNew</a>(0);
647 <span class="comment">// work with it</span>
648 <a class="code" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel</a> (keys);
649 </pre></div> goes ok, the alloc size will be 16, defined in kdbprivate.h. The alloc size will be doubled whenever size reaches alloc size, so it also performs out large keysets.<p>
650 But if you have any clue how large your keyset may be you should read the next statements.<p>
651 If you want a keyset with length 15 (because you know of your application that you normally need about 12 up to 14 keys), use: <div class="fragment"><pre class="fragment">KeySet * keys = <a class="code" href="group__keyset.html#g671e1aaee3ae9dc13b4834a4ddbd2c3c">ksNew</a> (15, KS_END);
652 <span class="comment">// work with it</span>
653 <a class="code" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel</a> (keys);
654 </pre></div><p>
655 If you start having 3 keys, and your application needs approximately 200-500 keys, you can use: <div class="fragment"><pre class="fragment">KeySet * config = <a class="code" href="group__keyset.html#g671e1aaee3ae9dc13b4834a4ddbd2c3c">ksNew</a> (500,
656         <a class="code" href="group__key.html#gf6893c038b3ebee90c73a9ea8356bebf">keyNew</a> (<span class="stringliteral">"user/sw/app/fixedConfiguration/key1"</span>, KEY_SWITCH_VALUE, <span class="stringliteral">"value1"</span>, 0),
657         <a class="code" href="group__key.html#gf6893c038b3ebee90c73a9ea8356bebf">keyNew</a> (<span class="stringliteral">"user/sw/app/fixedConfiguration/key2"</span>, KEY_SWITCH_VALUE, <span class="stringliteral">"value2"</span>, 0),
658         <a class="code" href="group__key.html#gf6893c038b3ebee90c73a9ea8356bebf">keyNew</a> (<span class="stringliteral">"user/sw/app/fixedConfiguration/key3"</span>, KEY_SWITCH_VALUE, <span class="stringliteral">"value3"</span>, 0),
659         KS_END); <span class="comment">// don't forget the KS_END at the end!</span>
660 <span class="comment">// work with it</span>
661 <a class="code" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel</a> (config);
662 </pre></div> Alloc size is 500, the size of the keyset will be 3 after ksNew. This means the keyset will reallocate when appending more than 497 keys.<p>
663 The main benefit of taking a list of variant length parameters is to be able to have one C-Statement for any possible KeySet.<p>
664 Due to ABI compatibility, the <code>KeySet</code> structure is only declared in kdb.h, and not defined. So you can only declare <code>pointers</code> to <code>KeySets</code> in your program. See <a href="http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html#AEN135">http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html#AEN135</a><p>
665 <dl class="see" compact><dt><b>See also:</b></dt><dd><a class="el" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel()</a> to free the <a class="el" href="group__keyset.html" title="Methods to manipulate KeySets.">KeySet :: Class Methods</a> afterwards <p>
666 <a class="el" href="group__keyset.html#gc59e4b328245463f1451f68d5106151c">ksDup()</a> to duplicate an existing <a class="el" href="group__keyset.html" title="Methods to manipulate KeySets.">KeySet :: Class Methods</a> </dd></dl>
667 <dl compact><dt><b>Parameters:</b></dt><dd>
668   <table border="0" cellspacing="2" cellpadding="0">
669     <tr><td valign="top"></td><td valign="top"><em>alloc</em>&nbsp;</td><td>gives a hint for the size how many Keys may be stored initially </td></tr>
670   </table>
671 </dl>
672 <dl class="return" compact><dt><b>Returns:</b></dt><dd>a ready to use KeySet object <p>
673 0 on memory error </dd></dl>
674
675 </div>
676 </div><p>
677 <a class="anchor" name="g317321c9065b5a4b3e33fe1c399bcec9"></a><!-- doxytag: member="keyset.c::ksNext" ref="g317321c9065b5a4b3e33fe1c399bcec9" args="(KeySet *ks)" -->
678 <div class="memitem">
679 <div class="memproto">
680       <table class="memname">
681         <tr>
682           <td class="memname">Key* ksNext           </td>
683           <td>(</td>
684           <td class="paramtype">KeySet *&nbsp;</td>
685           <td class="paramname"> <em>ks</em>          </td>
686           <td>&nbsp;)&nbsp;</td>
687           <td></td>
688         </tr>
689       </table>
690 </div>
691 <div class="memdoc">
692
693 <p>
694 Returns the next Key in a KeySet.<p>
695 KeySets have an internal cursor that can be reset with <a class="el" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind()</a>. Every time <a class="el" href="group__keyset.html#g317321c9065b5a4b3e33fe1c399bcec9">ksNext()</a> is called the cursor is incremented and the new current Key is returned.<p>
696 You'll get a NULL pointer if the key after the end of the KeySet was reached. It will set the cursor to the beginning of the KeySet and the next time the first key is returned.<p>
697 The <code>ks</code> internal cursor will be changed, so it is not const.<p>
698 <dl class="note" compact><dt><b>Note:</b></dt><dd>You must not delete or change the key, use <a class="el" href="group__keyset.html#ge42530b04defb772059de0600159cf69">ksPop()</a> if you want to delete it.</dd></dl>
699 <dl compact><dt><b>Parameters:</b></dt><dd>
700   <table border="0" cellspacing="2" cellpadding="0">
701     <tr><td valign="top"></td><td valign="top"><em>ks</em>&nbsp;</td><td>the keyset object to work with </td></tr>
702   </table>
703 </dl>
704 <dl class="return" compact><dt><b>Returns:</b></dt><dd>the new current Key <p>
705 0 when the end is reached <p>
706 0 on NULL pointer </dd></dl>
707 <dl class="see" compact><dt><b>See also:</b></dt><dd><a class="el" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind()</a>, <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a> </dd></dl>
708
709 </div>
710 </div><p>
711 <a class="anchor" name="ge42530b04defb772059de0600159cf69"></a><!-- doxytag: member="keyset.c::ksPop" ref="ge42530b04defb772059de0600159cf69" args="(KeySet *ks)" -->
712 <div class="memitem">
713 <div class="memproto">
714       <table class="memname">
715         <tr>
716           <td class="memname">Key* ksPop           </td>
717           <td>(</td>
718           <td class="paramtype">KeySet *&nbsp;</td>
719           <td class="paramname"> <em>ks</em>          </td>
720           <td>&nbsp;)&nbsp;</td>
721           <td></td>
722         </tr>
723       </table>
724 </div>
725 <div class="memdoc">
726
727 <p>
728 Remove and return the last key of <code>ks</code>.<p>
729 The reference counter will be decremented by one.<p>
730 The KeySets cursor will not be effected if it did not point to the popped key.<p>
731 <dl class="note" compact><dt><b>Note:</b></dt><dd>You need to <a class="el" href="group__key.html#g3df95bbc2494e3e6703ece5639be5bb1">keyDel()</a> the key afterwards, if you don't append it to another keyset. It has the same semantics like a key allocated with <a class="el" href="group__key.html#gf6893c038b3ebee90c73a9ea8356bebf">keyNew()</a> or <a class="el" href="group__key.html#ge6ec6a60cc4b8c1463fa08623d056ce3">keyDup()</a>.</dd></dl>
732 <div class="fragment"><pre class="fragment">ks1=<a class="code" href="group__keyset.html#g671e1aaee3ae9dc13b4834a4ddbd2c3c">ksNew</a>(0);
733 ks2=<a class="code" href="group__keyset.html#g671e1aaee3ae9dc13b4834a4ddbd2c3c">ksNew</a>(0);
734
735 k1=<a class="code" href="group__key.html#gf6893c038b3ebee90c73a9ea8356bebf">keyNew</a>(0); <span class="comment">// ref counter 0</span>
736 <a class="code" href="group__keyset.html#ga5a1d467a4d71041edce68ea7748ce45">ksAppendKey</a>(ks1, k1); <span class="comment">// ref counter 1</span>
737 <a class="code" href="group__keyset.html#ga5a1d467a4d71041edce68ea7748ce45">ksAppendKey</a>(ks2, k1); <span class="comment">// ref counter 2</span>
738
739 k1=<a class="code" href="group__keyset.html#ge42530b04defb772059de0600159cf69">ksPop</a> (ks1); <span class="comment">// ref counter 1</span>
740 k1=<a class="code" href="group__keyset.html#ge42530b04defb772059de0600159cf69">ksPop</a> (ks2); <span class="comment">// ref counter 0, like after keyNew()</span>
741
742 <a class="code" href="group__keyset.html#ga5a1d467a4d71041edce68ea7748ce45">ksAppendKey</a>(ks1, k1); <span class="comment">// ref counter 1</span>
743
744 <a class="code" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel</a> (ks1); <span class="comment">// key is deleted too</span>
745 <a class="code" href="group__keyset.html#g27e5c16473b02a422238c8d970db7ac8">ksDel</a> (ks2);
746  *
747 </pre></div><p>
748 <dl class="return" compact><dt><b>Returns:</b></dt><dd>the last key of <code>ks</code> <p>
749 NULL if <code>ks</code> is empty or on NULL pointer </dd></dl>
750 <dl compact><dt><b>Parameters:</b></dt><dd>
751   <table border="0" cellspacing="2" cellpadding="0">
752     <tr><td valign="top"></td><td valign="top"><em>ks</em>&nbsp;</td><td>KeySet to work with </td></tr>
753   </table>
754 </dl>
755 <dl class="see" compact><dt><b>See also:</b></dt><dd><a class="el" href="group__keyset.html#ga5a1d467a4d71041edce68ea7748ce45">ksAppendKey()</a>, <a class="el" href="group__keyset.html#g21eb9c3a14a604ee3a8bdc779232e7b7">ksAppend()</a> <p>
756 commandList() for an example </dd></dl>
757
758 </div>
759 </div><p>
760 <a class="anchor" name="gbe793ff51f1728e3429c84a8a9086b70"></a><!-- doxytag: member="keyset.c::ksRewind" ref="gbe793ff51f1728e3429c84a8a9086b70" args="(KeySet *ks)" -->
761 <div class="memitem">
762 <div class="memproto">
763       <table class="memname">
764         <tr>
765           <td class="memname">int ksRewind           </td>
766           <td>(</td>
767           <td class="paramtype">KeySet *&nbsp;</td>
768           <td class="paramname"> <em>ks</em>          </td>
769           <td>&nbsp;)&nbsp;</td>
770           <td></td>
771         </tr>
772       </table>
773 </div>
774 <div class="memdoc">
775
776 <p>
777 Rewinds the KeySet internal cursor.<p>
778 Use it to set the cursor to the beginning of the KeySet. <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a> will then always return NULL afterwards. So you want to <a class="el" href="group__keyset.html#g317321c9065b5a4b3e33fe1c399bcec9">ksNext()</a> first.<p>
779 <div class="fragment"><pre class="fragment"><a class="code" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind</a> (ks);
780 <span class="keywordflow">while</span> ((key = keyNext (ks))!=0) {}
781 </pre></div><p>
782 <dl compact><dt><b>Parameters:</b></dt><dd>
783   <table border="0" cellspacing="2" cellpadding="0">
784     <tr><td valign="top"></td><td valign="top"><em>ks</em>&nbsp;</td><td>the keyset object to work with </td></tr>
785   </table>
786 </dl>
787 <dl class="return" compact><dt><b>Returns:</b></dt><dd>0 on success <p>
788 -1 on NULL pointer </dd></dl>
789 <dl class="see" compact><dt><b>See also:</b></dt><dd><a class="el" href="group__keyset.html#g317321c9065b5a4b3e33fe1c399bcec9">ksNext()</a>, <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a> </dd></dl>
790
791 </div>
792 </div><p>
793 <a class="anchor" name="gd94c9ffaa3e8034564c0712fd407c345"></a><!-- doxytag: member="keyset.c::ksSetCursor" ref="gd94c9ffaa3e8034564c0712fd407c345" args="(KeySet *ks, cursor_t cursor)" -->
794 <div class="memitem">
795 <div class="memproto">
796       <table class="memname">
797         <tr>
798           <td class="memname">int ksSetCursor           </td>
799           <td>(</td>
800           <td class="paramtype">KeySet *&nbsp;</td>
801           <td class="paramname"> <em>ks</em>, </td>
802         </tr>
803         <tr>
804           <td class="paramkey"></td>
805           <td></td>
806           <td class="paramtype">cursor_t&nbsp;</td>
807           <td class="paramname"> <em>cursor</em></td><td>&nbsp;</td>
808         </tr>
809         <tr>
810           <td></td>
811           <td>)</td>
812           <td></td><td></td><td></td>
813         </tr>
814       </table>
815 </div>
816 <div class="memdoc">
817
818 <p>
819 Set the KeySet internal cursor.<p>
820 Use it to set the cursor to a stored position. <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a> will then be the position which you got with.<p>
821 <dl class="warning" compact><dt><b>Warning:</b></dt><dd>Cursors may get invalid when the key was <a class="el" href="group__keyset.html#ge42530b04defb772059de0600159cf69">ksPop()</a>ed or <a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a> was used together with KDB_O_POP.</dd></dl>
822 <div class="fragment"><pre class="fragment">cursor_t cursor;
823 ..
824 <span class="comment">// key now in any position here</span>
825 cursor = <a class="code" href="group__keyset.html#gffe507ab9281c322eb16c3e992075d29">ksGetCursor</a> (ks);
826 <span class="keywordflow">while</span> ((key = keyNext (ks))!=0) {}
827 <a class="code" href="group__keyset.html#gd94c9ffaa3e8034564c0712fd407c345">ksSetCursor</a> (ks, cursor); <span class="comment">// reset state</span>
828 <a class="code" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent</a>(ks); <span class="comment">// in same position as before</span>
829 </pre></div><p>
830 An invalid cursor will set the keyset to its beginning like <a class="el" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind()</a>. When you set an invalid cursor <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a> is 0 and <a class="el" href="group__keyset.html#g317321c9065b5a4b3e33fe1c399bcec9">ksNext()</a> == <a class="el" href="group__keyset.html#ge7dbf3aef70e67b5328475eb3d1f92f5">ksHead()</a>.<p>
831 <dl compact><dt><b>Parameters:</b></dt><dd>
832   <table border="0" cellspacing="2" cellpadding="0">
833     <tr><td valign="top"></td><td valign="top"><em>cursor</em>&nbsp;</td><td>the cursor to use </td></tr>
834     <tr><td valign="top"></td><td valign="top"><em>ks</em>&nbsp;</td><td>the keyset object to work with </td></tr>
835   </table>
836 </dl>
837 <dl class="return" compact><dt><b>Returns:</b></dt><dd>0 when the keyset is <a class="el" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind()</a>ed <p>
838 1 otherwise <p>
839 -1 on NULL pointer </dd></dl>
840 <dl class="see" compact><dt><b>See also:</b></dt><dd><a class="el" href="group__keyset.html#g317321c9065b5a4b3e33fe1c399bcec9">ksNext()</a>, <a class="el" href="group__keyset.html#gffe507ab9281c322eb16c3e992075d29">ksGetCursor()</a> </dd></dl>
841
842 </div>
843 </div><p>
844 <a class="anchor" name="g023554d395ccf2319a3807b8b5d2530c"></a><!-- doxytag: member="keyset.c::ksSort" ref="g023554d395ccf2319a3807b8b5d2530c" args="(KeySet *ks)" -->
845 <div class="memitem">
846 <div class="memproto">
847       <table class="memname">
848         <tr>
849           <td class="memname">void ksSort           </td>
850           <td>(</td>
851           <td class="paramtype">KeySet *&nbsp;</td>
852           <td class="paramname"> <em>ks</em>          </td>
853           <td>&nbsp;)&nbsp;</td>
854           <td></td>
855         </tr>
856       </table>
857 </div>
858 <div class="memdoc">
859
860 <p>
861 Sorts a KeySet alphabetically by Key name.<p>
862 You need <a class="el" href="group__keyset.html#g023554d395ccf2319a3807b8b5d2530c">ksSort()</a> only in few cases directly.<h2><a class="anchor" name="sortlookup">
863 Don't need to sort before using ksLookup</a></h2>
864 You don't need it if you just just <a class="el" href="group__kdb.html#g37b44bda1b83bc0144916bf21a86c1b5">kdbGet()</a> and subsequent <a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a>. <div class="fragment"><pre class="fragment">KeySet *ks = <a class="code" href="group__keyset.html#g671e1aaee3ae9dc13b4834a4ddbd2c3c">ksNew</a>(0);
865 <a class="code" href="group__kdb.html#g37b44bda1b83bc0144916bf21a86c1b5">kdbGet</a>(h, ks, k, 0);
866 <span class="comment">// ksPop(), ksAppend() and ksAppendKey() allowed here</span>
867 <a class="code" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup</a>(ks, s, 0); <span class="comment">// you dont need to sort ks</span>
868 </pre></div><p>
869 This is because the KeySet tracks if it needs to be sorted and <a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a> will sort when needed.<h2><a class="anchor" name="sortiterate">
870 Sort when iterating</a></h2>
871 Before you iterate over a keyset you have to sort it, if you need it in a sorted way.<p>
872 To achieve that you can pass option_t::KDB_O_SORT to <a class="el" href="group__kdb.html#g37b44bda1b83bc0144916bf21a86c1b5">kdbGet()</a> and <a class="el" href="group__kdb.html#g953cf29721e6000c2516cd6b5d36f571">kdbSet()</a>. Then you will receive a already sorted keyset over which you can iterate. <div class="fragment"><pre class="fragment">KeySet *ks = <a class="code" href="group__keyset.html#g671e1aaee3ae9dc13b4834a4ddbd2c3c">ksNew</a>(0);
873 <a class="code" href="group__kdb.html#g37b44bda1b83bc0144916bf21a86c1b5">kdbGet</a>(h, ks, k, KDB_O_SORT);
874 <span class="comment">// no changes to keyset allowed</span>
875 <a class="code" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind</a>(ks);
876 <span class="comment">// now you can iterate over a sorted keyset</span>
877 </pre></div><p>
878 Its of course also possible to use <a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a> once, because it will sort the keyset too.<h2><a class="anchor" name="sortkey">
879 Sort when changing key</a></h2>
880 <dl class="warning" compact><dt><b>Warning:</b></dt><dd>You should not use <a class="el" href="group__keyname.html#g7699091610e7f3f43d2949514a4b35d9">keySetName()</a> or <a class="el" href="group__keymeta.html#g6e14e5f1de26e1318100631a149f2984">keyRemove()</a> when a key belongs to a keyset. When you are doing this, you always need to <code>manually</code> sort <code>all</code> keysets where the key was before using <a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a> (otherwise <a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a> won't find that keys), <a class="el" href="group__kdb.html#g37b44bda1b83bc0144916bf21a86c1b5">kdbGet()</a> or <a class="el" href="group__kdb.html#g953cf29721e6000c2516cd6b5d36f571">kdbSet()</a> methods.</dd></dl>
881 When you change a key's name or its remove status the order which was previously correctly is then wrong. The keyset does not recognize this, so the programmer has to take care that <a class="el" href="group__keyset.html#g023554d395ccf2319a3807b8b5d2530c">ksSort()</a> is called before any operation which needs a sorted keyset (which are all <a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a>, all <a class="el" href="group__kdb.html#g37b44bda1b83bc0144916bf21a86c1b5">kdbGet()</a> and all <a class="el" href="group__kdb.html#g953cf29721e6000c2516cd6b5d36f571">kdbSet()</a> functions).<p>
882 <dl class="note" compact><dt><b>Note:</b></dt><dd>You can remember that easily that all functions which get options require one of the following:<ul>
883 <li>that you did not manipulate a keys name or a remove status</li><li>that you pass KDB_O_SORT when you know that you manipulated at least one key</li><li>that you <a class="el" href="group__keyset.html#g023554d395ccf2319a3807b8b5d2530c">ksSort()</a> yourself after manipulating keys</li></ul>
884 </dd></dl>
885 <h2><a class="anchor" name="dirty">
886 Dirty KeySet</a></h2>
887 When you use <a class="el" href="group__keyset.html#g21eb9c3a14a604ee3a8bdc779232e7b7">ksAppend()</a>, <a class="el" href="group__keyset.html#ga5a1d467a4d71041edce68ea7748ce45">ksAppendKey()</a>, <a class="el" href="group__keyset.html#ge42530b04defb772059de0600159cf69">ksPop()</a> the keyset is dirty afterwards, which means that it needs to be sorted. This is done automatically using a <a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a> method and in ksGet() or ksSet() (All methods which accept options).<p>
888 It won't be done if you just iterate over the keyset, so you might use a <a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a> or <a class="el" href="group__keyset.html#g023554d395ccf2319a3807b8b5d2530c">ksSort()</a> first. <a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a> will be more efficient in that case, because it will only sort when needed. Don't pass KDB_O_NOALL (it will deactivate the sorting feature), see <a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a> for more information.<p>
889 <dl compact><dt><b>Parameters:</b></dt><dd>
890   <table border="0" cellspacing="2" cellpadding="0">
891     <tr><td valign="top"></td><td valign="top"><em>ks</em>&nbsp;</td><td>KeySet to be sorted </td></tr>
892   </table>
893 </dl>
894 <dl class="see" compact><dt><b>See also:</b></dt><dd><a class="el" href="group__kdb.html#g37b44bda1b83bc0144916bf21a86c1b5">kdbGet()</a>, <a class="el" href="group__kdb.html#g953cf29721e6000c2516cd6b5d36f571">kdbSet()</a>, <a class="el" href="group__keyset.html#ga34fc43a081e6b01e4120daa6c112004">ksLookup()</a> for some functions which may need sorting before they are called. (All functions which take options as arguments) <p>
895 <a class="el" href="group__keyname.html#g7699091610e7f3f43d2949514a4b35d9">keySetName()</a>, <a class="el" href="group__keyname.html#g6e804bd453f98c28b0ff51430d1df407">keySetBaseName()</a>, <a class="el" href="group__keyname.html#ga942091fc4bd5c2699e49ddc50829524">keyAddBaseName()</a> and <a class="el" href="group__keymeta.html#g6e14e5f1de26e1318100631a149f2984">keyRemove()</a> for all methods which change the sorting state where the <a class="el" href="group__keyset.html" title="Methods to manipulate KeySets.">KeySet :: Class Methods</a> can't track the change. <p>
896 <a class="el" href="group__keyset.html#g21eb9c3a14a604ee3a8bdc779232e7b7">ksAppend()</a>, <a class="el" href="group__keyset.html#ga5a1d467a4d71041edce68ea7748ce45">ksAppendKey()</a>, <a class="el" href="group__keyset.html#ge42530b04defb772059de0600159cf69">ksPop()</a> for all methods which make a <a class="el" href="group__keyset.html" title="Methods to manipulate KeySets.">KeySet :: Class Methods</a> dirty. </dd></dl>
897
898 </div>
899 </div><p>
900 <a class="anchor" name="gdca442c4ab43cf532b15091d7711559e"></a><!-- doxytag: member="keyset.c::ksTail" ref="gdca442c4ab43cf532b15091d7711559e" args="(const KeySet *ks)" -->
901 <div class="memitem">
902 <div class="memproto">
903       <table class="memname">
904         <tr>
905           <td class="memname">Key* ksTail           </td>
906           <td>(</td>
907           <td class="paramtype">const KeySet *&nbsp;</td>
908           <td class="paramname"> <em>ks</em>          </td>
909           <td>&nbsp;)&nbsp;</td>
910           <td></td>
911         </tr>
912       </table>
913 </div>
914 <div class="memdoc">
915
916 <p>
917 Return the last key in the KeySet.<p>
918 The KeySets cursor will not be effected.<p>
919 If <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a>==ksTail() you know you are on the last key. <a class="el" href="group__keyset.html#g317321c9065b5a4b3e33fe1c399bcec9">ksNext()</a> will return a NULL pointer afterwards.<p>
920 <dl compact><dt><b>Parameters:</b></dt><dd>
921   <table border="0" cellspacing="2" cellpadding="0">
922     <tr><td valign="top"></td><td valign="top"><em>ks</em>&nbsp;</td><td>the keyset object to work with </td></tr>
923   </table>
924 </dl>
925 <dl class="return" compact><dt><b>Returns:</b></dt><dd>the last Key of a keyset <p>
926 0 on NULL pointer or empty keyset </dd></dl>
927 <dl class="see" compact><dt><b>See also:</b></dt><dd><a class="el" href="group__keyset.html#ge7dbf3aef70e67b5328475eb3d1f92f5">ksHead()</a> for the first <a class="el" href="group__key.html" title="Key construction and initialization methods.">Key :: Basic Methods</a> <p>
928 <a class="el" href="group__keyset.html#gbe793ff51f1728e3429c84a8a9086b70">ksRewind()</a>, <a class="el" href="group__keyset.html#g4287b9416912c5f2ab9c195cb74fb094">ksCurrent()</a> and <a class="el" href="group__keyset.html#g317321c9065b5a4b3e33fe1c399bcec9">ksNext()</a> for iterating over the <a class="el" href="group__keyset.html" title="Methods to manipulate KeySets.">KeySet :: Class Methods</a> </dd></dl>
929
930 </div>
931 </div><p>
932 </div>
933 <hr size="1"><address style="text-align: right;"><small>Generated on Tue Jun 30 14:43:54 2009 for Elektra Projekt by&nbsp;
934 <a href="http://www.doxygen.org/index.html">
935 <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.6 </small></address>
936 </body>
937 </html>