]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/include/rocksdb/utilities/object_registry.h
import 14.2.4 nautilus point release
[ceph.git] / ceph / src / rocksdb / include / rocksdb / utilities / object_registry.h
CommitLineData
7c673cae 1// Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
11fdf7f2
TL
2// This source code is licensed under both the GPLv2 (found in the
3// COPYING file in the root directory) and Apache 2.0 License
4// (found in the LICENSE.Apache file in the root directory).
7c673cae
FG
5
6#pragma once
7
8#ifndef ROCKSDB_LITE
9
10#include <functional>
11#include <memory>
12#include <regex>
13#include <string>
14#include <vector>
15
16#include "rocksdb/env.h"
17
18namespace rocksdb {
19
20// Creates a new T using the factory function that was registered with a pattern
21// that matches the provided "target" string according to std::regex_match.
22//
23// If no registered functions match, returns nullptr. If multiple functions
24// match, the factory function used is unspecified.
25//
26// Populates res_guard with result pointer if caller is granted ownership.
27template <typename T>
28T* NewCustomObject(const std::string& target, std::unique_ptr<T>* res_guard);
29
494da23a
TL
30// Returns a new T when called with a string. Populates the std::unique_ptr
31// argument if granting ownership to caller.
7c673cae
FG
32template <typename T>
33using FactoryFunc = std::function<T*(const std::string&, std::unique_ptr<T>*)>;
34
35// To register a factory function for a type T, initialize a Registrar<T> object
36// with static storage duration. For example:
37//
38// static Registrar<Env> hdfs_reg("hdfs://.*", &CreateHdfsEnv);
39//
40// Then, calling NewCustomObject<Env>("hdfs://some_path", ...) will match the
41// regex provided above, so it returns the result of invoking CreateHdfsEnv.
42template <typename T>
43class Registrar {
44 public:
45 explicit Registrar(std::string pattern, FactoryFunc<T> factory);
46};
47
48// Implementation details follow.
49
50namespace internal {
51
52template <typename T>
53struct RegistryEntry {
54 std::regex pattern;
55 FactoryFunc<T> factory;
56};
57
58template <typename T>
59struct Registry {
60 static Registry* Get() {
61 static Registry<T> instance;
62 return &instance;
63 }
64 std::vector<RegistryEntry<T>> entries;
65
66 private:
67 Registry() = default;
68};
69
70} // namespace internal
71
72template <typename T>
73T* NewCustomObject(const std::string& target, std::unique_ptr<T>* res_guard) {
74 res_guard->reset();
75 for (const auto& entry : internal::Registry<T>::Get()->entries) {
76 if (std::regex_match(target, entry.pattern)) {
77 return entry.factory(target, res_guard);
78 }
79 }
80 return nullptr;
81}
82
83template <typename T>
84Registrar<T>::Registrar(std::string pattern, FactoryFunc<T> factory) {
85 internal::Registry<T>::Get()->entries.emplace_back(internal::RegistryEntry<T>{
86 std::regex(std::move(pattern)), std::move(factory)});
87}
88
89} // namespace rocksdb
90#endif // ROCKSDB_LITE