Skip to content

Commit f9e9bb8

Browse files
authored
bytes copy-on-write (#491)
Signed-off-by: turuslan <[email protected]>
1 parent 595195e commit f9e9bb8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+254
-170
lines changed

core/cbor_blake/ipld.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,23 @@
88
#include <memory>
99

1010
#include "cbor_blake/cid.hpp"
11+
#include "common/bytes_cow.hpp"
1112

1213
namespace fc {
1314
struct CbIpld {
1415
virtual ~CbIpld() = default;
1516
virtual bool get(const CbCid &key, Bytes *value) const = 0;
16-
virtual void put(const CbCid &key, BytesIn value) = 0;
17+
virtual void put(const CbCid &key, BytesCow &&value) = 0;
1718

1819
bool has(const CbCid &key) const {
1920
return get(key, nullptr);
2021
}
2122
bool get(const CbCid &key, Bytes &value) const {
2223
return get(key, &value);
2324
}
24-
CbCid put(BytesIn cbor) {
25+
CbCid put(BytesCow &&cbor) {
2526
auto key{CbCid::hash(cbor)};
26-
put(key, cbor);
27+
put(key, std::move(cbor));
2728
return key;
2829
}
2930
};

core/cbor_blake/ipld_any.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ namespace fc {
2222
}
2323
return false;
2424
}
25-
outcome::result<void> set(const CID &key, Value value) override {
25+
outcome::result<void> set(const CID &key, BytesCow &&value) override {
2626
auto cid{asBlake(key)};
2727
assert(cid);
28-
ipld->put(*cid, value);
28+
ipld->put(*cid, std::move(value));
2929
return outcome::success();
3030
}
3131
outcome::result<Value> get(const CID &key) const override {
@@ -62,8 +62,8 @@ namespace fc {
6262
bool get(const CbCid &key, Bytes *value) const override {
6363
return get(ipld, key, value);
6464
}
65-
void put(const CbCid &key, BytesIn value) override {
66-
ipld->set(CID{key}, copy(value)).value();
65+
void put(const CbCid &key, BytesCow &&value) override {
66+
ipld->set(CID{key}, std::move(value)).value();
6767
}
6868
};
6969
} // namespace fc

core/cbor_blake/ipld_version.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ namespace fc {
1717
outcome::result<bool> contains(const CID &key) const override {
1818
return ipld->contains(key);
1919
}
20-
outcome::result<void> set(const CID &key, Value value) override {
21-
return ipld->set(key, value);
20+
outcome::result<void> set(const CID &key, BytesCow &&value) override {
21+
return ipld->set(key, std::move(value));
2222
}
2323
outcome::result<Value> get(const CID &key) const override {
2424
return ipld->get(key);

core/cbor_blake/memory.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ namespace fc {
2525
}
2626
return false;
2727
}
28-
void put(const CbCid &key, BytesIn value) override {
29-
map.emplace(key, copy(value));
28+
void put(const CbCid &key, BytesCow &&value) override {
29+
map.emplace(key, value.into());
3030
}
3131
};
3232
} // namespace fc

core/common/bytes_cow.hpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#pragma once
7+
8+
#include <variant>
9+
10+
#include "common/bytes.hpp"
11+
12+
namespace fc {
13+
class BytesCow {
14+
private:
15+
std::variant<BytesIn, Bytes> variant;
16+
17+
public:
18+
BytesCow() = default;
19+
// NOLINTNEXTLINE(google-explicit-constructor)
20+
BytesCow(Bytes &&vector) : variant{std::move(vector)} {}
21+
BytesCow(const Bytes &) = delete;
22+
// NOLINTNEXTLINE(google-explicit-constructor)
23+
BytesCow(const BytesIn &span) : variant{span} {}
24+
BytesCow(const BytesCow &) = delete;
25+
BytesCow(BytesCow &&) = default;
26+
BytesCow &operator=(const BytesCow &) = delete;
27+
BytesCow &operator=(BytesCow &&) = default;
28+
~BytesCow() = default;
29+
30+
bool owned() const {
31+
return variant.index() == 1;
32+
}
33+
34+
BytesIn span() const {
35+
if (!owned()) {
36+
return std::get<BytesIn>(variant);
37+
}
38+
return BytesIn{std::get<Bytes>(variant)};
39+
}
40+
41+
// NOLINTNEXTLINE(google-explicit-constructor)
42+
operator BytesIn() const {
43+
return span();
44+
}
45+
46+
size_t size() const {
47+
return span().size();
48+
}
49+
50+
// get mutable vector reference, copy once if span
51+
Bytes &mut() {
52+
if (!owned()) {
53+
variant.emplace<Bytes>(copy(std::get<BytesIn>(variant)));
54+
}
55+
return std::get<Bytes>(variant);
56+
}
57+
58+
// move vector away, copy once if span
59+
Bytes into() {
60+
auto vector{std::move(mut())};
61+
variant.emplace<BytesIn>();
62+
return vector;
63+
}
64+
};
65+
66+
inline void copy(Bytes &l, BytesCow &&r) {
67+
copy(l, BytesIn{r});
68+
}
69+
} // namespace fc

core/markets/discovery/impl/discovery_impl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace fc::markets::discovery {
2828
}
2929
peers.push_back(peer);
3030
OUTCOME_TRY(peers_cbored, codec::cbor::encode(peers));
31-
OUTCOME_TRY(datastore_->put(cid_key, peers_cbored));
31+
OUTCOME_TRY(datastore_->put(cid_key, std::move(peers_cbored)));
3232
return outcome::success();
3333
}
3434

core/markets/storage/client/import_manager/import_manager.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ namespace fc::markets::storage::client::import_manager {
8888
outcome::result<void> ImportManager::addImported(
8989
const CID &root, const boost::filesystem::path &path) {
9090
OUTCOME_TRY(key, root.toBytes());
91-
return imported_->put(key, copy(common::span::cbytes(path.string())));
91+
return imported_->put(key, common::span::cbytes(path.string()));
9292
}
9393

9494
} // namespace fc::markets::storage::client::import_manager

core/markets/storage/provider/impl/stored_ask.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ namespace fc::markets::storage::provider {
7878

7979
outcome::result<void> StoredAsk::saveSignedAsk(const SignedStorageAsk &ask) {
8080
OUTCOME_TRY(cbored_ask, codec::cbor::encode(ask));
81-
OUTCOME_TRY(datastore_->put(kBestAskKey, cbored_ask));
81+
OUTCOME_TRY(datastore_->put(kBestAskKey, std::move(cbored_ask)));
8282
last_signed_storage_ask_ = ask;
8383
return outcome::success();
8484
}

core/miner/main/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ namespace fc {
446446
auto markets_ipld{std::make_shared<storage::ipfs::LeveldbDatastore>(
447447
prefixed("markets_ipld/"))};
448448
auto gs_sub{graphsync->subscribe([&](auto &, auto &data) {
449-
OUTCOME_EXCEPT(markets_ipld->set(data.cid, data.content));
449+
OUTCOME_EXCEPT(markets_ipld->set(data.cid, BytesIn{data.content}));
450450
})};
451451
auto stored_ask{std::make_shared<markets::storage::provider::StoredAsk>(
452452
prefixed("stored_ask/"), napi, *config.actor)};

core/node/main/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ namespace fc {
267267
auto &o = obj_res.value();
268268

269269
auto gs_sub{o.graphsync->subscribe([&](auto &, auto &data) {
270-
o.markets_ipld->set(data.cid, data.content).value();
270+
o.markets_ipld->set(data.cid, BytesIn{data.content}).value();
271271
})};
272272

273273
auto mpool_gossip{o.events->subscribeMessageFromPubSub([&](auto &e) {

0 commit comments

Comments
 (0)