/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include "glean/rts/ownership/uset.h" #include "glean/storage/common.h" #include "glean/storage/stats.h" #include "glean/lmdb/container-impl.h" #include "glean/lmdb/glean_lmdb.h" #include "glean/lmdb/util.h" namespace facebook { namespace glean { namespace lmdb { namespace impl { using namespace facebook::glean::db; struct DatabaseImpl final : DatabaseCommon { int64_t db_version; Id starting_id; Id next_id; AtomicPredicateStats stats_; explicit DatabaseImpl( ContainerImpl c, Id start, rts::UsetId first_unit_id, int64_t version); DatabaseImpl(const DatabaseImpl&) = delete; DatabaseImpl& operator=(const DatabaseImpl&) = delete; DatabaseImpl(DatabaseImpl&&) = delete; DatabaseImpl& operator=(DatabaseImpl&&) = delete; Container& container() noexcept override { return container_; } void commit(rts::FactSet& facts) override; /// Lookup implementation Id idByKey(Pid type, folly::ByteRange key) override; Pid typeById(Id id) override; bool factById(Id id, std::function f) override; rts::Id startingId() const override { return starting_id; } rts::Id firstFreeId() const override { return next_id; } rts::Interval count(Pid pid) const override { return stats_.count(pid); } std::unique_ptr enumerate(Id from, Id upto) override; std::unique_ptr enumerateBack(Id from, Id downto) override; std::unique_ptr seek( Pid type, folly::ByteRange prefix, std::optional restart) override; std::unique_ptr seekWithinSection( Pid type, folly::ByteRange prefix, Id from, Id upto, std::optional restart) override; /// stats rts::PredicateStats loadStats(); rts::PredicateStats predicateStats() const override { return stats_.get(); } bool lookupById(Txn& txn, Id id, folly::ByteRange& val); // returned memory is valid until txn is finished /// Ownership (most of this is in common.h) OwnershipStats getOwnershipStats() override; }; extern const char* admin_names[]; template folly::Optional readAdminValue(ContainerImpl& container_, AdminId id) { container_.requireOpen(); folly::ByteRange val; binary::Output key; key.fixed(id); auto txn = container_.txn_read(); if (txn.get(container_.family(Family::admin), key.bytes(), val)) { binary::Input value(val); auto result = value.fixed(); if (!value.empty()) { rts::error( "corrupt database - invalid {}", admin_names[static_cast(id)]); } return result; } else { return {}; }; } } // namespace impl } // namespace lmdb } // namespace glean } // namespace facebook