51 #define CONF_OBJECTSTORE_MIN_REPLICATION_FACTOR "OBJECTSTORE/min_replication_factor" 52 #define CONF_OBJECTSTORE_REPLICAS "OBJECTSTORE/replicas" 53 #define CONF_OBJECTSTORE_PERSISTED "OBJECTSTORE/persisted" 54 #define CONF_OBJECTSTORE_LOGGED "OBJECTSTORE/logged" 64 virtual std::tuple<version_t,uint64_t>
put(
const Object&
object) = 0;
70 virtual std::tuple<version_t,uint64_t>
remove(
const OID& oid) = 0;
101 virtual std::tuple<version_t,uint64_t> orderedPut(
const Object&
object) = 0;
107 virtual std::tuple<version_t,uint64_t> orderedRemove(
const OID& oid) = 0;
114 virtual const Object orderedGet(
const OID& oid) = 0;
142 virtual std::tuple<version_t,uint64_t>
put(
const Object&
object) {
145 decltype(results)::ReplyMap& replies = results.get();
148 for(
auto& reply_pair : replies) {
149 vRet = reply_pair.second.get();
154 virtual std::tuple<version_t,uint64_t>
remove(
const OID& oid) {
155 auto& subgroup_handle =
group->template get_subgroup<VolatileUnloggedObjectStore>();
157 decltype(results)::ReplyMap& replies = results.get();
160 for(
auto& reply_pair : replies) {
161 vRet = reply_pair.second.get();
169 dbg_default_info(
"{}:{} does not support versioned query ( oid = {}; ver = 0x{:x} ). Return with an invalid object.",
170 typeid(*this).name(), __func__, oid, ver);
174 auto& subgroup_handle =
group->template get_subgroup<VolatileUnloggedObjectStore>();
176 decltype(results)::ReplyMap& replies = results.get();
179 return replies.begin()->second.get();
183 dbg_default_info(
"{}:{} does not support temporal query (oid = {}; timestamp = {} us). Return with an invalid object.",
184 typeid(*this).name(), __func__, oid, ts_us);
191 std::tuple<version_t,uint64_t> version = get_version();
192 dbg_default_info(
"orderedPut object:{},version:0x{:x},timestamp:{}",
object.oid, std::get<0>(version), std::get<1>(version));
193 this->objects.erase(
object.oid);
194 object.ver = version;
195 this->objects.emplace(
object.oid,
object);
198 object_watcher(
object.oid,
object);
204 auto version = get_version();
205 dbg_default_info(
"orderedRemove object:{},version:0x{:x},timestamp:{}", oid, std::get<0>(version), std::get<1>(version));
206 if(this->objects.erase(oid)) {
207 object_watcher(oid, inv_obj);
213 auto version = get_version();
214 dbg_default_info(
"orderedGet object:{},version:0x{:x},timestamp:{}", oid, std::get<0>(version), std::get<1>(version));
215 if(objects.find(oid) != objects.end()) {
216 return objects.at(oid);
218 return this->inv_obj;
229 auto ptr_to_objects = mutils::from_bytes<decltype(objects)>(dsm, buf);
230 auto ptr_to_return = std::make_unique<VolatileUnloggedObjectStore>(std::move(*ptr_to_objects),
232 ptr_to_objects.release();
233 return ptr_to_return;
249 #define DEFAULT_DELTA_BUFFER_CAPACITY (4096) 259 inline void setOpid(
_OPID opid) {
260 assert(buffer !=
nullptr);
261 assert(capacity >=
sizeof(uint32_t));
262 *(
_OPID*)buffer = opid;
264 inline void setDataLen(
const size_t& dlen) {
265 assert(capacity >= (dlen +
sizeof(uint32_t)));
266 this->len = dlen +
sizeof(uint32_t);
268 inline char* dataPtr() {
269 assert(buffer !=
nullptr);
270 assert(capacity >
sizeof(uint32_t));
271 return buffer +
sizeof(uint32_t);
273 inline void calibrate(
const size_t& dlen) {
274 size_t new_cap = dlen +
sizeof(uint32_t);
275 if(this->capacity >= new_cap) {
279 int width =
sizeof(size_t) << 3;
280 int right_shift_bits = 1;
282 while(right_shift_bits < width) {
283 new_cap |= new_cap >> right_shift_bits;
284 right_shift_bits = right_shift_bits << 1;
288 this->buffer = (
char*)realloc(buffer, new_cap);
289 if(this->buffer ==
nullptr) {
290 dbg_default_crit(
"{}:{} Failed to allocate delta buffer. errno={}", __FILE__, __LINE__, errno);
293 this->capacity = new_cap;
296 inline bool isEmpty() {
297 return (this->len == 0);
299 inline void clean() {
302 inline void destroy() {
303 if(this->capacity > 0) {
311 if(delta.buffer ==
nullptr) {
312 dbg_default_crit(
"{}:{} Failed to allocate delta buffer. errno={}", __FILE__, __LINE__, errno);
335 df(this->delta.buffer, this->delta.len);
340 const char* data = (delta +
sizeof(
const uint32_t));
341 switch(*(
const uint32_t*)delta) {
343 applyOrderedPut(*mutils::from_bytes<Object>(
nullptr, data));
346 applyOrderedRemove(*(
const OID*)data);
349 std::cerr << __FILE__ <<
":" << __LINE__ <<
":" << __func__ <<
" " << std::endl;
361 return std::make_unique<DeltaObjectStoreCore>((
ObjectWatcher){});
366 this->objects.erase(
object.oid);
367 this->objects.emplace(
object.oid,
object);
370 object_watcher(
object.oid,
object);
376 if(this->objects.erase(oid)) {
379 object_watcher(oid, inv_obj);
389 assert(this->delta.isEmpty());
391 object.to_bytes(this->delta.dataPtr());
393 this->delta.setOpid(PUT);
395 applyOrderedPut(
object);
401 assert(this->delta.isEmpty());
402 this->delta.calibrate(
sizeof(
OID));
403 *(
OID*)this->delta.dataPtr() = oid;
404 this->delta.setDataLen(
sizeof(
OID));
405 this->delta.setOpid(REMOVE);
407 return applyOrderedRemove(oid);
411 if(objects.find(oid) != objects.end()) {
412 return objects.at(oid);
414 return this->inv_obj;
429 return std::make_unique<DeltaObjectStoreCore>(
435 return std::make_unique<DeltaObjectStoreCore>(
455 if(delta.buffer !=
nullptr) {
484 auto& subgroup_handle =
group->template get_subgroup<PersistentLoggedObjectStore>();
485 object.ver = subgroup_handle.get_next_version();
486 dbg_default_info(
"orderedPut object:{},version:0x{:x},timestamp:{}",
object.oid, std::get<0>(
object.ver), std::get<1>(
object.ver));
487 this->persistent_objectstore->orderedPut(
object);
492 auto& subgroup_handle =
group->template get_subgroup<PersistentLoggedObjectStore>();
493 std::tuple<version_t,uint64_t> vRet = subgroup_handle.get_next_version();
494 dbg_default_info(
"orderedRemove object:{},version:0x{:x},timestamp:{}", oid, std::get<0>(vRet), std::get<1>(vRet));
495 this->persistent_objectstore->orderedRemove(oid);
501 auto& subgroup_handle =
group->template get_subgroup<PersistentLoggedObjectStore>();
502 auto version = subgroup_handle.get_next_version();
503 dbg_default_info(
"orderedGet object:{},version:0x{:x},timestamp:{}", oid, std::get<0>(version), std::get<1>(version));
505 return this->persistent_objectstore->orderedGet(oid);
508 virtual std::tuple<version_t,uint64_t>
put(
const Object&
object) {
509 auto& subgroup_handle =
group->template get_subgroup<PersistentLoggedObjectStore>();
510 auto results = subgroup_handle.ordered_send<
RPC_NAME(orderedPut)>(object);
511 decltype(results)::ReplyMap& replies = results.get();
513 for(
auto& reply_pair : replies) {
514 vRet = reply_pair.second.get();
519 virtual std::tuple<version_t,uint64_t>
remove(
const OID& oid) {
520 auto& subgroup_handle =
group->template get_subgroup<PersistentLoggedObjectStore>();
522 decltype(results)::ReplyMap& replies = results.get();
524 for(
auto& reply_pair : replies) {
525 vRet = reply_pair.second.get();
532 auto& subgroup_handle =
group->template get_subgroup<PersistentLoggedObjectStore>();
535 decltype(results)::ReplyMap& replies = results.get();
538 return replies.begin()->second.get();
542 if(ver > lv || ver < 0) {
543 dbg_default_info(
"{}::{} failed with invalid version ( oid={}, ver = 0x{:x}, latest_version=0x{:x}), returning an invalid object.",
544 typeid(*this).name(), __func__, oid, ver, lv);
555 return persistent_objectstore[ver]->objects.at(oid);
556 }
catch(std::out_of_range& ex) {
564 const HLC hlc(ts_us,0ull);
566 return persistent_objectstore.
get(hlc)->objects.at(oid);
567 }
catch (
const int64_t &ex) {
568 dbg_default_warn(
"temporal query throws exception:0x{:x}. oid={}, ts={}", ex, oid, ts_us);
570 dbg_default_warn(
"temporal query throws unknown exception. oid={}, ts={}", oid, ts_us);
585 auto ptr_to_persistent_objectstore = mutils::from_bytes<decltype(persistent_objectstore)>(dsm, buf);
586 auto ptr_to_return = std::make_unique<PersistentLoggedObjectStore>(std::move(*ptr_to_persistent_objectstore));
587 ptr_to_persistent_objectstore.release();
588 return ptr_to_return;
617 static std::vector<node_id_t> parseReplicaList(
618 const std::string& replica_str) {
619 std::string::size_type s = 0, e;
620 std::vector<node_id_t> replicas;
621 while(s < replica_str.size()) {
622 e = replica_str.find(
',', s);
623 if(e == std::string::npos) {
624 e = replica_str.size();
627 std::string range = replica_str.substr(s, e - s);
628 std::string::size_type hyphen_pos = range.find(
'-');
629 if(hyphen_pos != std::string::npos) {
631 node_id_t rsid = std::stol(range.substr(0, hyphen_pos));
632 node_id_t reid = std::stol(range.substr(hyphen_pos + 1));
633 while(rsid <= reid) {
634 replicas.push_back(rsid);
638 replicas.push_back((
node_id_t)std::stol(range));
670 bReplica(
std::find(replicas.begin(), replicas.end(),
678 [
this](
const std::vector<std::type_index>& subgroup_type_order,
679 const std::unique_ptr<derecho::View>& prev_view,
682 for(
const auto& subgroup_type : subgroup_type_order) {
684 std::vector<node_id_t> active_replicas;
685 for(uint32_t i = 0; i < curr_view.members.size(); i++) {
686 const node_id_t id = curr_view.members[i];
687 if(!curr_view.failed[i] && std::find(replicas.begin(), replicas.end(), id) != replicas.end()) {
688 active_replicas.push_back(
id);
696 subgroup_vector[0].emplace_back(curr_view.make_subview(active_replicas));
697 curr_view.next_unassigned_rank += active_replicas.size();
698 subgroup_allocation.emplace(subgroup_type, std::move(subgroup_vector));
703 return subgroup_allocation;
706 std::vector<derecho::view_upcall_t>{},
711 if(mode == PERSISTENT_UNLOGGED || mode == VOLATILE_LOGGED) {
722 template <
typename T>
724 std::lock_guard<std::mutex> guard(write_mutex);
725 if(bReplica && !force_client) {
728 return std::move(os_rpc_handle.template ordered_send<
RPC_NAME(orderedPut)>(
object));
731 node_id_t target = replicas[myid % replicas.size()];
733 return std::move(os_p2p_handle.template p2p_send<
RPC_NAME(
put)>(target,
object));
737 template <
typename T>
738 std::tuple<version_t,uint64_t>
_bio_put(
const Object&
object,
const bool& force_client) {
740 decltype(results)::ReplyMap& replies = results.
get();
743 for(
auto& reply_pair : replies) {
744 vRet = reply_pair.second.get();
750 virtual std::tuple<version_t,uint64_t>
bio_put(
const Object&
object,
const bool& force_client) {
751 dbg_default_debug(
"bio_put object id={}, mode={}, force_client={}",
object.oid, mode, force_client);
754 case VOLATILE_UNLOGGED:
755 vRet = this->
template _bio_put<VolatileUnloggedObjectStore>(object, force_client);
757 case PERSISTENT_LOGGED:
758 vRet = this->
template _bio_put<PersistentLoggedObjectStore>(object, force_client);
768 dbg_default_debug(
"aio_put object id={}, mode={}, force_client={}",
object.oid, mode, force_client);
770 case VOLATILE_UNLOGGED:
771 return this->
template _aio_put<VolatileUnloggedObjectStore>(object, force_client);
772 case PERSISTENT_LOGGED:
773 return this->
template _aio_put<PersistentLoggedObjectStore>(object, force_client);
780 template <
typename T>
782 std::lock_guard<std::mutex> guard(write_mutex);
783 if(bReplica && !force_client) {
786 return std::move(os_rpc_handle.template ordered_send<
RPC_NAME(orderedRemove)>(oid));
789 node_id_t target = replicas[myid % replicas.size()];
791 return std::move(os_p2p_handle.template p2p_send<
RPC_NAME(
remove)>(target, oid));
795 template <
typename T>
796 std::tuple<version_t,uint64_t>
_bio_remove(
const OID& oid,
const bool& force_client) {
798 decltype(results)::ReplyMap& replies = results.
get();
801 for(
auto& reply_pair : replies) {
802 vRet = reply_pair.second.get();
808 virtual std::tuple<version_t,uint64_t>
bio_remove(
const OID& oid,
const bool& force_client) {
809 dbg_default_debug(
"bio_remove object id={}, mode={}, force_client={}", oid, mode, force_client);
811 case VOLATILE_UNLOGGED:
812 return this->
template _bio_remove<VolatileUnloggedObjectStore>(oid, force_client);
813 case PERSISTENT_LOGGED:
814 return this->
template _bio_remove<PersistentLoggedObjectStore>(oid, force_client);
823 dbg_default_debug(
"aio_remove object id={}, mode={}, force_client={}", oid, mode, force_client);
825 case VOLATILE_UNLOGGED:
826 return this->
template _aio_remove<VolatileUnloggedObjectStore>(oid, force_client);
827 case PERSISTENT_LOGGED:
828 return this->
template _aio_remove<PersistentLoggedObjectStore>(oid, force_client);
836 template <
typename T>
838 std::lock_guard<std::mutex> guard(write_mutex);
839 if(bReplica && !force_client) {
843 return std::move(os_rpc_handle.template ordered_send<
RPC_NAME(orderedGet)>(oid));
846 return std::move(os_rpc_handle.template p2p_send<
RPC_NAME(
get)>(myid, oid, ver));
850 node_id_t target = replicas[myid % replicas.size()];
852 return std::move(os_p2p_handle.template p2p_send<
RPC_NAME(
get)>(target, oid, ver));
856 template <
typename T>
858 std::lock_guard<std::mutex> guard(write_mutex);
862 return std::move(os_rpc_handle.template p2p_send<
RPC_NAME(
get_by_time)>(myid, oid, ts_us));
865 node_id_t target = replicas[myid % replicas.size()];
867 return std::move(os_p2p_handle.template p2p_send<
RPC_NAME(
get_by_time)>(target, oid, ts_us));
871 template <
typename T>
874 decltype(results)::ReplyMap& replies = results.
get();
876 return replies.begin()->second.get();
879 template <
typename T>
882 decltype(results)::ReplyMap& replies = results.
get();
883 return replies.begin()->second.get();
887 dbg_default_debug(
"bio_get object id={}, ver={}, mode={}, force_client={}", oid, ver, mode, force_client);
889 case VOLATILE_UNLOGGED:
890 return this->
template _bio_get<VolatileUnloggedObjectStore>(oid, ver, force_client);
891 case PERSISTENT_LOGGED:
892 return this->
template _bio_get<PersistentLoggedObjectStore>(oid, ver, force_client);
902 case VOLATILE_UNLOGGED:
903 return this->
template _bio_get<VolatileUnloggedObjectStore>(oid, ts_us);
904 case PERSISTENT_LOGGED:
905 return this->
template _bio_get<PersistentLoggedObjectStore>(oid, ts_us);
913 dbg_default_debug(
"aio_get object id={}, ver={}, mode={}, force_client={}", oid, ver, mode, force_client);
915 case VOLATILE_UNLOGGED:
916 return this->
template _aio_get<VolatileUnloggedObjectStore>(oid, ver, force_client);
917 case PERSISTENT_LOGGED:
918 return this->
template _aio_get<PersistentLoggedObjectStore>(oid, ver, force_client);
928 case VOLATILE_UNLOGGED:
929 return this->
template _aio_get<VolatileUnloggedObjectStore>(oid, ts_us);
930 case PERSISTENT_LOGGED:
931 return this->
template _aio_get<PersistentLoggedObjectStore>(oid, ts_us);
938 virtual void leave(
bool group_shutdown) {
942 group.
leave(group_shutdown);
946 return this->object_watcher;
960 if(IObjectStoreService::singleton.
get() ==
nullptr) {
964 IObjectStoreService::singleton = std::make_shared<ObjectStoreService>(ow);
967 return *IObjectStoreService::singleton.get();
std::map< OID, Object > objects
virtual const ObjectWatcher & getObjectWatcher()=0
derecho::rpc::QueryResults< const Object > _aio_get(const OID &oid, const version_t &ver, const bool &force_client)
virtual derecho::rpc::QueryResults< const Object > aio_get(const OID &oid, const version_t &ver, const bool &force_client)
virtual void leave(bool group_shutdown)
virtual std::tuple< version_t, uint64_t > bio_put(const Object &object, const bool &force_client)
void barrier_sync()
Waits until all members of the group have called this function.
The top-level object for creating a Derecho group.
std::enable_if_t< std::is_base_of< ByteRepresentable CMA T >::value, std::unique_ptr< T > > from_bytes(DeserializationManager *ctx, char const *v)
Calls T::from_bytes(ctx,v) when T is a ByteRepresentable.
DeltaObjectStoreCore(const std::map< OID, Object > &_objects, const ObjectWatcher &ow)
virtual derecho::rpc::QueryResults< std::tuple< version_t, uint64_t > > aio_put(const Object &object, const bool &force_client)
static IObjectStoreService & getObjectStoreService(int argc, char **argv, const ObjectWatcher &ow={})
virtual const Object get_by_time(const OID &oid, const uint64_t &ts_us)
void applyOrderedPut(const Object &object)
const ObjectWatcher object_watcher
virtual ~DeltaObjectStoreCore()
virtual std::tuple< version_t, uint64_t > orderedPut(const Object &object)
std::vector< std::vector< SubView > > subgroup_shard_layout_t
The data structure used to store a subgroups-and-shards layout for a single subgroup type (i...
derecho::rpc::QueryResults< std::tuple< version_t, uint64_t > > _aio_remove(const OID &oid, const bool &force_client)
const std::string & getConfString(const std::string &key)
std::map< OID, Object > objects
virtual int64_t getLatestVersion() noexcept(false)
get the lastest version excluding truncated ones.
persistent::version_t version_t
#define CONF_OBJECTSTORE_REPLICAS
DeltaObjectStoreCore(const ObjectWatcher &ow)
void ensure_registered(mutils::DeserializationManager &)
static std::unique_ptr< DeltaObjectStoreCore > create(mutils::DeserializationManager *dm)
const ObjectWatcher & object_watcher
ExternalCaller< SubgroupType > & get_nonmember_subgroup(uint32_t subgroup_index=0)
Gets the "handle" for a subgroup of the specified type and index, assuming this node is not a member ...
virtual Object bio_get(const OID &oid, const version_t &ver, const bool &force_client)
void leave(bool group_shutdown=true)
Causes this node to cleanly leave the group by setting itself to "failed.".
const ObjectWatcher object_watcher
const uint32_t getConfUInt32(const std::string &key)
VolatileUnloggedObjectStore(const std::map< OID, Object > &_objects, const ObjectWatcher &ow)
virtual const Object orderedGet(const OID &oid)
derecho::Group< VolatileUnloggedObjectStore, PersistentLoggedObjectStore > group
virtual void finalizeCurrentDelta(const DeltaFinalizer &df)
std::tuple< version_t, uint64_t > get_version()
#define dbg_default_debug(...)
#define DEFAULT_DESERIALIZE_NOALLOC(Name)
#define dbg_default_error(...)
std::tuple< version_t, uint64_t > _bio_remove(const OID &oid, const bool &force_client)
std::tuple< version_t, uint64_t > _bio_put(const Object &object, const bool &force_client)
std::function< void(char const *const, std::size_t)> DeltaFinalizer
A non-POD type which wishes to mark itself byte representable should extend this class.
auto bytes_size(const T &)
Just calls sizeof(T)
An exception that indicates that a subgroup membership function was unable to finish executing becaus...
std::map< std::type_index, subgroup_shard_layout_t > subgroup_allocation_map_t
The data structure used to store the subgroups-and-shards layouts for all subgroup types in a Group (...
virtual std::tuple< version_t, uint64_t > orderedRemove(const OID &oid)
virtual void applyDelta(char const *const delta)
PersistentLoggedObjectStore(persistent::PersistentRegistry *pr, IObjectStoreService &oss)
#define DEFAULT_DELTA_BUFFER_CAPACITY
static void initialize(int argc, char *argv[], const char *conf_file=nullptr)
static std::unique_ptr< DeltaObjectStoreCore > from_bytes(mutils::DeserializationManager *dsm, char const *buf)
virtual const Object get_by_time(const OID &oid, const uint64_t &ts_us)
The manager for any RemoteDeserializationContexts.
virtual std::tuple< version_t, uint64_t > put(const Object &object)=0
virtual const Object get_by_time(const OID &oid, const uint64_t &ts_us)=0
PersistentLoggedObjectStore(Persistent< DeltaObjectStoreCore > &&_persistent_objectstore)
#define DEFAULT_SERIALIZE(...)
VolatileUnloggedObjectStore(const ObjectWatcher &ow)
derecho::rpc::QueryResults< const Object > _aio_get(const OID &oid, const uint64_t &ts_us)
T & mgr()
Lookup the context registered at this DeserializationManager whose type is T.
static std::unique_ptr< PersistentLoggedObjectStore > from_bytes(mutils::DeserializationManager *dsm, char const *buf)
void ensure_registered(mutils::DeserializationManager &)
#define CONF_OBJECTSTORE_MIN_REPLICATION_FACTOR
Object _bio_get(const OID &oid, const uint64_t &ts_us)
virtual std::tuple< version_t, uint64_t > put(const Object &object)
virtual std::tuple< version_t, uint64_t > bio_remove(const OID &oid, const bool &force_client)
virtual const Object orderedGet(const OID &oid)
std::function< void(const OID &, const Object &)> ObjectWatcher
#define RPC_NAME(...)
This macro generates the Derecho-registered name of an RPC function, for use in the template paramete...
virtual const bool isReplica()
This is a marker interface for user-defined Replicated Objects (i.e.
virtual derecho::rpc::QueryResults< const Object > aio_get(const OID &oid, const uint64_t &ts_us)
virtual std::tuple< persistent::version_t, uint64_t > get_next_version()
Get the next version to be handled.
virtual bool orderedPut(const Object &object)
#define dbg_default_crit(...)
virtual Object bio_get(const OID &oid, const uint64_t &ts_us)
uint32_t node_id_t
Type alias for Node IDs in a Derecho group.
VolatileUnloggedObjectStore(std::map< OID, Object > &&_objects, const ObjectWatcher &ow)
const bool getConfBoolean(const std::string &key)
PersistentRegistry pr(nullptr, typeid(ReplicatedT), 123, 321)
ObjectStoreService(const ObjectWatcher &ow)
static std::shared_ptr< IObjectStoreService > singleton
virtual const Object orderedGet(const OID &oid)
virtual std::tuple< version_t, uint64_t > put(const Object &object)
void ensure_registered(mutils::DeserializationManager &)
#define dbg_default_info(...)
virtual const ObjectWatcher & getObjectWatcher()
std::vector< node_id_t > replicas
DeltaObjectStoreCore(std::map< OID, Object > &&_objects, const ObjectWatcher &ow)
#define CONF_DERECHO_LOCAL_ID
derecho::rpc::QueryResults< std::tuple< version_t, uint64_t > > _aio_put(const Object &object, const bool &force_client)
Object _bio_get(const OID &oid, const version_t &ver, const bool &force_client)
#define CONF_OBJECTSTORE_LOGGED
bool applyOrderedRemove(const OID &oid)
virtual std::tuple< version_t, uint64_t > orderedPut(const Object &object)
Data structure that (indirectly) holds a set of futures for a single RPC function call; there is one ...
ReplyMap & get()
Block until the ReplyMap is fulfilled, then return the map by reference.
auto ordered_send(Args &&... args)
Sends a multicast to the entire subgroup that replicates this Replicated<T>, invoking the RPC functio...
Base exception class for all exceptions raised by Derecho.
auto get(const Func &fun, mutils::DeserializationManager *dm=nullptr) noexcept(false)
get the latest Value of T.
const uint64_t getConfUInt64(const std::string &key)
virtual bool orderedRemove(const OID &oid)
#define CONF_OBJECTSTORE_PERSISTED
Persistent< DeltaObjectStoreCore > persistent_objectstore
static std::unique_ptr< VolatileUnloggedObjectStore > from_bytes(mutils::DeserializationManager *dsm, char const *buf)
virtual derecho::rpc::QueryResults< std::tuple< version_t, uint64_t > > aio_remove(const OID &oid, const bool &force_client)
PersistentRegistry is a book for all the Persistent<T> or Volatile<T> variables.
virtual std::tuple< version_t, uint64_t > orderedRemove(const OID &oid)
#define REGISTER_RPC_FUNCTIONS(...)
This macro automatically generates a register_functions() method for a Derecho Replicated Object...
#define dbg_default_warn(...)