Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any clonable object pool implementation in C or C++?

This may seem odd, but I'll try to rationalize it. I currently use boost.object_pool extensively in conjunction with shared_ptr, and recently I encountered a situation that I need to take snapshots of current program states, in order to make functionality like full-scale replay/rollback/fast-forward.

So I am not trying to clone a object pool to use elsewhere, that won't work obviously because even if I am allowed to do so by boost.pool's interface (which I am not), there will be no valid pointers pointing to chunks in that newly cloned pool and it would just be pointless. But my use case here is I want to "paste" it back into the original pool if there's replay/rollback needs.

I certainly can just copy and clone all states, objects, and sub-states, sub-objects and subsub... manually and then pack them into a snapshot, and hope everything will go right, but that is error-prone given the complexity the project has already got, and it's gotta be a lot slower than if I can just copy the memory directly. Using Command pattern (or the like) to achieve undo-redo is pretty out of the question as well because undo-redo mechanism is not my intention.

I was just wondering if I do the project from scratch again using a die-hard traditional-C way, and a simple memcpy(snapshot, all_states, size) call would do almost all the work.

Is there any other option I am still missing? Is there any boost.object_pool like implementation that allow you to clone the underlying memory area? Is intrusively hacking boost.object_pool a plausible option considering the situation?

like image 425
arch.jslin Avatar asked Nov 04 '22 11:11

arch.jslin


1 Answers

Not that I know of.

As you noted, the main issue here is the presence of possible inter-dependencies between the objects which requires updating the pointers as you make the copy. Certainly non-trivial.

I can think of two possible solutions:

  • Persistency
  • Serialization

Persistency is about never mutating existing state. When you change state, you thus create a new snapshot that refers to the old state except for the new bits. It's typically used in MVCC implementations of databases, for example, and is pervasive in the functional programming world. It's also a good way to get space leaks if you try and keep too many references. Finally, it requires a deep re-engineering.

Serialization is about persisting state, but in a different format. You dump your current state in serialization format (whether textual or binary), and you are able to recreate it by reading the serialized buffer. You can even apply a compression pass on the serialized buffer to spare some memory.

Since you are already using Boost, then be glad to learn that Boost.Serialization automatically handle graphs of objects (eh!) and I think already deals correctly with boost::shared_ptr. It might be your best option here.

like image 141
Matthieu M. Avatar answered Nov 11 '22 13:11

Matthieu M.