.TH "kdb::KeySet" 3elektra "Sun May 29 2016" "Version 0.8.14" "Elektra" \" -*- nroff -*- .ad l .nh .SH NAME kdb::KeySet \- A keyset holds together a set of keys\&. .SH SYNOPSIS .br .PP .PP \fC#include \fP .SS "Public Member Functions" .in +1c .ti -1c .RI "\fBKeySet\fP ()" .br .RI "\fICreates a new empty keyset with no keys\&. \fP" .ti -1c .RI "\fBKeySet\fP (ckdb::KeySet *k)" .br .RI "\fITakes ownership of keyset! \fP" .ti -1c .RI "\fBKeySet\fP (const \fBKeySet\fP &other)" .br .RI "\fIDuplicate a keyset\&. \fP" .ti -1c .RI "\fBKeySet\fP (size_t alloc,\&.\&.\&.)" .br .RI "\fICreate a new keyset\&. \fP" .ti -1c .RI "\fBKeySet\fP (\fBVa\fP va, size_t alloc, va_list ap)" .br .RI "\fICreate a new keyset\&. \fP" .ti -1c .RI "\fB~KeySet\fP ()" .br .RI "\fIDeconstruct a keyset\&. \fP" .ti -1c .RI "ckdb::KeySet * \fBrelease\fP ()" .br .RI "\fIIf you don't want destruction of keyset at the end you can release the pointer\&. \fP" .ti -1c .RI "ckdb::KeySet * \fBgetKeySet\fP () const " .br .RI "\fIPasses out the raw keyset pointer\&. \fP" .ti -1c .RI "void \fBsetKeySet\fP (ckdb::KeySet *k)" .br .RI "\fITake ownership of passed keyset\&. \fP" .ti -1c .RI "\fBKeySet\fP & \fBoperator=\fP (\fBKeySet\fP const &other)" .br .RI "\fIDuplicate a keyset\&. \fP" .ti -1c .RI "ssize_t \fBsize\fP () const " .br .RI "\fIThe size of the keyset\&. \fP" .ti -1c .RI "ckdb::KeySet * \fBdup\fP () const " .br .RI "\fIDuplicate a keyset\&. \fP" .ti -1c .RI "void \fBcopy\fP (const \fBKeySet\fP &other)" .br .RI "\fICopy a keyset\&. \fP" .ti -1c .RI "void \fBclear\fP ()" .br .RI "\fIClear the keyset\&. \fP" .ti -1c .RI "ssize_t \fBappend\fP (const \fBKey\fP &toAppend)" .br .RI "\fIappend a key \fP" .ti -1c .RI "ssize_t \fBappend\fP (const \fBKeySet\fP &toAppend)" .br .RI "\fIappend a keyset \fP" .ti -1c .RI "\fBKey\fP \fBhead\fP () const " .br .RI "\fIReturn the first key in the \fBKeySet\fP\&. \fP" .ti -1c .RI "\fBKey\fP \fBtail\fP () const " .br .RI "\fIReturn the last key in the \fBKeySet\fP\&. \fP" .ti -1c .RI "void \fBrewind\fP () const " .br .RI "\fIRewinds the \fBKeySet\fP internal cursor\&. \fP" .ti -1c .RI "\fBKey\fP \fBnext\fP () const " .br .RI "\fIReturns the next \fBKey\fP in a \fBKeySet\fP\&. \fP" .ti -1c .RI "\fBKey\fP \fBcurrent\fP () const " .br .RI "\fIReturn the current \fBKey\fP\&. \fP" .ti -1c .RI "void \fBsetCursor\fP (cursor_t cursor) const " .br .RI "\fISet the \fBKeySet\fP internal cursor\&. \fP" .ti -1c .RI "cursor_t \fBgetCursor\fP () const " .br .RI "\fIGet the \fBKeySet\fP internal cursor\&. \fP" .ti -1c .RI "\fBKey\fP \fBpop\fP ()" .br .RI "\fIRemove and return the last key of \fCks\fP\&. \fP" .ti -1c .RI "\fBKeySet\fP \fBcut\fP (\fBKey\fP k)" .br .RI "\fICuts out a keyset at the cutpoint\&. \fP" .ti -1c .RI "\fBKey\fP \fBlookup\fP (const \fBKey\fP &k, const \fBoption_t\fP options=\fBKDB_O_NONE\fP) const " .br .RI "\fILook for a \fBKey\fP contained in \fCks\fP that matches the name of the \fCkey\fP\&. \fP" .ti -1c .RI "\fBKey\fP \fBlookup\fP (std::string const &name, const \fBoption_t\fP options=\fBKDB_O_NONE\fP) const " .br .RI "\fILookup a key by name\&. \fP" .ti -1c .RI "\fBKey\fP \fBat\fP (cursor_t pos) const " .br .RI "\fILookup a key by index\&. \fP" .in -1c .SH "Detailed Description" .PP A keyset holds together a set of keys\&. Methods to manipulate KeySets\&. A \fBKeySet\fP is a set of keys\&. .PP Most important properties of a \fBKeySet\fP: .PP .IP "\(bu" 2 Allows us to iterate over all keys (in any depth) .IP "\(bu" 2 Iteration is always sorted .IP "\(bu" 2 Fast key lookup .IP "\(bu" 2 A \fBKey\fP may be shared among many KeySets\&. .PP .PP The most important methods of \fBKeySet\fP: .PP .IP "\(bu" 2 With \fBksNew()\fP you can create a new \fBKeySet\fP\&. .IP "\(bu" 2 You can add keys with \fBksAppendKey()\fP\&. .IP "\(bu" 2 Using \fBksAppend()\fP you can append a whole keyset\&. .IP "\(bu" 2 Using \fBksLookup()\fP you can lookup a key\&. .IP "\(bu" 2 \fBksGetSize()\fP tells you the current size\&. .PP .PP \fBNote:\fP .RS 4 Because the key is not copied, also the pointer to the current metadata \fBkeyNextMeta()\fP will be shared\&. .RE .PP With \fBksRewind()\fP and \fBksNext()\fP you can iterate through the keyset\&. Be assured that you will get every key of the set in a stable order (parents before children)\&. .PP KeySets have an \fBinternal cursor \fP\&. Methods should avoid to change this cursor, unless they want to communicate something with it\&. The internal cursor is used: .PP .IP "\(bu" 2 in \fBksLookup()\fP: points to the found key .IP "\(bu" 2 in \fBkdbSet()\fP: points to the key which caused an error .PP .PP \fBKeySet\fP is the most important data structure in 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 and it can be used in plugins to manipulate or check configuration\&. .PP With \fBksLookupByName()\fP it is possible to fetch easily specific keys out of the list of keys\&. .PP You can easily create and iterate keys: .PP .nf #include // create a new keyset with 3 keys // with a hint that about 20 keys will be inside KeySet *myConfig = ksNew(20, keyNew ("user/name1", 0), keyNew ("user/name2", 0), keyNew ("user/name3", 0), KS_END); // append a key in the keyset ksAppendKey(myConfig, keyNew("user/name4", 0)); Key *current; ksRewind(myConfig); while ((current=ksNext(myConfig))!=0) { printf("Key name is %s\&.\n", keyName (current)); } ksDel (myConfig); // delete keyset and all keys appended .fi .PP .PP \fBInvariant:\fP .RS 4 always holds an underlying elektra keyset\&. .RE .PP \fBNote:\fP .RS 4 that the cursor is mutable, so it might be changed even in const functions as described\&. .RE .PP .SH "Constructor & Destructor Documentation" .PP .SS "kdb::KeySet::KeySet ()\fC [inline]\fP" .PP Creates a new empty keyset with no keys\&. Allocate, initialize and return a new \fBKeySet\fP object\&. Objects created with \fBksNew()\fP must be destroyed with \fBksDel()\fP\&. .PP 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\&. .PP So, terminate with ksNew(0, KS_END) or ksNew(20, \&.\&.\&., KS_END) .PP For most uses .PP .nf KeySet *keys = ksNew(0, KS_END); // work with it ksDel (keys); .fi .PP 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\&. .PP But if you have any clue how large your keyset may be you should read the next statements\&. .PP If you want a keyset with length 15 (because you know of your application that you normally need about 12 up to 15 keys), use: .PP .nf KeySet * keys = ksNew (15, keyNew ("user/sw/app/fixedConfiguration/key01", KEY_SWITCH_VALUE, "value01", 0), keyNew ("user/sw/app/fixedConfiguration/key02", KEY_SWITCH_VALUE, "value02", 0), keyNew ("user/sw/app/fixedConfiguration/key03", KEY_SWITCH_VALUE, "value03", 0), // \&.\&.\&. keyNew ("user/sw/app/fixedConfiguration/key15", KEY_SWITCH_VALUE, "value15", 0), KS_END); // work with it ksDel (keys); .fi .PP .PP If you start having 3 keys, and your application needs approximately 200-500 keys, you can use: .PP .nf KeySet * config = ksNew (500, keyNew ("user/sw/app/fixedConfiguration/key1", KEY_SWITCH_VALUE, "value1", 0), keyNew ("user/sw/app/fixedConfiguration/key2", KEY_SWITCH_VALUE, "value2", 0), keyNew ("user/sw/app/fixedConfiguration/key3", KEY_SWITCH_VALUE, "value3", 0), KS_END); // don't forget the KS_END at the end! // work with it ksDel (config); .fi .PP 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\&. .PP The main benefit of taking a list of variant length parameters is to be able to have one C-Statement for any possible \fBKeySet\fP\&. .PP \fBPostcondition:\fP .RS 4 the keyset is rewinded properly .RE .PP \fBSee also:\fP .RS 4 \fBksDel()\fP to free the \fBKeySet\fP afterwards .PP \fBksDup()\fP to duplicate an existing \fBKeySet\fP .RE .PP \fBParameters:\fP .RS 4 \fIalloc\fP gives a hint for the size how many Keys may be stored initially .RE .PP \fBReturns:\fP .RS 4 a ready to use \fBKeySet\fP object .RE .PP \fBReturn values:\fP .RS 4 \fI0\fP on memory error .RE .PP .SS "kdb::KeySet::KeySet (ckdb::KeySet * k)\fC [inline]\fP" .PP Takes ownership of keyset! Keyset will be destroyed at destructor you cant continue to use keyset afterwards! .PP Use \fBKeySet::release()\fP to avoid destruction\&. .PP \fBParameters:\fP .RS 4 \fIk\fP the keyset to take the ownership from .RE .PP \fBSee also:\fP .RS 4 \fBrelease()\fP .PP \fBsetKeySet()\fP .RE .PP .SS "kdb::KeySet::KeySet (const \fBKeySet\fP & other)\fC [inline]\fP" .PP Duplicate a keyset\&. This keyset will be a duplicate of the other afterwards\&. .PP \fBNote:\fP .RS 4 that they still reference to the same Keys, so if you change key values also the keys in the original keyset will be changed\&. .RE .PP So it is shallow copy, to create a deep copy you have to \fBdup()\fP every key (it still won't copy meta data, but they are COW): .PP .nf kdb::KeySet ksDeepCopy(kdb::KeySet orig) { kdb::KeySet deepCopy; orig\&.rewind(); while(orig\&.next()) { deepCopy\&.append(orig\&.current()\&.dup()); } return deepCopy; } .fi .PP .PP \fBSee also:\fP .RS 4 \fBdup\fP .RE .PP .SS "kdb::KeySet::KeySet (size_t alloc, \&.\&.\&.)\fC [inline]\fP, \fC [explicit]\fP" .PP Create a new keyset\&. .PP \fBParameters:\fP .RS 4 \fIalloc\fP minimum number of keys to allocate .br \fI\&.\&.\&.\fP variable argument list .RE .PP Allocate, initialize and return a new \fBKeySet\fP object\&. Objects created with \fBksNew()\fP must be destroyed with \fBksDel()\fP\&. .PP 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\&. .PP So, terminate with ksNew(0, KS_END) or ksNew(20, \&.\&.\&., KS_END) .PP For most uses .PP .nf KeySet *keys = ksNew(0, KS_END); // work with it ksDel (keys); .fi .PP 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\&. .PP But if you have any clue how large your keyset may be you should read the next statements\&. .PP If you want a keyset with length 15 (because you know of your application that you normally need about 12 up to 15 keys), use: .PP .nf KeySet * keys = ksNew (15, keyNew ("user/sw/app/fixedConfiguration/key01", KEY_SWITCH_VALUE, "value01", 0), keyNew ("user/sw/app/fixedConfiguration/key02", KEY_SWITCH_VALUE, "value02", 0), keyNew ("user/sw/app/fixedConfiguration/key03", KEY_SWITCH_VALUE, "value03", 0), // \&.\&.\&. keyNew ("user/sw/app/fixedConfiguration/key15", KEY_SWITCH_VALUE, "value15", 0), KS_END); // work with it ksDel (keys); .fi .PP .PP If you start having 3 keys, and your application needs approximately 200-500 keys, you can use: .PP .nf KeySet * config = ksNew (500, keyNew ("user/sw/app/fixedConfiguration/key1", KEY_SWITCH_VALUE, "value1", 0), keyNew ("user/sw/app/fixedConfiguration/key2", KEY_SWITCH_VALUE, "value2", 0), keyNew ("user/sw/app/fixedConfiguration/key3", KEY_SWITCH_VALUE, "value3", 0), KS_END); // don't forget the KS_END at the end! // work with it ksDel (config); .fi .PP 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\&. .PP The main benefit of taking a list of variant length parameters is to be able to have one C-Statement for any possible \fBKeySet\fP\&. .PP \fBPostcondition:\fP .RS 4 the keyset is rewinded properly .RE .PP \fBSee also:\fP .RS 4 \fBksDel()\fP to free the \fBKeySet\fP afterwards .PP \fBksDup()\fP to duplicate an existing \fBKeySet\fP .RE .PP \fBParameters:\fP .RS 4 \fIalloc\fP gives a hint for the size how many Keys may be stored initially .RE .PP \fBReturns:\fP .RS 4 a ready to use \fBKeySet\fP object .RE .PP \fBReturn values:\fP .RS 4 \fI0\fP on memory error .RE .PP \fBPrecondition:\fP .RS 4 caller must call va_start and va_end .RE .PP \fBva the list of arguments\fP .RS 4 .RE .PP \fBParameters:\fP .RS 4 \fIalloc\fP the allocation size .br \fIva\fP the list of variable arguments .RE .PP .SS "kdb::KeySet::KeySet (\fBVa\fP va, size_t alloc, va_list av)\fC [inline]\fP, \fC [explicit]\fP" .PP Create a new keyset\&. .PP \fBParameters:\fP .RS 4 \fIalloc\fP minimum number of keys to allocate .br \fIap\fP variable arguments list .RE .PP Use va as first argument to use this constructor, e\&.g\&.: .PP .nf KeySet ks(va, 23, \&.\&.\&.); .fi .PP .PP Allocate, initialize and return a new \fBKeySet\fP object\&. Objects created with \fBksNew()\fP must be destroyed with \fBksDel()\fP\&. .PP 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\&. .PP So, terminate with ksNew(0, KS_END) or ksNew(20, \&.\&.\&., KS_END) .PP For most uses .PP .nf KeySet *keys = ksNew(0, KS_END); // work with it ksDel (keys); .fi .PP 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\&. .PP But if you have any clue how large your keyset may be you should read the next statements\&. .PP If you want a keyset with length 15 (because you know of your application that you normally need about 12 up to 15 keys), use: .PP .nf KeySet * keys = ksNew (15, keyNew ("user/sw/app/fixedConfiguration/key01", KEY_SWITCH_VALUE, "value01", 0), keyNew ("user/sw/app/fixedConfiguration/key02", KEY_SWITCH_VALUE, "value02", 0), keyNew ("user/sw/app/fixedConfiguration/key03", KEY_SWITCH_VALUE, "value03", 0), // \&.\&.\&. keyNew ("user/sw/app/fixedConfiguration/key15", KEY_SWITCH_VALUE, "value15", 0), KS_END); // work with it ksDel (keys); .fi .PP .PP If you start having 3 keys, and your application needs approximately 200-500 keys, you can use: .PP .nf KeySet * config = ksNew (500, keyNew ("user/sw/app/fixedConfiguration/key1", KEY_SWITCH_VALUE, "value1", 0), keyNew ("user/sw/app/fixedConfiguration/key2", KEY_SWITCH_VALUE, "value2", 0), keyNew ("user/sw/app/fixedConfiguration/key3", KEY_SWITCH_VALUE, "value3", 0), KS_END); // don't forget the KS_END at the end! // work with it ksDel (config); .fi .PP 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\&. .PP The main benefit of taking a list of variant length parameters is to be able to have one C-Statement for any possible \fBKeySet\fP\&. .PP \fBPostcondition:\fP .RS 4 the keyset is rewinded properly .RE .PP \fBSee also:\fP .RS 4 \fBksDel()\fP to free the \fBKeySet\fP afterwards .PP \fBksDup()\fP to duplicate an existing \fBKeySet\fP .RE .PP \fBParameters:\fP .RS 4 \fIalloc\fP gives a hint for the size how many Keys may be stored initially .RE .PP \fBReturns:\fP .RS 4 a ready to use \fBKeySet\fP object .RE .PP \fBReturn values:\fP .RS 4 \fI0\fP on memory error .RE .PP \fBPrecondition:\fP .RS 4 caller must call va_start and va_end .RE .PP \fBva the list of arguments\fP .RS 4 .RE .PP \fBParameters:\fP .RS 4 \fIalloc\fP the allocation size .br \fIva\fP the list of variable arguments .RE .PP .SS "kdb::KeySet::~KeySet ()\fC [inline]\fP" .PP Deconstruct a keyset\&. A destructor for \fBKeySet\fP objects\&. Cleans all internal dynamic attributes, decrement all reference pointers to all keys and then \fBkeyDel()\fP all contained Keys, and free()s the release the \fBKeySet\fP object memory (that was previously allocated by \fBksNew()\fP)\&. .PP \fBParameters:\fP .RS 4 \fIks\fP the keyset object to work with .RE .PP \fBReturn values:\fP .RS 4 \fI0\fP when the keyset was freed .br \fI-1\fP on null pointer .RE .PP \fBSee also:\fP .RS 4 \fBksNew()\fP .RE .PP .SH "Member Function Documentation" .PP .SS "ssize_t kdb::KeySet::append (const \fBKey\fP & toAppend)\fC [inline]\fP" .PP append a key .PP \fBParameters:\fP .RS 4 \fItoAppend\fP key to append .RE .PP \fBReturns:\fP .RS 4 number of keys in the keyset .RE .PP Appends a \fBKey\fP to the end of \fCks\fP\&. Will take ownership of the key \fCtoAppend\fP\&. That means ksDel(ks) will remove the key unless the key: .IP "\(bu" 2 was duplicated before inserting .IP "\(bu" 2 got its refcount incremented by \fBkeyIncRef()\fP before inserting .IP "\(bu" 2 was also inserted into another keyset with \fBksAppendKey()\fP .PP .PP The reference counter of the key will be incremented to show this ownership, and thus \fCtoAppend\fP is not const\&. .PP \fBNote:\fP .RS 4 Because the key is not copied, also the pointer to the current metadata \fBkeyNextMeta()\fP will be shared\&. .RE .PP \fBSee also:\fP .RS 4 \fBkeyGetRef()\fP\&. .RE .PP If the keyname already existed in the keyset, it will be replaced with the new key\&. .PP The \fBKeySet\fP internal cursor will be set to the new key\&. .PP It is save to directly append newly created keys: .PP .nf KeySet *ks = ksNew(1, KS_END); ksAppendKey(ks, keyNew("user/my/new/key", KEY_END)); ksDel(ks); // key deleted, too! .fi .PP If you want the key to outlive the keyset, make sure to do proper ref counting: .PP .nf KeySet *ks = ksNew(1, KS_END); Key *k = keyNew("user/ref/key", KEY_END); keyIncRef(k); ksAppendKey(ks, k); ksDel(ks); // now we still can work with the key k! keyDecRef(k); keyDel(k); .fi .PP Or if you want to avoid aliasing at all, you can duplicate the key\&. But then key in the keyset has another identity: .PP .nf KeySet *ks = ksNew(1, KS_END); Key *k = keyNew("user/ref/key", KEY_END); ksAppendKey(ks, keyDup(k)); ksDel(ks); // now we still can work with the key k! keyDel(k); .fi .PP .PP \fBReturns:\fP .RS 4 the size of the \fBKeySet\fP after insertion .RE .PP \fBReturn values:\fP .RS 4 \fI-1\fP on NULL pointers .br \fI-1\fP if insertion failed, the key will be deleted then\&. .RE .PP \fBParameters:\fP .RS 4 \fIks\fP \fBKeySet\fP that will receive the key .br \fItoAppend\fP \fBKey\fP that will be appended to ks or deleted .RE .PP \fBSee also:\fP .RS 4 \fBksAppend()\fP, \fBkeyNew()\fP, \fBksDel()\fP .PP \fBkeyIncRef()\fP .RE .PP .SS "ssize_t kdb::KeySet::append (const \fBKeySet\fP & toAppend)\fC [inline]\fP" .PP append a keyset .PP \fBParameters:\fP .RS 4 \fItoAppend\fP keyset to append .RE .PP \fBReturns:\fP .RS 4 number of keys in the keyset .RE .PP Append all \fCtoAppend\fP contained keys to the end of the \fCks\fP\&. \fCtoAppend\fP \fBKeySet\fP will be left unchanged\&. .PP If a key is both in toAppend and ks, the \fBKey\fP in ks will be overridden\&. .PP \fBNote:\fP .RS 4 Because the key is not copied, also the pointer to the current metadata \fBkeyNextMeta()\fP will be shared\&. .RE .PP \fBPostcondition:\fP .RS 4 Sorted \fBKeySet\fP ks with all keys it had before and additionally the keys from toAppend .RE .PP \fBReturns:\fP .RS 4 the size of the \fBKeySet\fP after transfer .RE .PP \fBReturn values:\fP .RS 4 \fI-1\fP on NULL pointers .RE .PP \fBParameters:\fP .RS 4 \fIks\fP the \fBKeySet\fP that will receive the keys .br \fItoAppend\fP the \fBKeySet\fP that provides the keys that will be transferred .RE .PP \fBSee also:\fP .RS 4 \fBksAppendKey()\fP .RE .PP .SS "\fBKey\fP kdb::KeySet::at (cursor_t pos) const\fC [inline]\fP" .PP Lookup a key by index\&. .PP \fBParameters:\fP .RS 4 \fIpos\fP cursor position .RE .PP \fBReturns:\fP .RS 4 the found key .RE .PP .SS "void kdb::KeySet::clear ()\fC [inline]\fP" .PP Clear the keyset\&. Keyset will have no keys afterwards\&. .SS "void kdb::KeySet::copy (const \fBKeySet\fP & other)\fC [inline]\fP" .PP Copy a keyset\&. .PP \fBParameters:\fP .RS 4 \fIother\fP other keyset to copy .RE .PP This is only a shallow copy\&. For a deep copy you need to dup every key\&. .PP Copy a keyset\&. Most often you may want a duplicate of a keyset, see \fBksDup()\fP or append keys, see \fBksAppend()\fP\&. But in some situations you need to copy a keyset to a existing keyset, for that this function exists\&. .PP You can also use it to clear a keyset when you pass a NULL pointer as \fCsource\fP\&. .PP Note that all keys in \fCdest\fP will be deleted\&. Afterwards the content of the source will be added to the destination and the \fBksCurrent()\fP is set properly in \fCdest\fP\&. .PP A flat copy is made, so the keys will not be duplicated, but there reference counter is updated, so both keysets need to be \fBksDel()\fP\&. .PP \fBNote:\fP .RS 4 Because the key is not copied, also the pointer to the current metadata \fBkeyNextMeta()\fP will be shared\&. .RE .PP .PP .nf int f (KeySet *ks) { KeySet *c = ksNew (20, \&.\&.\&., KS_END); // c receives keys ksCopy (ks, c); // pass the keyset to the caller ksDel (c); } // caller needs to ksDel (ks) .fi .PP .PP \fBParameters:\fP .RS 4 \fIsource\fP has to be an initialized source \fBKeySet\fP or NULL .br \fIdest\fP has to be an initialized \fBKeySet\fP where to write the keys .RE .PP \fBReturn values:\fP .RS 4 \fI1\fP on success .br \fI0\fP if dest was cleared successfully (source is NULL) .br \fI-1\fP on NULL pointer .RE .PP \fBSee also:\fP .RS 4 \fBksNew()\fP, \fBksDel()\fP, \fBksDup()\fP .PP \fBkeyCopy()\fP for copying keys .RE .PP .SS "\fBKey\fP kdb::KeySet::current () const\fC [inline]\fP" .PP Return the current \fBKey\fP\&. The pointer is NULL if you reached the end or after \fBksRewind()\fP\&. .PP \fBNote:\fP .RS 4 You must not delete the key or change the key, use \fBksPop()\fP if you want to delete it\&. .RE .PP \fBParameters:\fP .RS 4 \fIks\fP the keyset object to work with .RE .PP \fBReturns:\fP .RS 4 pointer to the \fBKey\fP pointed by \fCks's\fP cursor .RE .PP \fBReturn values:\fP .RS 4 \fI0\fP on NULL pointer .RE .PP \fBSee also:\fP .RS 4 \fBksNext()\fP, \fBksRewind()\fP .RE .PP .SS "\fBKeySet\fP kdb::KeySet::cut (\fBKey\fP k)\fC [inline]\fP" .PP Cuts out a keyset at the cutpoint\&. Searches for the cutpoint inside the \fBKeySet\fP ks\&. If found it cuts out everything which is below (see \fBkeyIsBelow()\fP) this key\&. These keys will be missing in the keyset \fCks\fP\&. Instead, they will be moved to the returned keyset\&. If \fCcutpoint\fP is not found an empty keyset is returned and \fCks\fP is not changed\&. .PP The cursor will stay at the same key as it was before\&. If the cursor was inside the region of cut (moved) keys, the cursor will be set to the key before the cutpoint\&. .PP If you use \fBksCut()\fP on a keyset you got from \fBkdbGet()\fP and plan to make a \fBkdbSet()\fP later, make sure that you keep all keys that should not be removed permanently\&. You have to keep the \fBKeySet\fP that was returned and the \fBKeySet\fP \fCks\fP\&. .PP \fBExample:\fP .RS 4 .RE .PP You have the keyset \fCks:\fP .IP "\(bu" 2 \fCsystem/mountpoint/interest\fP .IP "\(bu" 2 \fCsystem/mountpoint/interest/folder\fP .IP "\(bu" 2 \fCsystem/mountpoint/interest/folder/key1\fP .IP "\(bu" 2 \fCsystem/mountpoint/interest/folder/key2\fP .IP "\(bu" 2 \fCsystem/mountpoint/other/key1\fP .PP .PP When you use .PP .nf Key *parentKey = keyNew("system/mountpoint/interest", KEY_END); KDB *kdb = kdbOpen(parentKey); KeySet *ks = ksNew(0, KS_END); kdbGet(kdb, ks, parentKey); KeySet *returned = ksCut(ks, parentKey); kdbSet(kdb, ks, parentKey); // all keys below cutpoint are now removed kdbClose(kdb, parentKey); .fi .PP Then in \fCreturned\fP are: .IP "\(bu" 2 \fCsystem/mountpoint/interest\fP .IP "\(bu" 2 \fCsystem/mountpoint/interest/folder\fP .IP "\(bu" 2 \fCsystem/mountpoint/interest/folder/key1\fP .IP "\(bu" 2 \fCsystem/mountpoint/interest/folder/key2\fP .PP .PP And in \fCks\fP are: .IP "\(bu" 2 \fCsystem/mountpoint/other/key1\fP .PP .PP So \fBkdbSet()\fP permanently removes all keys below \fCsystem/mountpoint/interest\fP\&. .PP \fBSee also:\fP .RS 4 \fBkdbGet()\fP for explanation why you might get more keys than you requested\&. .RE .PP \fBReturns:\fP .RS 4 a new allocated \fBKeySet\fP which needs to deleted with \fBksDel()\fP\&. The keyset consists of all keys (of the original keyset ks) below the cutpoint\&. If the key cutpoint exists, it will also be appended\&. .RE .PP \fBReturn values:\fP .RS 4 \fI0\fP on null pointers, no key name or allocation problems .RE .PP \fBParameters:\fP .RS 4 \fIks\fP the keyset to cut\&. It will be modified by removing all keys below the cutpoint\&. The cutpoint itself will also be removed\&. .br \fIcutpoint\fP the point where to cut out the keyset .RE .PP .SS "ckdb::KeySet * kdb::KeySet::dup () const\fC [inline]\fP" .PP Duplicate a keyset\&. .PP \fBReturns:\fP .RS 4 a copy of the keys .RE .PP This is only a shallow copy\&. For a deep copy you need to dup every key\&. .PP Return a duplicate of a keyset\&. Objects created with \fBksDup()\fP must be destroyed with \fBksDel()\fP\&. .PP Memory will be allocated as needed for dynamic properties, so you need to \fBksDel()\fP the returned pointer\&. .PP A flat copy is made, so the keys will not be duplicated, but there reference counter is updated, so both keysets need \fBksDel()\fP\&. .PP \fBParameters:\fP .RS 4 \fIsource\fP has to be an initialized source \fBKeySet\fP .RE .PP \fBReturns:\fP .RS 4 a flat copy of source on success .RE .PP \fBReturn values:\fP .RS 4 \fI0\fP on NULL pointer .RE .PP \fBSee also:\fP .RS 4 \fBksNew()\fP, \fBksDel()\fP .PP \fBkeyDup()\fP for \fBKey\fP duplication .RE .PP .SS "cursor_t kdb::KeySet::getCursor () const\fC [inline]\fP" .PP Get the \fBKeySet\fP internal cursor\&. Use it to get the cursor of the actual position\&. .PP \fBWarning:\fP .RS 4 Cursors are getting invalid when the key was \fBksPop()\fPed or \fBksLookup()\fP with KDB_O_POP was used\&. .RE .PP .SH "Read ahead" .PP With the cursors it is possible to read ahead in a keyset: .PP .PP .nf cursor_t jump; ksRewind (ks); while ((key = keyNextMeta (ks))!=0) { // now mark this key jump = ksGetCursor(ks); //code\&.\&. keyNextMeta (ks); // now browse on // use ksCurrent(ks) to check the keys //code\&.\&. // jump back to the position marked before ksSetCursor(ks, jump); } .fi .PP .SH "Restoring state" .PP It can also be used to restore the state of a keyset in a function .PP .PP .nf int f (KeySet *ks) { cursor_t state = ksGetCursor(ks); // work with keyset // now bring the keyset to the state before ksSetCursor (ks, state); } .fi .PP .PP It is of course possible to make the \fBKeySet\fP const and cast its const away to set the cursor\&. Another way to achieve the same is to \fBksDup()\fP the keyset, but it is not as efficient\&. .PP An invalid cursor will be returned directly after \fBksRewind()\fP\&. When you set an invalid cursor \fBksCurrent()\fP is 0 and \fBksNext()\fP == \fBksHead()\fP\&. .PP \fBNote:\fP .RS 4 Only use a cursor for the same keyset which it was made for\&. .RE .PP \fBParameters:\fP .RS 4 \fIks\fP the keyset object to work with .RE .PP \fBReturns:\fP .RS 4 a valid cursor on success .PP an invalid cursor on NULL pointer or after \fBksRewind()\fP .RE .PP \fBSee also:\fP .RS 4 \fBksNext()\fP, \fBksSetCursor()\fP .RE .PP .SS "ckdb::KeySet * kdb::KeySet::getKeySet () const\fC [inline]\fP" .PP Passes out the raw keyset pointer\&. .PP \fBReturns:\fP .RS 4 pointer to internal ckdb \fBKeySet\fP .RE .PP \fBSee also:\fP .RS 4 \fBrelease()\fP .PP \fBsetKeySet()\fP .RE .PP .SS "\fBKey\fP kdb::KeySet::head () const\fC [inline]\fP" .PP Return the first key in the \fBKeySet\fP\&. .PP \fBReturns:\fP .RS 4 alphabetical first key .RE .PP The KeySets cursor will not be effected\&. .PP If \fBksCurrent()\fP==\fBksHead()\fP you know you are on the first key\&. .PP \fBParameters:\fP .RS 4 \fIks\fP the keyset object to work with .RE .PP \fBReturns:\fP .RS 4 the first \fBKey\fP of a keyset .RE .PP \fBReturn values:\fP .RS 4 \fI0\fP on NULL pointer or empty keyset .RE .PP \fBSee also:\fP .RS 4 \fBksTail()\fP for the last \fBKey\fP .PP \fBksRewind()\fP, \fBksCurrent()\fP and \fBksNext()\fP for iterating over the \fBKeySet\fP .RE .PP .SS "\fBKey\fP kdb::KeySet::lookup (const \fBKey\fP & key, const \fBoption_t\fP options = \fC\fBKDB_O_NONE\fP\fP) const\fC [inline]\fP" .PP Look for a \fBKey\fP contained in \fCks\fP that matches the name of the \fCkey\fP\&. \fC\fBksLookup()\fP\fP is designed to let you work with entirely pre-loaded KeySets\&. The idea is to fully \fBkdbGet()\fP for your application root key and process it all at once with \fC\fBksLookup()\fP\fP\&. .PP This function is efficient by using binary search\&. Together with \fBkdbGet()\fP which can you load the whole configuration you can write very effective but short code for configuration: .PP .PP .nf .fi .PP This is the way programs should get their 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\&. Furthermore, using the kdb-tool, it is possible to find out which value an application will find\&. .PP If found, \fCks\fP internal cursor will be positioned in the matched key (also accessible by \fBksCurrent()\fP), and a pointer to the \fBKey\fP is returned\&. If not found, \fCks\fP internal cursor will not move, and a NULL pointer is returned\&. .PP Cascading is done if the first character is a /\&. This leads to search in all namespaces proc/, dir/, user/ and system/, but also correctly considers the specification (=metadata) in spec/: .PP .IP "\(bu" 2 \fCoverride/#\fP will make sure that another key is considered before .IP "\(bu" 2 \fCnamespace/#\fP will change the number and/or order in which the namespaces are searched .IP "\(bu" 2 \fCfallback/#\fP will search for other keys when the other possibilities up to now were not successful .IP "\(bu" 2 \fCdefault\fP to return the given value when not even \fCfallback\fP keys were found\&. .PP .PP \fBNote:\fP .RS 4 override and fallback work recursively, while default does not\&. .RE .PP This process is very flexible, but it would be boring to follow all this links in the head to find out which key will be taken\&. So use \fCkdb get -v\fP to trace the keys\&. .PP \fBKDB_O_POP\fP .RS 4 When \fBKDB_O_POP\fP is set the key which was found will be \fBksPop()\fPed\&. \fBksCurrent()\fP will not be changed, only iff \fBksCurrent()\fP is the searched key, then the keyset will be \fBksRewind()\fPed\&. .RE .PP \fBNote:\fP .RS 4 Like in \fBksPop()\fP the popped key always needs to be \fBkeyDel()\fP afterwards, even if it is appended to another keyset\&. .RE .PP \fBWarning:\fP .RS 4 All cursors on the keyset will be invalid iff you use \fBKDB_O_POP\fP, so don't use this if you rely on a cursor, see \fBksGetCursor()\fP\&. .RE .PP The invalidation of cursors does not matter if you use multiple keysets, e\&.g\&. by using \fBksDup()\fP\&. E\&.g\&., to separate \fBksLookup()\fP with \fBKDB_O_POP\fP and \fBksAppendKey()\fP: .PP .PP .nf void f(KeySet *iterator, KeySet *lookup) { KeySet *append = ksNew (ksGetSize(lookup), KS_END); Key *key; Key *current; ksRewind(iterator); while ((current=ksNext(iterator))) { key = ksLookup (lookup, current, KDB_O_POP); // do something\&.\&.\&. ksAppendKey(append, key); // now append it to append, not lookup! keyDel (key); // make sure to ALWAYS delete poped keys\&. } ksAppend(lookup, append); // now lookup needs to be sorted only once, append never ksDel (append); } .fi .PP This is also a nice example how a complete application with \fBksLookup()\fP can look like\&. .PP \fBKDB_O_DEL\fP .RS 4 Passing \fBKDB_O_DEL\fP will cause the deletion of the parameter \fCkey\fP using \fBkeyDel()\fP\&. .RE .PP \fBKDB_O_NOALL (deprecated)\fP .RS 4 When \fBKDB_O_NOALL\fP is set the keyset will be only searched from \fBksCurrent()\fP to \fBksTail()\fP\&. You need to \fBksRewind()\fP the keyset yourself\&. \fBksCurrent()\fP is always set properly after searching a key, so you can go on searching another key after the found key\&. .br When \fBKDB_O_NOALL\fP is not set the cursor will stay untouched and all keys are considered\&. A much more efficient binary search will be used then\&. .RE .PP \fBKDB_O_WITHOWNER (deprecated)\fP .RS 4 Also consider correct owner (needs \fBKDB_O_NOALL\fP)\&. .RE .PP \fBKDB_O_NOCASE (deprecated)\fP .RS 4 Lookup ignoring case (needs \fBKDB_O_NOALL\fP)\&. .RE .PP \fBParameters:\fP .RS 4 \fIks\fP where to look for .br \fIkey\fP the key object you are looking for .br \fIoptions\fP of type \fBoption_t\fP with some \fCKDB_O_*\fP option bits as explained above .RE .PP \fBReturns:\fP .RS 4 pointer to the \fBKey\fP found, 0 otherwise .RE .PP \fBReturn values:\fP .RS 4 \fI0\fP on NULL pointers .RE .PP \fBSee also:\fP .RS 4 \fBksLookupByName()\fP to search by a name given by a string .PP \fBksCurrent()\fP, \fBksRewind()\fP, \fBksNext()\fP for iterating over a \fBKeySet\fP .RE .PP \fBNote:\fP .RS 4 That the internal key cursor will point to the found key .RE .PP .SS "\fBKey\fP kdb::KeySet::lookup (std::string const & name, const \fBoption_t\fP options = \fC\fBKDB_O_NONE\fP\fP) const\fC [inline]\fP" .PP Lookup a key by name\&. .PP \fBParameters:\fP .RS 4 \fIname\fP the name to look for .br \fIoptions\fP some options to pass .RE .PP \fBReturns:\fP .RS 4 the found key .RE .PP \fBSee also:\fP .RS 4 \fBlookup\fP (const \fBKey\fP &\fBKey\fP, const \fBoption_t\fP options) .RE .PP \fBNote:\fP .RS 4 That the internal key cursor will point to the found key .RE .PP .SS "\fBKey\fP kdb::KeySet::next () const\fC [inline]\fP" .PP Returns the next \fBKey\fP in a \fBKeySet\fP\&. KeySets have an internal cursor that can be reset with \fBksRewind()\fP\&. Every time \fBksNext()\fP is called the cursor is incremented and the new current \fBKey\fP is returned\&. .PP You'll get a NULL pointer if the key after the end of the \fBKeySet\fP was reached\&. On subsequent calls of \fBksNext()\fP it will still return the NULL pointer\&. .PP The \fCks\fP internal cursor will be changed, so it is not const\&. .PP \fBNote:\fP .RS 4 You must not delete or change the key, use \fBksPop()\fP if you want to delete it\&. .RE .PP \fBParameters:\fP .RS 4 \fIks\fP the keyset object to work with .RE .PP \fBReturns:\fP .RS 4 the new current \fBKey\fP .RE .PP \fBReturn values:\fP .RS 4 \fI0\fP when the end is reached .br \fI0\fP on NULL pointer .RE .PP \fBSee also:\fP .RS 4 \fBksRewind()\fP, \fBksCurrent()\fP .RE .PP .SS "\fBKeySet\fP & kdb::KeySet::operator= (\fBKeySet\fP const & other)\fC [inline]\fP" .PP Duplicate a keyset\&. This keyset will be a duplicate of the other afterwards\&. .PP \fBNote:\fP .RS 4 that they still reference to the same Keys, so if you change key values also the keys in the original keyset will be changed\&. .RE .PP .SS "\fBKey\fP kdb::KeySet::pop ()\fC [inline]\fP" .PP Remove and return the last key of \fCks\fP\&. The reference counter will be decremented by one\&. .PP The KeySets cursor will not be effected if it did not point to the popped key\&. .PP \fBNote:\fP .RS 4 You need to \fBkeyDel()\fP the key afterwards, if you don't append it to another keyset\&. It has the same semantics like a key allocated with \fBkeyNew()\fP or \fBkeyDup()\fP\&. .RE .PP .PP .nf ks1=ksNew(0, KS_END); ks2=ksNew(0, KS_END); k1=keyNew("user/name", KEY_END); // ref counter 0 ksAppendKey(ks1, k1); // ref counter 1 ksAppendKey(ks2, k1); // ref counter 2 k1=ksPop (ks1); // ref counter 1 k1=ksPop (ks2); // ref counter 0, like after keyNew() ksAppendKey(ks1, k1); // ref counter 1 ksDel (ks1); // key is deleted too ksDel (ks2); .fi .PP .PP \fBReturns:\fP .RS 4 the last key of \fCks\fP .RE .PP \fBReturn values:\fP .RS 4 \fINULL\fP if \fCks\fP is empty or on NULL pointer .RE .PP \fBParameters:\fP .RS 4 \fIks\fP \fBKeySet\fP to work with .RE .PP \fBSee also:\fP .RS 4 \fBksAppendKey()\fP, \fBksAppend()\fP .PP commandList() for an example .RE .PP .SS "void kdb::KeySet::rewind () const\fC [inline]\fP" .PP Rewinds the \fBKeySet\fP internal cursor\&. Use it to set the cursor to the beginning of the \fBKeySet\fP\&. \fBksCurrent()\fP will then always return NULL afterwards\&. So you want to \fBksNext()\fP first\&. .PP .PP .nf ksRewind (ks); while ((key = ksNext (ks))!=0) {} .fi .PP .PP \fBParameters:\fP .RS 4 \fIks\fP the keyset object to work with .RE .PP \fBReturn values:\fP .RS 4 \fI0\fP on success .br \fI-1\fP on NULL pointer .RE .PP \fBSee also:\fP .RS 4 \fBksNext()\fP, \fBksCurrent()\fP .RE .PP .SS "void kdb::KeySet::setCursor (cursor_t cursor) const\fC [inline]\fP" .PP Set the \fBKeySet\fP internal cursor\&. Use it to set the cursor to a stored position\&. \fBksCurrent()\fP will then be the position which you got with\&. .PP \fBWarning:\fP .RS 4 Cursors may get invalid when the key was \fBksPop()\fPed or \fBksLookup()\fP was used together with KDB_O_POP\&. .RE .PP .PP .nf cursor_t cursor; \&.\&. // key now in any position here cursor = ksGetCursor (ks); while ((key = keyNextMeta (ks))!=0) {} ksSetCursor (ks, cursor); // reset state ksCurrent(ks); // in same position as before .fi .PP .PP An invalid cursor will set the keyset to its beginning like \fBksRewind()\fP\&. When you set an invalid cursor \fBksCurrent()\fP is 0 and \fBksNext()\fP == \fBksHead()\fP\&. .PP \fBParameters:\fP .RS 4 \fIcursor\fP the cursor to use .br \fIks\fP the keyset object to work with .RE .PP \fBReturn values:\fP .RS 4 \fI0\fP when the keyset is \fBksRewind()\fPed .br \fI1\fP otherwise .br \fI-1\fP on NULL pointer .RE .PP \fBSee also:\fP .RS 4 \fBksNext()\fP, \fBksGetCursor()\fP .RE .PP .SS "void kdb::KeySet::setKeySet (ckdb::KeySet * k)\fC [inline]\fP" .PP Take ownership of passed keyset\&. .PP \fBParameters:\fP .RS 4 \fIk\fP the keyset to take ownership from .RE .PP \fBSee also:\fP .RS 4 \fBrelease()\fP .PP \fBgetKeySet()\fP .RE .PP .SS "ssize_t kdb::KeySet::size () const\fC [inline]\fP" .PP The size of the keyset\&. .PP \fBReturns:\fP .RS 4 the number of keys in the keyset .RE .PP .SS "\fBKey\fP kdb::KeySet::tail () const\fC [inline]\fP" .PP Return the last key in the \fBKeySet\fP\&. .PP \fBReturns:\fP .RS 4 alphabetical last key .RE .PP The KeySets cursor will not be effected\&. .PP If \fBksCurrent()\fP==\fBksTail()\fP you know you are on the last key\&. \fBksNext()\fP will return a NULL pointer afterwards\&. .PP \fBParameters:\fP .RS 4 \fIks\fP the keyset object to work with .RE .PP \fBReturns:\fP .RS 4 the last \fBKey\fP of a keyset .RE .PP \fBReturn values:\fP .RS 4 \fI0\fP on NULL pointer or empty keyset .RE .PP \fBSee also:\fP .RS 4 \fBksHead()\fP for the first \fBKey\fP .PP \fBksRewind()\fP, \fBksCurrent()\fP and \fBksNext()\fP for iterating over the \fBKeySet\fP .RE .PP .SH "Author" .PP Generated automatically by Doxygen for Elektra from the source code\&.