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. 16 class BlobstoreClient::impl { 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 BlobstoreClient()25BlobstoreClient::BlobstoreClient() : impl(new class BlobstoreClient::impl) {} 26 27 // Upload a new blob and return a blobid that serves as a handle to the blob. put(MultiBuf & buf) const28uint64_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. tag(uint64_t blobid,rust::Str tag) const50void BlobstoreClient::tag(uint64_t blobid, rust::Str tag) const { 51 impl->blobs[blobid].tags.emplace(tag); 52 } 53 54 // Retrieve metadata about a blob. metadata(uint64_t blobid) const55BlobMetadata 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(); 60 std::for_each(blob->second.tags.cbegin(), blob->second.tags.cend(), 61 [&](auto &t) { metadata.tags.emplace_back(t); }); 62 } 63 return metadata; 64 } 65 new_blobstore_client()66std::unique_ptr<BlobstoreClient> new_blobstore_client() { 67 return std::make_unique<BlobstoreClient>(); 68 } 69 70 } // namespace blobstore 71 } // namespace org 72