| David Tolnay | 4ca366f | 2020-11-10 20:55:31 -0800 | [diff] [blame] | 1 | #include "demo/include/blobstore.h" |
| 2 | #include "demo/src/main.rs.h" |
| 3 | #include <algorithm> |
| 4 | #include <functional> |
| 5 | #include <set> |
| 6 | #include <string> |
| 7 | #include <unordered_map> |
| 8 | |
| 9 | namespace org { |
| 10 | namespace blobstore { |
| 11 | |
| 12 | // Toy implementation of an in-memory blobstore. |
| 13 | // |
| 14 | // In reality the implementation of BlobstoreClient could be a large complex C++ |
| 15 | // library. |
| David Tolnay | cbc2a10 | 2020-11-11 09:58:01 -0800 | [diff] [blame] | 16 | class BlobstoreClient::impl { |
| David Tolnay | 4ca366f | 2020-11-10 20:55:31 -0800 | [diff] [blame] | 17 | friend BlobstoreClient; |
| 18 | using Blob = struct { |
| 19 | std::string data; |
| 20 | std::set<std::string> tags; |
| 21 | }; |
| 22 | std::unordered_map<uint64_t, Blob> blobs; |
| 23 | }; |
| 24 | |
| David Tolnay | e0d261b | 2020-11-11 09:58:34 -0800 | [diff] [blame] | 25 | BlobstoreClient::BlobstoreClient() : impl(new class BlobstoreClient::impl) {} |
| David Tolnay | 4ca366f | 2020-11-10 20:55:31 -0800 | [diff] [blame] | 26 | |
| 27 | // Upload a new blob and return a blobid that serves as a handle to the blob. |
| 28 | uint64_t BlobstoreClient::put(MultiBuf &buf) const { |
| 29 | std::string contents; |
| 30 | |
| 31 | // Traverse the caller's chunk iterator. |
| 32 | // |
| 33 | // In reality there might be sophisticated batching of chunks and/or parallel |
| 34 | // upload implemented by the blobstore's C++ client. |
| 35 | while (true) { |
| 36 | auto chunk = next_chunk(buf); |
| 37 | if (chunk.size() == 0) { |
| 38 | break; |
| 39 | } |
| 40 | contents.append(reinterpret_cast<const char *>(chunk.data()), chunk.size()); |
| 41 | } |
| 42 | |
| 43 | // Insert into map and provide caller the handle. |
| 44 | auto blobid = std::hash<std::string>{}(contents); |
| 45 | impl->blobs[blobid] = {std::move(contents), {}}; |
| 46 | return blobid; |
| 47 | } |
| 48 | |
| 49 | // Add tag to an existing blob. |
| 50 | void BlobstoreClient::tag(uint64_t blobid, rust::Str tag) const { |
| 51 | impl->blobs[blobid].tags.emplace(tag); |
| 52 | } |
| 53 | |
| 54 | // Retrieve metadata about a blob. |
| 55 | BlobMetadata BlobstoreClient::metadata(uint64_t blobid) const { |
| 56 | BlobMetadata metadata{}; |
| 57 | auto blob = impl->blobs.find(blobid); |
| 58 | if (blob != impl->blobs.end()) { |
| 59 | metadata.size = blob->second.data.size(); |
| David Tolnay | 4bf55ef | 2020-11-11 10:23:53 -0800 | [diff] [blame^] | 60 | std::for_each(blob->second.tags.cbegin(), blob->second.tags.cend(), |
| David Tolnay | 4ca366f | 2020-11-10 20:55:31 -0800 | [diff] [blame] | 61 | [&](auto &t) { metadata.tags.emplace_back(t); }); |
| 62 | } |
| 63 | return metadata; |
| 64 | } |
| 65 | |
| 66 | std::unique_ptr<BlobstoreClient> new_blobstore_client() { |
| 67 | return std::make_unique<BlobstoreClient>(); |
| 68 | } |
| 69 | |
| 70 | } // namespace blobstore |
| 71 | } // namespace org |