Google OR-Tools v9.15
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
solver_interface_mock.cc
Go to the documentation of this file.
1// Copyright 2010-2025 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
15
16#include <functional>
17#include <memory>
18
19#include "absl/log/check.h"
20#include "absl/log/die_if_null.h"
21#include "absl/log/log.h"
22#include "absl/random/random.h"
23#include "absl/synchronization/mutex.h"
27
28namespace operations_research {
29namespace math_opt {
30
31namespace {
32
33// Returns a random solver type.
34SolverTypeProto RandomSolverType() {
35 // Pick random values in [SolverType_MIN + 1, SolverType_MAX] and return the
36 // first valid one (using SolverType_MIN + 1 excludes
37 // SOLVER_TYPE_UNSPECIFIED).
38 //
39 // As of 2025-10-16 solver type values are dense so we should not loop.
40 constexpr int kNumAttempts = 1;
41 absl::BitGen gen;
42 for (int i = 0; i < kNumAttempts; ++i) {
44 const int choice =
45 absl::Uniform(absl::IntervalClosedClosed, gen,
46 // Excludes SOLVER_TYPE_UNSPECIFIED; see static_assert().
48 if (SolverTypeProto_IsValid(choice)) {
49 return static_cast<SolverTypeProto>(choice);
50 }
51 }
52 LOG(FATAL) << "Failed to pick a random SOLVER_TYPE after " << kNumAttempts
53 << " attempts.";
54}
55
56} // namespace
57
60 : caller_data_(std::make_shared<CallerData>(factory)),
61 solver_type_(RandomSolverType()) {
62 // We make a copy of the shared_ptr since we make a copy of the member field
63 // in the capture below. It must be an identifier.
64 const auto caller_data = caller_data_;
65
66 // We register a lambda that shares the same CallerData instance at this class
67 // using a shared_ptr. Note that here alternate_registry_ has been constructed
68 // and injected into AllSolversRegistry thus AllSolversRegistry::Instance() is
69 // a temporary and empty registry.
71 solver_type_, [caller_data](const ModelProto& model,
72 const SolverInterface::InitArgs& init_args) {
73 // We hold the lock during the call of the factory since we want to
74 // delay the destruction of the registration during the call to the
75 // factory (the factory may be invalid after the destruction).
76 absl::MutexLock lock(caller_data->mutex);
77 CHECK(caller_data->factory != nullptr)
78 << "Can't use this solver factory after the destruction of the "
79 "SolverFactoryRegistration!";
80 return caller_data->factory(model, init_args);
81 });
82}
83
85 absl::MutexLock lock(caller_data_->mutex);
86 caller_data_->factory = nullptr;
87}
88
89SolverFactoryRegistration::CallerData::CallerData(
91 : factory(ABSL_DIE_IF_NULL(factory)) {}
92
93} // namespace math_opt
94} // namespace operations_research
void Register(SolverTypeProto solver_type, SolverInterface::Factory factory)
static AllSolversRegistry *absl_nonnull Instance()
std::function< absl::StatusOr< std::unique_ptr< SolverInterface > >( const ModelProto &model, const InitArgs &init_args)> Factory
constexpr SolverTypeProto SolverTypeProto_MAX
constexpr SolverTypeProto SolverTypeProto_MIN
bool SolverTypeProto_IsValid(int value)
OR-Tools root namespace.
STL namespace.