|
19 | 19 | #include "bucket_logger.h" |
20 | 20 | #include "collections/collections_constants.h" |
21 | 21 | #include "collections/collections_types.h" |
| 22 | +#include "collections/manifest_generated.h" |
22 | 23 | #include "ep_engine.h" |
23 | 24 | #include "kv_bucket.h" |
24 | 25 | #include "statistics/collector.h" |
@@ -301,6 +302,85 @@ nlohmann::json Manifest::toJson( |
301 | 302 | return manifest; |
302 | 303 | } |
303 | 304 |
|
| 305 | +flatbuffers::DetachedBuffer Manifest::toFlatbuffer() const { |
| 306 | + flatbuffers::FlatBufferBuilder builder; |
| 307 | + std::vector<flatbuffers::Offset<Collections::Persist::Scope>> fbScopes; |
| 308 | + |
| 309 | + for (const auto& scope : scopes) { |
| 310 | + std::vector<flatbuffers::Offset<Collections::Persist::Collection>> |
| 311 | + fbCollections; |
| 312 | + |
| 313 | + for (const auto& c : scope.second.collections) { |
| 314 | + auto newEntry = Collections::Persist::CreateCollection( |
| 315 | + builder, |
| 316 | + uint32_t(c.id), |
| 317 | + c.maxTtl.has_value(), |
| 318 | + c.maxTtl.value_or(std::chrono::seconds(0)).count(), |
| 319 | + builder.CreateString(collections.at(c.id).name.data(), |
| 320 | + collections.at(c.id).name.size())); |
| 321 | + fbCollections.push_back(newEntry); |
| 322 | + } |
| 323 | + auto collectionVector = builder.CreateVector(fbCollections); |
| 324 | + |
| 325 | + auto newEntry = Collections::Persist::CreateScope( |
| 326 | + builder, |
| 327 | + scope.first, |
| 328 | + builder.CreateString(scope.second.name.data(), |
| 329 | + scope.second.name.size()), |
| 330 | + collectionVector); |
| 331 | + fbScopes.push_back(newEntry); |
| 332 | + } |
| 333 | + |
| 334 | + auto scopeVector = builder.CreateVector(fbScopes); |
| 335 | + auto toWrite = |
| 336 | + Collections::Persist::CreateManifest(builder, uid, scopeVector); |
| 337 | + builder.Finish(toWrite); |
| 338 | + return builder.Release(); |
| 339 | +} |
| 340 | + |
| 341 | +// sibling of toFlatbuffer, construct a Manifest from a flatbuffer format |
| 342 | +Manifest::Manifest(std::string_view flatbufferData, Manifest::FlatBuffers tag) |
| 343 | + : defaultCollectionExists(false), scopes(), collections(), uid(0) { |
| 344 | + flatbuffers::Verifier v( |
| 345 | + reinterpret_cast<const uint8_t*>(flatbufferData.data()), |
| 346 | + flatbufferData.size()); |
| 347 | + if (!v.VerifyBuffer<Collections::Persist::Manifest>(nullptr)) { |
| 348 | + std::stringstream ss; |
| 349 | + ss << "Collections::Manifest::Manifest(FlatBuffers): flatbufferData " |
| 350 | + "invalid, ptr:" |
| 351 | + << reinterpret_cast<const void*>(flatbufferData.data()) |
| 352 | + << ", size:" << flatbufferData.size(); |
| 353 | + |
| 354 | + throw std::invalid_argument(ss.str()); |
| 355 | + } |
| 356 | + |
| 357 | + auto manifest = flatbuffers::GetRoot<Collections::Persist::Manifest>( |
| 358 | + reinterpret_cast<const uint8_t*>(flatbufferData.data())); |
| 359 | + |
| 360 | + uid = manifest->uid(); |
| 361 | + for (const Collections::Persist::Scope* scope : *manifest->scopes()) { |
| 362 | + std::vector<CollectionEntry> scopeCollections; |
| 363 | + |
| 364 | + for (const Collections::Persist::Collection* collection : |
| 365 | + *scope->collections()) { |
| 366 | + cb::ExpiryLimit maxTtl; |
| 367 | + CollectionID cid(collection->collectionId()); |
| 368 | + if (collection->ttlValid()) { |
| 369 | + maxTtl = std::chrono::seconds(collection->maxTtl()); |
| 370 | + } |
| 371 | + this->collections.emplace(std::make_pair( |
| 372 | + cid, |
| 373 | + Collection{scope->scopeId(), collection->name()->str()})); |
| 374 | + enableDefaultCollection(cid); |
| 375 | + scopeCollections.push_back({cid, maxTtl}); |
| 376 | + } |
| 377 | + |
| 378 | + this->scopes.emplace( |
| 379 | + scope->scopeId(), |
| 380 | + Scope{scope->name()->str(), std::move(scopeCollections)}); |
| 381 | + } |
| 382 | +} |
| 383 | + |
304 | 384 | void Manifest::addCollectionStats(KVBucket& bucket, |
305 | 385 | const void* cookie, |
306 | 386 | const AddStatFn& add_stat) const { |
|
0 commit comments