| 276 | } |
| 277 | |
| 278 | BlockServicesCacheDB::BlockServicesCacheDB(Logger& logger, std::shared_ptr<XmonAgent>& xmon, const SharedRocksDB& sharedDB, Duration blockServiceWritableDelay) : |
| 279 | _env(logger, xmon, "bs_cache_db"), |
| 280 | _db(sharedDB.db()), |
| 281 | _blockServicesCF(sharedDB.getCF("blockServicesCache")), |
| 282 | _picker(15, blockServiceWritableDelay) |
| 283 | { |
| 284 | LOG_INFO(_env, "Initializing block services cache DB"); |
| 285 | |
| 286 | std::unique_lock _(_mutex); |
| 287 | |
| 288 | const auto keyExists = [this](rocksdb::ColumnFamilyHandle* cf, const rocksdb::Slice& key) -> bool { |
| 289 | std::string value; |
| 290 | auto status = _db->Get({}, cf, key, &value); |
| 291 | if (status.IsNotFound()) { |
| 292 | return false; |
| 293 | } else { |
| 294 | ROCKS_DB_CHECKED(status); |
| 295 | return true; |
| 296 | } |
| 297 | }; |
| 298 | |
| 299 | if (!keyExists(_blockServicesCF, blockServicesCacheKey(&CURRENT_BLOCK_SERVICES_KEY))) { |
| 300 | LOG_INFO(_env, "initializing current block services (as empty)"); |
| 301 | OwnedValue<CurrentBlockServicesBody> v(std::vector<BlockServiceInfoShort>{}); |
| 302 | ROCKS_DB_CHECKED(_db->Put({}, _blockServicesCF, blockServicesCacheKey(&CURRENT_BLOCK_SERVICES_KEY), v.toSlice())); |
| 303 | } else { |
| 304 | LOG_INFO(_env, "initializing block services cache (from db)"); |
| 305 | std::string buf; |
| 306 | { |
| 307 | rocksdb::ReadOptions options; |
| 308 | static_assert(sizeof(BlockServicesCacheKey) == sizeof(uint8_t)); |
| 309 | auto upperBound = (BlockServicesCacheKey)((uint8_t)BLOCK_SERVICE_KEY + 1); |
| 310 | auto upperBoundSlice = blockServicesCacheKey(&upperBound); |
| 311 | options.iterate_upper_bound = &upperBoundSlice; |
| 312 | std::unique_ptr<rocksdb::Iterator> it(_db->NewIterator(options, _blockServicesCF)); |
| 313 | StaticValue<BlockServiceKey> beginKey; |
| 314 | beginKey().setKey(BLOCK_SERVICE_KEY); |
| 315 | beginKey().setBlockServiceId(0); |
| 316 | for (it->Seek(beginKey.toSlice()); it->Valid(); it->Next()) { |
| 317 | auto k = ExternalValue<BlockServiceKey>::FromSlice(it->key()); |
| 318 | ALWAYS_ASSERT(k().key() == BLOCK_SERVICE_KEY); |
| 319 | auto v = ExternalValue<BlockServiceBody>::FromSlice(it->value()); |
| 320 | auto& cache = _blockServices[k().blockServiceId()]; |
| 321 | cache.addrs[0].ip = v().ip1(); |
| 322 | cache.addrs[0].port = v().port1(); |
| 323 | cache.addrs[1].ip = v().ip2(); |
| 324 | cache.addrs[1].port = v().port2(); |
| 325 | expandKey(v().secretKey(), cache.secretKey); |
| 326 | cache.storageClass = v().storageClass(); |
| 327 | cache.flags = v().flags(); |
| 328 | cache.failureDomain = v().failureDomain(); |
| 329 | |
| 330 | if (v().version() >= 2) { |
| 331 | cache.locationId = v().locationId(); |
| 332 | cache.capacityBytes = v().capacityBytes(); |
| 333 | cache.availableBytes = v().availableBytes(); |
| 334 | cache.blocks = v().blocks(); |
| 335 | cache.firstSeen = TernTime(v().firstSeen()); |
nothing calls this directly
no test coverage detected