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