Copy-on-write Tuples

Copy-on-write (COW) tuples make passing values around cheap while also making sure that the system copies the actual data only when necessary.

CAF uses copy-on-write for its message type, which basically is a type-erased tuple. This allows actors to send the same message to multiple recipients (usually by sending it to publish/subscribe group) without storing the content in memory multiple times. CAF also includes cow_tuple which is a std::tuple-like type to wrap potentially expensive data (like strings and lists) into a single unit that actors can pass around cheaply.

Here is a small example to illustrate the API:

Source Code

auto xs = caf::make_cow_tuple(1, 2, 3);
auto ys = xs;
println("After initializing:");
println("xs: ", xs, " (", std::addressof(xs.data()), ")");
println("ys: ", ys, " (", std::addressof(ys.data()), ")");
ys.unshared() = std::tuple{10, 20, 30};
println("After assigning to ys:");
println("xs: ", xs, " (", std::addressof(xs.data()), ")");
println("ys: ", ys, " (", std::addressof(ys.data()), ")");

Output

After initializing:
xs: [1, 2, 3] (0x7fb091405ae0)
ys: [1, 2, 3] (0x7fb091405ae0)
After assigning to ys:
xs: [1, 2, 3] (0x7fb091405ae0)
ys: [10, 20, 30] (0x7fb091405b00)

By default, cow_tuple only grants const access to its elements. With get<I>(xs), users can get access to a single value of xs at the index I. With xs.data(), users get a const reference to the internally stored std::tuple.

In order to gain mutable access, users may call unshared() to get a mutable reference to the std::tuple. This function makes a deep copy of the data if there is more than one reference to the data at the moment. In our example above, ys initially points to the same data as xs. After calling unshared() on ys, however, the two tuples point to different data.

Previous
Previous

Message Builders

Next
Next

JSON Serialization