fork of https://github.com/oxigraph/rocksdb and https://github.com/facebook/rocksdb for nextgraph and oxigraph
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.5 KiB
90 lines
2.5 KiB
// Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
|
|
// This source code is licensed under both the GPLv2 (found in the
|
|
// COPYING file in the root directory) and Apache 2.0 License
|
|
// (found in the LICENSE.Apache file in the root directory).
|
|
|
|
#pragma once
|
|
|
|
#ifndef ROCKSDB_LITE
|
|
|
|
#include <functional>
|
|
#include <memory>
|
|
#include <regex>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "rocksdb/env.h"
|
|
|
|
namespace rocksdb {
|
|
|
|
// Creates a new T using the factory function that was registered with a pattern
|
|
// that matches the provided "target" string according to std::regex_match.
|
|
//
|
|
// If no registered functions match, returns nullptr. If multiple functions
|
|
// match, the factory function used is unspecified.
|
|
//
|
|
// Populates res_guard with result pointer if caller is granted ownership.
|
|
template <typename T>
|
|
T* NewCustomObject(const std::string& target, std::unique_ptr<T>* res_guard);
|
|
|
|
// Returns a new T when called with a string. Populates the unique_ptr argument
|
|
// if granting ownership to caller.
|
|
template <typename T>
|
|
using FactoryFunc = std::function<T*(const std::string&, std::unique_ptr<T>*)>;
|
|
|
|
// To register a factory function for a type T, initialize a Registrar<T> object
|
|
// with static storage duration. For example:
|
|
//
|
|
// static Registrar<Env> hdfs_reg("hdfs://.*", &CreateHdfsEnv);
|
|
//
|
|
// Then, calling NewCustomObject<Env>("hdfs://some_path", ...) will match the
|
|
// regex provided above, so it returns the result of invoking CreateHdfsEnv.
|
|
template <typename T>
|
|
class Registrar {
|
|
public:
|
|
explicit Registrar(std::string pattern, FactoryFunc<T> factory);
|
|
};
|
|
|
|
// Implementation details follow.
|
|
|
|
namespace internal {
|
|
|
|
template <typename T>
|
|
struct RegistryEntry {
|
|
std::regex pattern;
|
|
FactoryFunc<T> factory;
|
|
};
|
|
|
|
template <typename T>
|
|
struct Registry {
|
|
static Registry* Get() {
|
|
static Registry<T> instance;
|
|
return &instance;
|
|
}
|
|
std::vector<RegistryEntry<T>> entries;
|
|
|
|
private:
|
|
Registry() = default;
|
|
};
|
|
|
|
} // namespace internal
|
|
|
|
template <typename T>
|
|
T* NewCustomObject(const std::string& target, std::unique_ptr<T>* res_guard) {
|
|
res_guard->reset();
|
|
for (const auto& entry : internal::Registry<T>::Get()->entries) {
|
|
if (std::regex_match(target, entry.pattern)) {
|
|
return entry.factory(target, res_guard);
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
template <typename T>
|
|
Registrar<T>::Registrar(std::string pattern, FactoryFunc<T> factory) {
|
|
internal::Registry<T>::Get()->entries.emplace_back(internal::RegistryEntry<T>{
|
|
std::regex(std::move(pattern)), std::move(factory)});
|
|
}
|
|
|
|
} // namespace rocksdb
|
|
#endif // ROCKSDB_LITE
|
|
|