PMEMKV  1.4.1-git1.g7db5b8f
This is the C++ documentation for PMEMKV.
Classes | Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
pmem::kv::db::iterator< IsConst > Class Template Reference

Iterator provides methods to iterate over records in db. More...

#include <libpmemkv.hpp>

Classes

class  OutputIterator
 OutputIterator provides iteration through elements without a possibility of reading them. It is only allowed to modify them. More...
 

Public Member Functions

 iterator (iterator_type *it)
 
status seek (string_view key) noexcept
 Changes iterator position to the record with given key. More...
 
status seek_lower (string_view key) noexcept
 Changes iterator position to the record with key lower than given key. More...
 
status seek_lower_eq (string_view key) noexcept
 Changes iterator position to the record with key equal or lower than given key. More...
 
status seek_higher (string_view key) noexcept
 Changes iterator position to the record with key higher than given key. More...
 
status seek_higher_eq (string_view key) noexcept
 Changes iterator position to the record with key equal or higher than given key. More...
 
status seek_to_first () noexcept
 Changes iterator position to the first record. More...
 
status seek_to_last () noexcept
 Changes iterator position to the last record. More...
 
status is_next () noexcept
 Checks if there is a next record available. More...
 
status next () noexcept
 Changes iterator position to the next record. More...
 
status prev () noexcept
 Changes iterator position to the previous record. More...
 
result< string_viewkey () noexcept
 Returns record's key (pmem::kv::string_view), in pmem::kv::result<pmem::kv::string_view>. More...
 
result< string_viewread_range (size_t pos=0, size_t n=std::numeric_limits< size_t >::max()) noexcept
 Returns value's range (pmem::kv::string_view) to read, in pmem::kv::result. More...
 
template<bool IC = IsConst>
std::enable_if<!IC, result< pmem::obj::slice< OutputIterator< char > > > >::type write_range (size_t pos=0, size_t n=std::numeric_limits< size_t >::max()) noexcept
 
template<bool IC = IsConst>
std::enable_if<!IC, status >::type commit () noexcept
 
template<bool IC = IsConst>
std::enable_if<!IC >::type abort () noexcept
 
 iterator (iterator_type *it)
 
 iterator (iterator_type *it)
 
result< pmem::obj::slice< db::iterator< false >::OutputIterator< char > > > write_range (size_t pos, size_t n) noexcept
 Returns value's range (pmem::obj::slice<db::iterator::OutputIterator<char>>) to modify, in pmem::kv::result. More...
 
status commit () noexcept
 Commits modifications made on the current record. More...
 
void abort () noexcept
 Aborts uncommitted modifications made on the current record. More...
 

Private Types

using iterator_type = typename std::conditional< IsConst, pmemkv_iterator, pmemkv_write_iterator >::type
 

Private Member Functions

pmemkv_iterator * get_raw_it ()
 
pmemkv_iterator * get_raw_it ()
 
pmemkv_iterator * get_raw_it ()
 

Private Attributes

std::unique_ptr< iterator_type, typename std::conditional< IsConst, decltype(&pmemkv_iterator_delete), decltype(&pmemkv_write_iterator_delete)>::type > it_
 

Detailed Description

template<bool IsConst>
class pmem::kv::db::iterator< IsConst >

Iterator provides methods to iterate over records in db.

This API is EXPERIMENTAL and might change.

It can be only created by methods in db (db::new_read_iterator() - for a read iterator, and db::new_write_iterator() for a write iterator).

Both iterator types (write_iterator and read_iterator) allow reading record's key and value. A write_iterator additionally can modify record's value transactionally.

Holding simultaneously in the same thread more than one iterator is undefined behavior.

Example usage of iterators with single-threaded engines:

static std::string read_key(pmem::kv::db::read_iterator &it)
{
/* key_result's type is a pmem::kv::result<string_view>, for more information
* check pmem::kv::result documentation */
/* check if the result is ok, you can also do:
* key_result == pmem::kv::status::OK
* or
* key_result.get_status() == pmem::kv::status::OK */
ASSERT(key_result.is_ok());
return key_result.get_value().data();
}
static std::string read_value(pmem::kv::db::read_iterator &it)
{
/* val_result's type is a pmem::kv::result<string_view>, for more information
* check pmem::kv::result documentation */
/* check if the result is ok, you can also do:
* val_result == pmem::kv::status::OK
* or
* val_result.get_status() == pmem::kv::status::OK */
ASSERT(val_result.is_ok());
return val_result.get_value().data();
}
static void single_threaded_engine_example(const std::string &path)
{
const size_t n_elements = 10;
/* init radix engine */
auto kv = init_kv("radix", path + "_radix", n_elements);
/* We shouldn't hold simultaneously in the same thread more than one iterator. So
* every iterator in this example will be in a separate scope */
{
/* get a new read iterator */
auto res_it = kv->new_read_iterator();
/* you should check if the result is ok before getting a value */
ASSERT(res_it.is_ok());
/* you need to take reference to the iterator from the result, because
* iterator isn't copyable */
auto &it = res_it.get_value();
LOG("Iterate from first to last element");
auto s = it.seek_to_first();
size_t cnt = 0;
ASSERT(s == status::OK);
do {
/* read a key */
auto key = read_key(it);
ASSERT(key == std::to_string(cnt));
LOG("Key = " + key);
/* read a value */
auto value = read_value(it);
ASSERT(value == std::string(10 + cnt, 'a'));
LOG("Value = " + value);
++cnt;
} while (it.next() == status::OK);
LOG("Iterate from last to first element");
s = it.seek_to_last();
cnt = n_elements - 1;
ASSERT(s == status::OK);
do {
/* read a key */
auto key = read_key(it);
ASSERT(key == std::to_string(cnt));
LOG("Key = " + key);
/* read a value */
auto value = read_value(it);
ASSERT(value == std::string(10 + cnt, 'a'));
LOG("Value = " + value);
--cnt;
} while (it.prev() == status::OK);
/* read iterator is being destroyed now */
}
/* scope for a write iterator */
{
/* get a new write iterator */
auto res_w_it = kv->new_write_iterator();
/* you should check if the result is ok before getting a value */
ASSERT(res_w_it.is_ok());
/* you need to take reference to the iterator from the result, because
* iterator isn't copyable */
auto &w_it = res_w_it.get_value();
LOG("Modify value of the element lower than \"5\"");
/* seek to the element lower than "5" */
status s = w_it.seek_lower("5");
ASSERT(s == status::OK);
/* read a value before writting */
std::string value_before_write = w_it.read_range().get_value().data();
/* Get a write range. By default it is a whole value (pos = 0, n =
* std::numeric_limits<size_t>::max()). */
auto res = w_it.write_range();
ASSERT(res.is_ok());
/* set all chars to 'x' */
for (auto &c : res.get_value()) {
/* note that you can't read elements from write_range, so e.g.
* char x = c isn't possible. If you want to read a value, you
* need to use read_range method instead of write_range */
c = 'x';
}
/* commit modifications */
w_it.commit();
std::string current_value = w_it.read_range().get_value().data();
/* check if the value has changed */
ASSERT(current_value.compare(value_before_write) != 0);
ASSERT(current_value.compare(std::string(current_value.size(), 'x')) ==
0);
LOG("Value after commit = " + current_value);
/* write iterator is being destroyed now */
}
}

Example usage of iterators with concurrent engines:

static void concurrent_engine_example(const std::string &path)
{
const size_t n_elements = 20;
/* init csmap engine */
auto kv = init_kv("csmap", path + "_csmap", n_elements);
/* create 2 threads, in first thread iterate from the beginning to the element
* with key equal "5", in second from element with key equal "5" to the end */
std::vector<std::thread> threads;
/* thread1 */
threads.emplace_back([&]() {
auto res_it = kv->new_read_iterator();
ASSERT(res_it.is_ok());
auto &it = res_it.get_value();
do {
/* read a key */
auto key = read_key(it);
LOG("Key (from thread1) = " + key);
} while (it.next() == pmem::kv::status::OK && read_key(it).compare("5"));
});
/* thread2 */
threads.emplace_back([&]() {
auto res_it = kv->new_read_iterator();
ASSERT(res_it.is_ok());
auto &it = res_it.get_value();
it.seek("5");
do {
/* read a key */
auto key = read_key(it);
LOG("Key (from thread2) = " + key);
} while (it.next() == pmem::kv::status::OK);
});
for (auto &th : threads)
th.join();
}

Member Typedef Documentation

◆ iterator_type

template<bool IsConst>
using pmem::kv::db::iterator< IsConst >::iterator_type = typename std::conditional<IsConst, pmemkv_iterator, pmemkv_write_iterator>::type
private

Constructor & Destructor Documentation

◆ iterator() [1/3]

template<bool IsConst>
pmem::kv::db::iterator< IsConst >::iterator ( iterator_type it)

◆ iterator() [2/3]

pmem::kv::db::iterator< true >::iterator ( iterator_type it)
inline

◆ iterator() [3/3]

pmem::kv::db::iterator< false >::iterator ( iterator_type it)
inline

Member Function Documentation

◆ abort() [1/2]

template<bool IsConst>
template<bool IC = IsConst>
std::enable_if<!IC>::type pmem::kv::db::iterator< IsConst >::abort ( )
noexcept

◆ abort() [2/2]

void pmem::kv::db::iterator< false >::abort ( )
inlinenoexcept

Aborts uncommitted modifications made on the current record.

◆ commit() [1/2]

template<bool IsConst>
template<bool IC = IsConst>
std::enable_if<!IC, status>::type pmem::kv::db::iterator< IsConst >::commit ( )
noexcept

◆ commit() [2/2]

status pmem::kv::db::iterator< false >::commit ( )
inlinenoexcept

Commits modifications made on the current record.

Calling this method is the only way to save modifications made by the iterator on the current record. You need to call this method before changing the iterator position, otherwise modifications will be automatically aborted.

Returns
pmem::kv::status

◆ get_raw_it() [1/3]

template<bool IsConst>
pmemkv_iterator* pmem::kv::db::iterator< IsConst >::get_raw_it ( )
private

◆ get_raw_it() [2/3]

pmemkv_iterator * pmem::kv::db::iterator< true >::get_raw_it ( )
inlineprivate

◆ get_raw_it() [3/3]

pmemkv_iterator * pmem::kv::db::iterator< false >::get_raw_it ( )
inlineprivate

◆ is_next()

template<bool IsConst>
status pmem::kv::db::iterator< IsConst >::is_next ( )
inlinenoexcept

Checks if there is a next record available.

If true is returned, it is guaranteed that iterator.next() will return status::OK, otherwise iterator is already on the last element and iterator.next() will return status::NOT_FOUND.

If the iterator is on an undefined position, calling this method is undefined behaviour.

Returns
bool

◆ key()

template<bool IsConst>
result< string_view > pmem::kv::db::iterator< IsConst >::key ( )
inlinenoexcept

Returns record's key (pmem::kv::string_view), in pmem::kv::result<pmem::kv::string_view>.

If the iterator is on an undefined position, calling this method is undefined behaviour.

Returns
pmem::kv::result<pmem::kv::string_view>

◆ next()

template<bool IsConst>
status pmem::kv::db::iterator< IsConst >::next ( )
inlinenoexcept

Changes iterator position to the next record.

If the next record exists, returns pmem::kv::status::OK, otherwise pmem::kv::status::NOT_FOUND is returned and the iterator position is undefined. Other possible return values are described in pmem::kv::status.

It internally aborts all changes made to an element previously pointed by the iterator.

If the iterator is on an undefined position, calling this method is undefined behaviour.

Returns
pmem::kv::status

◆ prev()

template<bool IsConst>
status pmem::kv::db::iterator< IsConst >::prev ( )
inlinenoexcept

Changes iterator position to the previous record.

If the previous record exists, returns pmem::kv::status::OK, otherwise pmem::kv::status::NOT_FOUND is returned and the iterator position is undefined. Other possible return values are described in pmem::kv::status.

It internally aborts all changes made to an element previously pointed by the iterator.

If the iterator is on an undefined position, calling this method is undefined behaviour.

Returns
pmem::kv::status

◆ read_range()

template<bool IsConst>
result< string_view > pmem::kv::db::iterator< IsConst >::read_range ( size_t  pos = 0,
size_t  n = std::numeric_limits<size_t>::max() 
)
inlinenoexcept

Returns value's range (pmem::kv::string_view) to read, in pmem::kv::result.

It is only used to read a value. If you want to modify the value, use db::iterator::write_range instead.

If the iterator is on an undefined position, calling this method is undefined behaviour.

Parameters
[in]posposition of the element in a value which will be the first element in the returned range (default = 0)
[in]nnumber of elements in range (default = std::numeric_limits<size_t>::max(), if n is bigger than the length of a value it's automatically shrinked)
Returns
pmem::kv::result<pmem::kv::string_view>

◆ seek()

template<bool IsConst>
status pmem::kv::db::iterator< IsConst >::seek ( string_view  key)
inlinenoexcept

Changes iterator position to the record with given key.

If the record is present and no errors occurred, returns pmem::kv::status::OK. If the record does not exist, pmem::kv::status::NOT_FOUND is returned and the iterator position is undefined. Other possible return values are described in pmem::kv::status.

It internally aborts all changes made to an element previously pointed by the iterator.

Parameters
[in]keykey that will be equal to the key of the record on the new iterator position
Returns
pmem::kv::status

◆ seek_higher()

template<bool IsConst>
status pmem::kv::db::iterator< IsConst >::seek_higher ( string_view  key)
inlinenoexcept

Changes iterator position to the record with key higher than given key.

If the record is present and no errors occurred, returns pmem::kv::status::OK. If the record does not exist, pmem::kv::status::NOT_FOUND is returned and the iterator position is undefined. Other possible return values are described in pmem::kv::status.

It internally aborts all changes made to an element previously pointed by the iterator.

Parameters
[in]keykey that will be lower than the key of the record on the new iterator position
Returns
pmem::kv::status

◆ seek_higher_eq()

template<bool IsConst>
status pmem::kv::db::iterator< IsConst >::seek_higher_eq ( string_view  key)
inlinenoexcept

Changes iterator position to the record with key equal or higher than given key.

If the record is present and no errors occurred, returns pmem::kv::status::OK. If the record does not exist, pmem::kv::status::NOT_FOUND is returned and the iterator position is undefined. Other possible return values are described in pmem::kv::status.

It internally aborts all changes made to an element previously pointed by the iterator.

Parameters
[in]keykey that will be equal or lower than the key of the record on the new iterator position
Returns
pmem::kv::status

◆ seek_lower()

template<bool IsConst>
status pmem::kv::db::iterator< IsConst >::seek_lower ( string_view  key)
inlinenoexcept

Changes iterator position to the record with key lower than given key.

If the record is present and no errors occurred, returns pmem::kv::status::OK. If the record does not exist, pmem::kv::status::NOT_FOUND is returned and the iterator position is undefined. Other possible return values are described in pmem::kv::status.

It internally aborts all changes made to an element previously pointed by the iterator.

Parameters
[in]keykey that will be higher than the key of the record on the new iterator position
Returns
pmem::kv::status

◆ seek_lower_eq()

template<bool IsConst>
status pmem::kv::db::iterator< IsConst >::seek_lower_eq ( string_view  key)
inlinenoexcept

Changes iterator position to the record with key equal or lower than given key.

If the record is present and no errors occurred, returns pmem::kv::status::OK. If the record does not exist, pmem::kv::status::NOT_FOUND is returned and the iterator position is undefined. Other possible return values are described in pmem::kv::status.

It internally aborts all changes made to an element previously pointed by the iterator.

Parameters
[in]keykey that will be equal or higher than the key of the record on the new iterator position
Returns
pmem::kv::status

◆ seek_to_first()

template<bool IsConst>
status pmem::kv::db::iterator< IsConst >::seek_to_first ( )
inlinenoexcept

Changes iterator position to the first record.

If db isn't empty, and no errors occurred, returns pmem::kv::status::OK. If db is empty, pmem::kv::status::NOT_FOUND is returned and the iterator position is undefined. Other possible return values are described in pmem::kv::status.

It internally aborts all changes made to an element previously pointed by the iterator.

Returns
pmem::kv::status

◆ seek_to_last()

template<bool IsConst>
status pmem::kv::db::iterator< IsConst >::seek_to_last ( )
inlinenoexcept

Changes iterator position to the last record.

If db isn't empty, and no errors occurred, returns pmem::kv::status::OK. If db is empty, pmem::kv::status::NOT_FOUND is returned and the iterator position is undefined. Other possible return values are described in pmem::kv::status.

It internally aborts all changes made to an element previously pointed by the iterator.

Returns
pmem::kv::status

◆ write_range() [1/2]

result< pmem::obj::slice< db::iterator< false >::OutputIterator< char > > > pmem::kv::db::iterator< false >::write_range ( size_t  pos,
size_t  n 
)
inlinenoexcept

Returns value's range (pmem::obj::slice<db::iterator::OutputIterator<char>>) to modify, in pmem::kv::result.

It is only used to modify a value. If you want to read the value, use db::iterator::read_range instead.

Changes made on a requested range are not persistent until db::iterator::commit is called.

If iterator is on an undefined position, calling this method is undefined behaviour.

Parameters
[in]posposition of the element in a value which will be the first element in the returned range (default = 0)
[in]nnumber of elements in range (default = std::numeric_limits<size_t>::max(), if n is bigger than the length of a value it's automatically shrinked)
Returns
pmem::kv::result<pmem::obj::slice<db::iterator::OutputIterator<char>>>

◆ write_range() [2/2]

template<bool IsConst>
template<bool IC = IsConst>
std::enable_if<!IC, result<pmem::obj::slice<OutputIterator<char> > > >::type pmem::kv::db::iterator< IsConst >::write_range ( size_t  pos = 0,
size_t  n = std::numeric_limits< size_t >::max() 
)
noexcept

Member Data Documentation

◆ it_

template<bool IsConst>
std::unique_ptr< iterator_type, typename std::conditional<IsConst, decltype(&pmemkv_iterator_delete), decltype(&pmemkv_write_iterator_delete)>::type> pmem::kv::db::iterator< IsConst >::it_
private

The documentation for this class was generated from the following file:
pmem::kv::db::iterator::seek_to_last
status seek_to_last() noexcept
Changes iterator position to the last record.
Definition: libpmemkv.hpp:953
pmem::kv::result
Stores result of an operation. It always contains status and optionally can contain value.
Definition: libpmemkv.hpp:175
pmem::kv::db::iterator
Iterator provides methods to iterate over records in db.
Definition: libpmemkv.hpp:626
pmem::kv::db::iterator::key
result< string_view > key() noexcept
Returns record's key (pmem::kv::string_view), in pmem::kv::result<pmem::kv::string_view>.
Definition: libpmemkv.hpp:1022
pmem::kv::db::iterator::next
status next() noexcept
Changes iterator position to the next record.
Definition: libpmemkv.hpp:988
pmem::kv::status
status
Status returned by most of pmemkv functions.
Definition: libpmemkv.hpp:84
pmem::kv::db::iterator::seek
status seek(string_view key) noexcept
Changes iterator position to the record with given key.
Definition: libpmemkv.hpp:838
pmem::kv::result::is_ok
bool is_ok() const noexcept
Checks if the result contains value (status == status::OK).
Definition: libpmemkv.hpp:328
pmem::kv::db::iterator::prev
status prev() noexcept
Changes iterator position to the previous record.
Definition: libpmemkv.hpp:1007
pmem::kv::db::iterator::read_range
result< string_view > read_range(size_t pos=0, size_t n=std::numeric_limits< size_t >::max()) noexcept
Returns value's range (pmem::kv::string_view) to read, in pmem::kv::result.
Definition: libpmemkv.hpp:1051
pmem::kv::result::get_value
const T & get_value() const &
Returns const reference to value from the result.
Definition: libpmemkv.hpp:343
pmem::kv::db::iterator::seek_to_first
status seek_to_first() noexcept
Changes iterator position to the first record.
Definition: libpmemkv.hpp:936