зеркало из https://github.com/microsoft/CCF.git
145 строки
4.0 KiB
C++
145 строки
4.0 KiB
C++
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// Licensed under the Apache 2.0 License.
|
|
#pragma once
|
|
|
|
#include "ccf/kv/unit.h"
|
|
#include "ccf/kv/untyped_map_handle.h"
|
|
|
|
namespace ccf::kv
|
|
{
|
|
/** Grants read access to a @c ccf::kv::Value, as part of a @c ccf::kv::Tx.
|
|
*/
|
|
template <typename V, typename VSerialiser, typename Unit>
|
|
class ReadableValueHandle
|
|
{
|
|
protected:
|
|
ccf::kv::untyped::MapHandle& read_handle;
|
|
|
|
public:
|
|
using ValueType = V;
|
|
|
|
ReadableValueHandle(ccf::kv::untyped::MapHandle& uh) : read_handle(uh) {}
|
|
|
|
/** Get the stored value.
|
|
*
|
|
* This will return nullopt of the value has never been set, or has been
|
|
* removed.
|
|
*
|
|
* @return Optional containing associated value, or empty if the value
|
|
* doesn't exist
|
|
*/
|
|
std::optional<V> get()
|
|
{
|
|
const auto opt_v_rep = read_handle.get(Unit::get());
|
|
|
|
if (opt_v_rep.has_value())
|
|
{
|
|
return VSerialiser::from_serialised(*opt_v_rep);
|
|
}
|
|
|
|
return std::nullopt;
|
|
}
|
|
|
|
/** Get globally committed value, which has been replicated and
|
|
* acknowledged by consensus protocol.
|
|
*
|
|
* @return Optional containing associated value, or empty if the value
|
|
* doesn't exist in globally committed state
|
|
*/
|
|
std::optional<V> get_globally_committed()
|
|
{
|
|
const auto opt_v_rep = read_handle.get_globally_committed(Unit::get());
|
|
|
|
if (opt_v_rep.has_value())
|
|
{
|
|
return VSerialiser::from_serialised(*opt_v_rep);
|
|
}
|
|
|
|
return std::nullopt;
|
|
}
|
|
|
|
/** Test if value is defined.
|
|
*
|
|
* This is equivalent to `get().has_value()`, but is more efficient as it
|
|
* doesn't need to deserialise the value.
|
|
*
|
|
* @return Boolean true iff value is defined
|
|
*/
|
|
bool has()
|
|
{
|
|
return read_handle.has(Unit::get());
|
|
}
|
|
|
|
/** Get version when this value was last written to, by a previous
|
|
* transaction.
|
|
*
|
|
* @see ccf::kv::ReadableMapHandle::get_version_of_previous_write
|
|
*
|
|
* @return Optional containing version of applied transaction which last
|
|
* wrote to this value, or nullopt if such a version does not exist
|
|
*/
|
|
std::optional<Version> get_version_of_previous_write()
|
|
{
|
|
return read_handle.get_version_of_previous_write(Unit::get());
|
|
}
|
|
};
|
|
|
|
/** Grants write access to a @c ccf::kv::Value, as part of a @c ccf::kv::Tx.
|
|
*/
|
|
template <typename V, typename VSerialiser, typename Unit>
|
|
class WriteableValueHandle
|
|
{
|
|
protected:
|
|
ccf::kv::untyped::MapHandle& write_handle;
|
|
|
|
public:
|
|
WriteableValueHandle(ccf::kv::untyped::MapHandle& uh) : write_handle(uh) {}
|
|
|
|
/** Modify this value.
|
|
*
|
|
* If this value was previously defined, it will be overwritten. Even if the
|
|
* previous value was identical, this produces a serialised write in the
|
|
* ledger.
|
|
*
|
|
* @param value New entry to assign to this Value
|
|
*/
|
|
void put(const V& value)
|
|
{
|
|
write_handle.put(Unit::get(), VSerialiser::to_serialised(value));
|
|
}
|
|
|
|
/** Delete this value, restoring its original undefined state.
|
|
*/
|
|
void clear()
|
|
{
|
|
write_handle.clear();
|
|
}
|
|
};
|
|
|
|
/** Grants read and write access to a @c ccf::kv::Value, as part of a @c
|
|
* ccf::kv::Tx.
|
|
*
|
|
* @see ccf::kv::ReadableValueHandle
|
|
* @see ccf::kv::WriteableValueHandle
|
|
*/
|
|
template <typename V, typename VSerialiser, typename Unit>
|
|
class ValueHandle : public AbstractHandle,
|
|
public ReadableValueHandle<V, VSerialiser, Unit>,
|
|
public WriteableValueHandle<V, VSerialiser, Unit>
|
|
{
|
|
protected:
|
|
ccf::kv::untyped::MapHandle untyped_handle;
|
|
|
|
using ReadableBase = ReadableValueHandle<V, VSerialiser, Unit>;
|
|
using WriteableBase = WriteableValueHandle<V, VSerialiser, Unit>;
|
|
|
|
public:
|
|
ValueHandle(
|
|
ccf::kv::untyped::ChangeSet& changes, const std::string& map_name) :
|
|
ReadableBase(untyped_handle),
|
|
WriteableBase(untyped_handle),
|
|
untyped_handle(changes, map_name)
|
|
{}
|
|
};
|
|
}
|