Elektra  0.8.10
Public Member Functions
kdb::KeySet Class Reference

A keyset holds together a set of keys. More...

#include <keyset.hpp>

Public Member Functions

 KeySet ()
 
 
 KeySet (ckdb::KeySet *k)
 
 KeySet (const KeySet &other)
 
 KeySet (size_t alloc, va_list ap)
 Create a new keyset.
 
 KeySet (size_t alloc,...)
 Create a new keyset.
 
 ~KeySet ()
 Deconstruct a keyset.
 
ckdb::KeySet * release ()
 
ckdb::KeySet * getKeySet () const
 Passes out the raw keyset pointer.
 
void setKeySet (ckdb::KeySet *k)
 Take ownership of passed keyset.
 
KeySetoperator= (KeySet const &other)
 
ssize_t size () const
 The size of the keyset.
 
ckdb::KeySet * dup () const
 Duplicate a keyset.
 
void copy (const KeySet &other)
 Copy a keyset.
 
void clear ()
 Clear the keyset.
 
ssize_t append (const Key &toAppend)
 append a key
 
ssize_t append (const KeySet &toAppend)
 append a keyset
 
Key head () const
 
 
Key tail () const
 
 
void rewind () const
 
 
Key next () const
 
 
Key current () const
 
 
void setCursor (cursor_t cursor) const
 
 
cursor_t getCursor () const
 
 
Key pop ()
 
 
KeySet cut (Key k)
 
 
Key lookup (const Key &k, const option_t options=KDB_O_NONE) const
 
 
Key lookup (std::string const &name, const option_t options=KDB_O_NONE) const
 Lookup a key by name.
 
Key at (cursor_t pos) const
 Lookup a key by index.
 

Detailed Description

A keyset holds together a set of keys.

Methods to manipulate KeySets. A KeySet is a sorted set of keys. So the correct name actually would be KeyMap.With ksNew() you can create a new KeySet.You can add keys with ksAppendKey() in the keyset. Using ksAppend() you can append a whole keyset.

Note
Because the key is not copied, also the pointer to the current metadata keyNextMeta() will be shared.
ksGetSize() tells you the current size of the keyset.With ksRewind() and ksNext() 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.KeySets have an internal cursor . This is used for ksLookup() and kdbSet().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 ksLookupByName() it is possible to fetch easily specific keys out of the list of keys.You can easily create and iterate keys:

#include <kdb.h>
// 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

Invariant
always holds an underlying elektra keyset.
Note
that the cursor is mutable, so it might be changed even in const functions as described.

Constructor & Destructor Documentation

kdb::KeySet::KeySet ( )
inline

Creates a new empty keyset with no keys

Allocate, initialize and return a new KeySet object.Objects created with ksNew() must be destroyed with ksDel().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.So, terminate with ksNew(0, KS_END) or ksNew(20, ..., KS_END)For most uses

KeySet *keys = ksNew(0, KS_END);
// work with it
ksDel (keys);

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.But if you have any clue how large your keyset may be you should read the next statements.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:

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);
If you start having 3 keys, and your application needs approximately 200-500 keys, you can use:

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);

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.The main benefit of taking a list of variant length parameters is to be able to have one C-Statement for any possible KeySet.

Postcondition
the keyset is rewinded properly
See Also
ksDel() to free the KeySet afterwards
ksDup() to duplicate an existing KeySet
Parameters
allocgives a hint for the size how many Keys may be stored initially
Returns
a ready to use KeySet object
0 on memory error

kdb::KeySet::KeySet ( ckdb::KeySet *  k)
inline

Takes ownership of keyset!

Keyset will be destroyed at destructor you cant continue to use keyset afterwards!

Use KeySet::release() to avoid destruction.

Parameters
kthe keyset to take the ownership from
See Also
release()
setKeySet()
kdb::KeySet::KeySet ( const KeySet other)
inline

Duplicate a keyset.

This keyset will be a duplicate of the other afterwards.

Note
that they still reference to the same Keys, so if you change key values also the keys in the original keyset will be changed.

So it is shallow copy, to create a deep copy you have to dup() every key (it still won't copy meta data, but they are COW):

kdb::KeySet ksDeepCopy(kdb::KeySet orig)
{
kdb::KeySet deepCopy;
orig.rewind();
while(orig.next())
{
deepCopy.append(orig.current().dup());
}
return deepCopy;
}
See Also
dup
kdb::KeySet::KeySet ( size_t  alloc,
va_list  ap 
)
inlineexplicit

Create a new keyset.

Parameters
allocminimum number of keys to allocate
apvariable arguments list

Allocate, initialize and return a new KeySet object.Objects created with ksNew() must be destroyed with ksDel().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.So, terminate with ksNew(0, KS_END) or ksNew(20, ..., KS_END)For most uses

KeySet *keys = ksNew(0, KS_END);
// work with it
ksDel (keys);

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.But if you have any clue how large your keyset may be you should read the next statements.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:

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);
If you start having 3 keys, and your application needs approximately 200-500 keys, you can use:

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);

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.The main benefit of taking a list of variant length parameters is to be able to have one C-Statement for any possible KeySet.

Postcondition
the keyset is rewinded properly
See Also
ksDel() to free the KeySet afterwards
ksDup() to duplicate an existing KeySet
Parameters
allocgives a hint for the size how many Keys may be stored initially
Returns
a ready to use KeySet object
0 on memory error
Precondition
caller must call va_start and va_end
va the list of arguments
Parameters
allocthe allocation size
vathe list of variable arguments

kdb::KeySet::KeySet ( size_t  alloc,
  ... 
)
inlineexplicit

Create a new keyset.

Parameters
allocminimum number of keys to allocate
...variable argument list

Allocate, initialize and return a new KeySet object.Objects created with ksNew() must be destroyed with ksDel().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.So, terminate with ksNew(0, KS_END) or ksNew(20, ..., KS_END)For most uses

KeySet *keys = ksNew(0, KS_END);
// work with it
ksDel (keys);

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.But if you have any clue how large your keyset may be you should read the next statements.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:

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);
If you start having 3 keys, and your application needs approximately 200-500 keys, you can use:

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);

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.The main benefit of taking a list of variant length parameters is to be able to have one C-Statement for any possible KeySet.

Postcondition
the keyset is rewinded properly
See Also
ksDel() to free the KeySet afterwards
ksDup() to duplicate an existing KeySet
Parameters
allocgives a hint for the size how many Keys may be stored initially
Returns
a ready to use KeySet object
0 on memory error
Precondition
caller must call va_start and va_end
va the list of arguments
Parameters
allocthe allocation size
vathe list of variable arguments

kdb::KeySet::~KeySet ( )
inline

Deconstruct a keyset.

A destructor for KeySet objects.Cleans all internal dynamic attributes, decrement all reference pointers to all keys and then keyDel() all contained Keys, and free()s the release the KeySet object memory (that was previously allocated by ksNew()).

Parameters
ksthe keyset object to work with
Returns
0 when the keyset was freed
-1 on null pointer
See Also
ksNew()

Member Function Documentation

ssize_t kdb::KeySet::append ( const Key toAppend)
inline

append a key

Parameters
toAppendkey to append
Returns
number of keys in the keyset

Appends a Key to the end of ks.A pointer to the key will be stored, and not a private copy. So a future ksDel() on ks may keyDel() the toAppend object, see keyGetRef().The reference counter of the key will be incremented, and thus toAppend is not const.

Note
Because the key is not copied, also the pointer to the current metadata keyNextMeta() will be shared.
If the keyname already existed, it will be replaced with the new key.The KeySet internal cursor will be set to the new key.It is save to use ksAppendKey(ks, keyNew(..)).
Returns
the size of the KeySet after insertion
-1 on NULL pointers
-1 if insertion failed, the key will be deleted then.
Parameters
ksKeySet that will receive the key
toAppendKey that will be appended to ks or deleted
See Also
ksAppend(), keyNew(), ksDel()
keyIncRef()

ssize_t kdb::KeySet::append ( const KeySet toAppend)
inline

append a keyset

Parameters
toAppendkeyset to append
Returns
number of keys in the keyset

Append all toAppend contained keys to the end of the ks.toAppend KeySet will be left unchanged.If a key is both in toAppend and ks, the Key in ks will be overridden.

Note
Because the key is not copied, also the pointer to the current metadata keyNextMeta() will be shared.
Postcondition
Sorted KeySet ks with all keys it had before and additionally the keys from toAppend
Returns
the size of the KeySet after transfer
-1 on NULL pointers
Parameters
ksthe KeySet that will receive the keys
toAppendthe KeySet that provides the keys that will be transferred
See Also
ksAppendKey()

Key kdb::KeySet::at ( cursor_t  pos) const
inline

Lookup a key by index.

Parameters
poscursor position
Returns
the found key
void kdb::KeySet::clear ( )
inline

Clear the keyset.

Keyset will have no keys afterwards.

void kdb::KeySet::copy ( const KeySet other)
inline

Copy a keyset.

Parameters
otherother keyset to copy

This is only a shallow copy. For a deep copy you need to dup every key.

Copy a keyset.Most often you may want a duplicate of a keyset, see ksDup() or append keys, see ksAppend(). But in some situations you need to copy a keyset to a existing keyset, for that this function exists.You can also use it to clear a keyset when you pass a NULL pointer as source.Note that all keys in dest will be deleted. Afterwards the content of the source will be added to the destination and the ksCurrent() is set properly in dest.A flat copy is made, so the keys will not be duplicated, but there reference counter is updated, so both keysets need to be ksDel().

Note
Because the key is not copied, also the pointer to the current metadata keyNextMeta() will be shared.
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)
Parameters
sourcehas to be an initialized source KeySet or NULL
desthas to be an initialized KeySet where to write the keys
Returns
1 on success
0 if dest was cleared successfully (source is NULL)
-1 on NULL pointer
See Also
ksNew(), ksDel(), ksDup()
keyCopy() for copying keys

Key kdb::KeySet::current ( ) const
inline

Return the current Key.The pointer is NULL if you reached the end or after ksRewind().

Note
You must not delete the key or change the key, use ksPop() if you want to delete it.
Parameters
ksthe keyset object to work with
Returns
pointer to the Key pointed by ks's cursor
0 on NULL pointer
See Also
ksNext(), ksRewind()

KeySet kdb::KeySet::cut ( Key  k)
inline

Cuts out a keyset at the cutpoint.Searches for the cutpoint inside the KeySet ks. If found it cuts out everything which is below (see keyIsBelow()) this key. These keys will be missing in the keyset ks. Instead, they will be moved to the returned keyset. If cutpoint is not found an empty keyset is returned and ks is not changed.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.If you use ksCut() on a keyset you got from kdbGet() and plan to make a kdbSet() later, make sure that you keep all keys that should not be removed permanently. You have to keep the KeySet that was returned and the KeySet ks.

Example:

You have the keyset ks:

  • system/mountpoint/interest
  • system/mountpoint/interest/folder
  • system/mountpoint/interest/folder/key1
  • system/mountpoint/interest/folder/key2
  • system/mountpoint/other/key1
When you use

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);

Then in returned are:

  • system/mountpoint/interest
  • system/mountpoint/interest/folder
  • system/mountpoint/interest/folder/key1
  • system/mountpoint/interest/folder/key2
And in ks are:

  • system/mountpoint/other/key1
So kdbSet() permanently removes all keys below system/mountpoint/interest.
See Also
kdbGet() for explanation why you might get more keys than you requested.
Returns
a new allocated KeySet which needs to deleted with ksDel(). The keyset consists of all keys (of the original keyset ks) below the cutpoint. If the key cutpoint exists, it will also be appended.
Return values
0on null pointers, no key name or allocation problems
Parameters
ksthe keyset to cut. It will be modified by removing all keys below the cutpoint. The cutpoint itself will also be removed.
cutpointthe point where to cut out the keyset

ckdb::KeySet * kdb::KeySet::dup ( ) const
inline

Duplicate a keyset.

Returns
a copy of the keys

This is only a shallow copy. For a deep copy you need to dup every key.

Return a duplicate of a keyset.Objects created with ksDup() must be destroyed with ksDel().Memory will be allocated as needed for dynamic properties, so you need to ksDel() the returned pointer.A flat copy is made, so the keys will not be duplicated, but there reference counter is updated, so both keysets need ksDel().

Parameters
sourcehas to be an initialized source KeySet
Returns
a flat copy of source on success
0 on NULL pointer
See Also
ksNew(), ksDel()
keyDup() for Key duplication

cursor_t kdb::KeySet::getCursor ( ) const
inline

Get the KeySet internal cursor.Use it to get the cursor of the actual position.

Warning
Cursors are getting invalid when the key was ksPop()ed or ksLookup() with KDB_O_POP was used.

ckdb::KeySet * kdb::KeySet::getKeySet ( ) const
inline

Passes out the raw keyset pointer.

Returns
pointer to internal ckdb KeySet
See Also
release()
setKeySet()
Key kdb::KeySet::head ( ) const
inline

Returns
alphabetical first key

Return the first key in the KeySet.The KeySets cursor will not be effected.If ksCurrent()==ksHead() you know you are on the first key.

Parameters
ksthe keyset object to work with
Returns
the first Key of a keyset
0 on NULL pointer or empty keyset
See Also
ksTail() for the last Key
ksRewind(), ksCurrent() and ksNext() for iterating over the KeySet

Key kdb::KeySet::lookup ( const Key key,
const option_t  options = KDB_O_NONE 
) const
inline

Look for a Key contained in ks that matches the name of the key.

Note
That the internal key cursor will point to the found key
Key kdb::KeySet::lookup ( std::string const &  name,
const option_t  options = KDB_O_NONE 
) const
inline

Lookup a key by name.

Parameters
namethe name to look for
optionssome options to pass
Returns
the found key
See Also
lookup (const Key &Key, const option_t options)
Note
That the internal key cursor will point to the found key
Key kdb::KeySet::next ( ) const
inline

Returns the next Key in a KeySet.KeySets have an internal cursor that can be reset with ksRewind(). Every time ksNext() is called the cursor is incremented and the new current Key is returned.You'll get a NULL pointer if the key after the end of the KeySet was reached. On subsequent calls of ksNext() it will still return the NULL pointer.The ks internal cursor will be changed, so it is not const.

Note
You must not delete or change the key, use ksPop() if you want to delete it.
Parameters
ksthe keyset object to work with
Returns
the new current Key
0 when the end is reached
0 on NULL pointer
See Also
ksRewind(), ksCurrent()

KeySet & kdb::KeySet::operator= ( KeySet const &  other)
inline

Duplicate a keyset.

This keyset will be a duplicate of the other afterwards.

Note
that they still reference to the same Keys, so if you change key values also the keys in the original keyset will be changed.
Key kdb::KeySet::pop ( )
inline

Remove and return the last key of ks.The reference counter will be decremented by one.The KeySets cursor will not be effected if it did not point to the popped key.

Note
You need to keyDel() the key afterwards, if you don't append it to another keyset. It has the same semantics like a key allocated with keyNew() or keyDup().
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);
*
Returns
the last key of ks
NULL if ks is empty or on NULL pointer
Parameters
ksKeySet to work with
See Also
ksAppendKey(), ksAppend()
commandList() for an example

ckdb::KeySet * kdb::KeySet::release ( )
inline

If you don't want destruction of keyset at the end you can release the pointer.

void kdb::KeySet::rewind ( ) const
inline

Rewinds the KeySet internal cursor.Use it to set the cursor to the beginning of the KeySet. ksCurrent() will then always return NULL afterwards. So you want to ksNext() first.

ksRewind (ks);
while ((key = ksNext (ks))!=0) {}
Parameters
ksthe keyset object to work with
Returns
0 on success
-1 on NULL pointer
See Also
ksNext(), ksCurrent()

void kdb::KeySet::setCursor ( cursor_t  cursor) const
inline

Set the KeySet internal cursor.Use it to set the cursor to a stored position. ksCurrent() will then be the position which you got with.

Warning
Cursors may get invalid when the key was ksPop()ed or ksLookup() was used together with KDB_O_POP.
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
An invalid cursor will set the keyset to its beginning like ksRewind(). When you set an invalid cursor ksCurrent() is 0 and ksNext() == ksHead().
Parameters
cursorthe cursor to use
ksthe keyset object to work with
Returns
0 when the keyset is ksRewind()ed
1 otherwise
-1 on NULL pointer
See Also
ksNext(), ksGetCursor()

void kdb::KeySet::setKeySet ( ckdb::KeySet *  k)
inline

Take ownership of passed keyset.

Parameters
kthe keyset to take ownership from
See Also
release()
getKeySet()
ssize_t kdb::KeySet::size ( ) const
inline

The size of the keyset.

Returns
the number of keys in the keyset
Key kdb::KeySet::tail ( ) const
inline

Returns
alphabetical last key

Return the last key in the KeySet.The KeySets cursor will not be effected.If ksCurrent()==ksTail() you know you are on the last key. ksNext() will return a NULL pointer afterwards.

Parameters
ksthe keyset object to work with
Returns
the last Key of a keyset
0 on NULL pointer or empty keyset
See Also
ksHead() for the first Key
ksRewind(), ksCurrent() and ksNext() for iterating over the KeySet


The documentation for this class was generated from the following file: