diff options
author | Billy Donahue <billy.donahue@mongodb.com> | 2019-09-04 13:44:43 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-09-04 13:44:43 +0000 |
commit | e58bc0f552112f5c1c16f8092b771f7e562316fb (patch) | |
tree | 2c267cf35b71aec89fe8df5ac0426afeed55be37 /src/third_party/s2 | |
parent | 0031fa41177db46789e411895a5bcd33b2847ed5 (diff) | |
download | mongo-e58bc0f552112f5c1c16f8092b771f7e562316fb.tar.gz |
SERVER-41648 remove mongo headers from s2 files.
Diffstat (limited to 'src/third_party/s2')
-rwxr-xr-x | src/third_party/s2/base/SConscript | 5 | ||||
-rwxr-xr-x | src/third_party/s2/base/logging.cc | 35 | ||||
-rwxr-xr-x | src/third_party/s2/base/logging.h | 99 | ||||
-rw-r--r-- | src/third_party/s2/base/logging_mongo.cc | 138 | ||||
-rw-r--r-- | src/third_party/s2/s2cellid.cc | 28 | ||||
-rw-r--r-- | src/third_party/s2/s2loop.cc | 16 | ||||
-rw-r--r-- | src/third_party/s2/s2polygon.cc | 11 | ||||
-rw-r--r-- | src/third_party/s2/s2polyline.cc | 7 | ||||
-rw-r--r-- | src/third_party/s2/s2regioncoverer.cc | 20 |
9 files changed, 249 insertions, 110 deletions
diff --git a/src/third_party/s2/base/SConscript b/src/third_party/s2/base/SConscript index 217cc864236..8e437001e0e 100755 --- a/src/third_party/s2/base/SConscript +++ b/src/third_party/s2/base/SConscript @@ -11,10 +11,11 @@ env.Library( [ "int128.cc", "logging.cc", + "logging_mongo.cc", "stringprintf.cc", "strtoint.cc", ], - LIBDEPS=[ - '$BUILD_DIR/mongo/base', + LIBDEPS_PRIVATE=[ + "$BUILD_DIR/mongo/base", ], ) diff --git a/src/third_party/s2/base/logging.cc b/src/third_party/s2/base/logging.cc index 238afb0eb6d..58d9cab0471 100755 --- a/src/third_party/s2/base/logging.cc +++ b/src/third_party/s2/base/logging.cc @@ -17,32 +17,19 @@ #include <utility> -#include "mongo/util/assert_util.h" -#include "mongo/util/log.h" -#include "mongo/util/str.h" +namespace s2_env { -using ::mongo::logger::LogstreamBuilder; +LoggingEnv::~LoggingEnv() = default; -LogMessageBase::LogMessageBase(LogstreamBuilder builder, const char* file, int line) : - _lsb(std::move(builder)) { - _lsb.setBaseMessage(::mongo::str::stream() << file << ':' << line << ": "); -} +LogMessageSink::~LogMessageSink() = default; -LogMessageBase::LogMessageBase(LogstreamBuilder builder) : _lsb(std::move(builder)) { } +LogMessage::LogMessage(int verbosity) + : _sink(globalLoggingEnv().makeSink(verbosity)) { } +LogMessage::LogMessage(Severity severity) + : _sink(globalLoggingEnv().makeSink(severity)) { } +LogMessage::LogMessage(Severity severity, const char* file, int line) + : _sink(globalLoggingEnv().makeSink(severity, file, line)) { } -LogMessageInfo::LogMessageInfo() : LogMessageBase(mongo::log()) { } +LogMessage::~LogMessage() = default; -LogMessageWarning::LogMessageWarning(const char* file, int line) : - LogMessageBase(mongo::warning(), file, line) { } - -LogMessageFatal::LogMessageFatal(const char* file, int line) : - LogMessageBase(mongo::severe(), file, line) { } - -#pragma warning(push) -// C4722: 'LogMessageFatal::~LogMessageFatal': destructor never returns, potential memory leak -#pragma warning(disable : 4722) -LogMessageFatal::~LogMessageFatal() { - _lsb.~LogstreamBuilder(); - fassertFailed(40048); -} -#pragma warning(pop) +} // namespace s2_env diff --git a/src/third_party/s2/base/logging.h b/src/third_party/s2/base/logging.h index 4f40312141b..8dd7bdf6765 100755 --- a/src/third_party/s2/base/logging.h +++ b/src/third_party/s2/base/logging.h @@ -14,17 +14,14 @@ #ifndef BASE_LOGGING_H #define BASE_LOGGING_H -#include <iosfwd> - -#include "mongo/logger/log_severity.h" -#include "mongo/logger/logger.h" -#include "mongo/logger/logstream_builder.h" -#include "mongo/util/concurrency/thread_name.h" +#include <iostream> +#include <sstream> +#include <memory> #include "macros.h" // Always-on checking -#define CHECK(x) if(x){}else LogMessageFatal(__FILE__, __LINE__).stream() << "Check failed: " #x +#define CHECK(x) if(x){}else FATAL << "Check failed: " #x #define CHECK_LT(x, y) CHECK((x) < (y)) #define CHECK_GT(x, y) CHECK((x) > (y)) #define CHECK_LE(x, y) CHECK((x) <= (y)) @@ -43,7 +40,7 @@ #define DCHECK_GE(val1, val2) CHECK_GE(val1, val2) #define DCHECK_GT(val1, val2) CHECK_GT(val1, val2) #else -#define DCHECK(x) if(x){}else LogMessageWarning(__FILE__, __LINE__).stream() << "Check failed: " #x +#define DCHECK(x) if(x){}else WARN << "Check failed: " #x #define DCHECK_LT(x, y) DCHECK((x) < (y)) #define DCHECK_GT(x, y) DCHECK((x) > (y)) #define DCHECK_LE(x, y) DCHECK((x) <= (y)) @@ -53,56 +50,76 @@ #endif #include "base/port.h" -#define INFO LogMessageInfo().stream() -#define WARN LogMessageWarning(__FILE__, __LINE__).stream() -#define FATAL LogMessageFatal(__FILE__, __LINE__).stream() -#define DFATAL LogMessageFatal(__FILE__, __LINE__).stream() +#define INFO s2_env::LogMessage(s2_env::LogMessage::Severity::kInfo).stream() +#define WARN s2_env::LogMessage(s2_env::LogMessage::Severity::kWarning, __FILE__, __LINE__).stream() +#define FATAL s2_env::LogMessage(s2_env::LogMessage::Severity::kFatal, __FILE__, __LINE__).stream() +#define DFATAL s2_env::LogMessage(s2_env::LogMessage::Severity::kFatal, __FILE__, __LINE__).stream() -// VLOG messages will be logged at debug level 5 with the S2 log component. #define S2LOG(x) x -// Expansion of MONGO_LOG_COMPONENT defined in mongo/util/log.h #define VLOG(x) \ - if (!(::mongo::logger::globalLogDomain())->shouldLog(::mongo::logger::LogComponent::kGeo, ::mongo::logger::LogSeverity::Debug(5))) {} \ - else ::mongo::logger::LogstreamBuilder(::mongo::logger::globalLogDomain(), ::mongo::getThreadName(), ::mongo::logger::LogSeverity::Debug(5), ::mongo::logger::LogComponent::kGeo) + if (s2_env::globalLoggingEnv().shouldVLog((int)x)) {} \ + else s2_env::LogMessage(int(x)).stream() + +namespace s2_env { -class LogMessageBase { +class LogMessageSink { public: - LogMessageBase(::mongo::logger::LogstreamBuilder builder); - LogMessageBase(::mongo::logger::LogstreamBuilder builder, const char* file, int line); - virtual ~LogMessageBase() { }; - std::ostream& stream() { return _lsb.stream(); } -protected: - // Fatal message will deconstruct it before abort to flush final message. - mongo::logger::LogstreamBuilder _lsb; -private: - DISALLOW_COPY_AND_ASSIGN(LogMessageBase); + virtual ~LogMessageSink(); + virtual std::ostream& stream() = 0; }; -class LogMessageInfo : public LogMessageBase { +class LogMessage { public: - LogMessageInfo(); - virtual ~LogMessageInfo() { }; + enum class Severity { + kInfo, + kWarning, + kFatal, + }; -private: - DISALLOW_COPY_AND_ASSIGN(LogMessageInfo); + explicit LogMessage(int verbosity); + explicit LogMessage(Severity severity); + explicit LogMessage(Severity severity, const char* file, int line); + + virtual ~LogMessage(); + + std::ostream& stream() { + return _sink->stream(); + } + +protected: + std::unique_ptr<LogMessageSink> _sink; }; -class LogMessageWarning : public LogMessageBase { +class StringStream { public: - LogMessageWarning(const char* file, int line); - virtual ~LogMessageWarning() { }; + StringStream() = default; + + template <typename T> + StringStream& operator<<(T&& t) { + _s << std::forward<T>(t); + return *this; + } + + operator std::string() const { + return _s.str(); + } private: - DISALLOW_COPY_AND_ASSIGN(LogMessageWarning); + std::ostringstream _s; }; -class LogMessageFatal : public LogMessageBase { +class LoggingEnv { public: - LogMessageFatal(const char* file, int line); - virtual ~LogMessageFatal(); - -private: - DISALLOW_COPY_AND_ASSIGN(LogMessageFatal); + virtual ~LoggingEnv(); + virtual bool shouldVLog(int verbosity) = 0; + virtual std::unique_ptr<LogMessageSink> makeSink(int verbosity) = 0; + virtual std::unique_ptr<LogMessageSink> makeSink(LogMessage::Severity severity) = 0; + virtual std::unique_ptr<LogMessageSink> makeSink(LogMessage::Severity severity, + const char* file, int line) = 0; }; +// provided by logging_mongo.cc +LoggingEnv& globalLoggingEnv(); + +} // namespace s2_env #endif // BASE_LOGGING_H diff --git a/src/third_party/s2/base/logging_mongo.cc b/src/third_party/s2/base/logging_mongo.cc new file mode 100644 index 00000000000..c9f73754dde --- /dev/null +++ b/src/third_party/s2/base/logging_mongo.cc @@ -0,0 +1,138 @@ +/** + * Copyright (C) 2019-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kGeo + +#include "logging.h" + +#include <boost/optional.hpp> +#include <utility> + +#include "mongo/logger/logger.h" +#include "mongo/logger/log_severity.h" +#include "mongo/logger/logstream_builder.h" +#include "mongo/util/assert_util.h" +#include "mongo/util/concurrency/thread_name.h" +#include "mongo/util/log.h" + +namespace s2_mongo { + +namespace ml = mongo::logger; + +// VLOG messages will be logged at debug level 5 with the S2 log component. +// Expansion of MONGO_LOG_COMPONENT defined in mongo/util/log.h +class VLogSink : public s2_env::LogMessageSink { +public: + explicit VLogSink(int verbosity) + : _v(verbosity), + _lsb(ml::globalLogDomain(), + mongo::getThreadName(), + ml::LogSeverity::Debug(5), + ml::LogComponent::kGeo) {} + std::ostream& stream() override { return _lsb.stream(); } +private: + int _v; + ml::LogstreamBuilder _lsb; +}; + +class SeverityLogSink : public s2_env::LogMessageSink { +public: + // Fatal message will deconstruct it before abort to flush final message. + explicit SeverityLogSink(s2_env::LogMessage::Severity severity, ml::LogstreamBuilder builder) + : _severity(severity), + _lsb(std::move(builder)) {} + + SeverityLogSink(s2_env::LogMessage::Severity severity, ml::LogstreamBuilder builder, + const char* file, int line) + : _severity(severity), + _lsb(std::move(builder)) { + std::ostringstream os; + os << file << ":" << line << ": "; + _lsb->setBaseMessage(os.str()); + } + ~SeverityLogSink() { + if (_severity == s2_env::LogMessage::Severity::kFatal) { + _lsb = {}; // killing _lsb early to force a log flush + fassertFailed(40048); + } + } + + std::ostream& stream() override { return _lsb->stream(); } +private: + s2_env::LogMessage::Severity _severity; + boost::optional<ml::LogstreamBuilder> _lsb; +}; + +template <typename...A> +std::unique_ptr<s2_env::LogMessageSink> makeSinkImpl(s2_env::LogMessage::Severity severity, A&&...a) { + auto builder = [&] { + switch (severity) { + case s2_env::LogMessage::Severity::kInfo: + return mongo::log(); + case s2_env::LogMessage::Severity::kWarning: + return mongo::warning(); + case s2_env::LogMessage::Severity::kFatal: + default: + return mongo::severe(); + } + }; + return std::make_unique<SeverityLogSink>(severity, builder(), std::forward<A>(a)...); +} + +class MongoLoggingEnv : public s2_env::LoggingEnv { +public: + MongoLoggingEnv() = default; + ~MongoLoggingEnv() override {} + bool shouldVLog(int verbosity) override { + return ml::globalLogDomain()->shouldLog( + ml::LogComponent::kGeo, + ml::LogSeverity::Debug(5)); + } + std::unique_ptr<s2_env::LogMessageSink> makeSink(int verbosity) override { + return std::make_unique<VLogSink>(verbosity); + } + std::unique_ptr<s2_env::LogMessageSink> makeSink(s2_env::LogMessage::Severity severity) override { + return makeSinkImpl(severity); + } + std::unique_ptr<s2_env::LogMessageSink> makeSink(s2_env::LogMessage::Severity severity, + const char* file, int line) override { + return makeSinkImpl(severity, file, line); + } +}; + +} // namespace s2_mongo + +namespace s2_env { + +LoggingEnv& globalLoggingEnv() { + static LoggingEnv *p = new s2_mongo::MongoLoggingEnv(); + return *p; +} + +} // namespace s2_env diff --git a/src/third_party/s2/s2cellid.cc b/src/third_party/s2/s2cellid.cc index 920725f72a0..2cc7969172f 100644 --- a/src/third_party/s2/s2cellid.cc +++ b/src/third_party/s2/s2cellid.cc @@ -15,6 +15,8 @@ using std::reverse; #include <iomanip> using std::setprecision; +#include <mutex> + #include <vector> using std::vector; @@ -27,8 +29,6 @@ using std::vector; #include "util/math/mathutil.h" #include "util/math/vector2-inl.h" -#include "mongo/base/init.h" - // The following lookup tables are used to convert efficiently between an // (i,j) cell index and the corresponding position along the Hilbert curve. // "lookup_pos" maps 4 bits of "i", 4 bits of "j", and 2 bits representing the @@ -88,16 +88,16 @@ static void InitLookupCell(int level, int i, int j, int orig_orientation, } } -static void Init() { - InitLookupCell(0, 0, 0, 0, 0, 0); - InitLookupCell(0, 0, 0, kSwapMask, 0, kSwapMask); - InitLookupCell(0, 0, 0, kInvertMask, 0, kInvertMask); - InitLookupCell(0, 0, 0, kSwapMask|kInvertMask, 0, kSwapMask|kInvertMask); -} - -MONGO_INITIALIZER(S2CellIdInit)(mongo::InitializerContext *context) { - Init(); - return mongo::Status::OK(); +// Modern s2geometry does this with std::call_once, so we will copy that technique. +// https://github.com/google/s2geometry/blob/bec06921d7/src/s2/s2cell_id.cc#L102 +static std::once_flag flag; +static void MaybeInit() { + std::call_once(flag, []{ + InitLookupCell(0, 0, 0, 0, 0, 0); + InitLookupCell(0, 0, 0, kSwapMask, 0, kSwapMask); + InitLookupCell(0, 0, 0, kInvertMask, 0, kInvertMask); + InitLookupCell(0, 0, 0, kSwapMask|kInvertMask, 0, kSwapMask|kInvertMask); + }); } int S2CellId::level() const { @@ -211,6 +211,8 @@ inline int S2CellId::STtoIJ(double s) { S2CellId S2CellId::FromFaceIJ(int face, int i, int j) { + MaybeInit(); + // Optimization notes: // - Non-overlapping bit fields can be combined with either "+" or "|". // Generally "+" seems to produce better code, but not always. @@ -270,6 +272,8 @@ S2CellId S2CellId::FromLatLng(S2LatLng const& ll) { } int S2CellId::ToFaceIJOrientation(int* pi, int* pj, int* orientation) const { + MaybeInit(); + int i = 0, j = 0; int face = this->face(); int bits = (face & kSwapMask); diff --git a/src/third_party/s2/s2loop.cc b/src/third_party/s2/s2loop.cc index d4087fab971..dc6c9b8a4d5 100644 --- a/src/third_party/s2/s2loop.cc +++ b/src/third_party/s2/s2loop.cc @@ -29,19 +29,16 @@ using std::make_pair; #include "s2cell.h" #include "s2edgeindex.h" -#include "mongo/util/str.h" -using mongo::str::stream; - static const unsigned char kCurrentEncodingVersionNumber = 1; namespace { - stream& operator<<(stream& strStream, const S1Angle& angle) { + s2_env::StringStream& operator<<(s2_env::StringStream& strStream, const S1Angle& angle) { std::stringstream ss; ss << angle; return strStream << ss.str(); } // Reverse the output order of Lat/Lng to Lng/Lat - stream& operator<<(stream& strStream, const S2LatLng& ll) { + s2_env::StringStream& operator<<(s2_env::StringStream& strStream, const S2LatLng& ll) { return strStream << "[" << ll.lng() << ", " << ll.lat() << "]"; } } @@ -118,7 +115,7 @@ bool S2Loop::IsValid(string* err) const { for (int i = 0; i < num_vertices(); ++i) { if (!S2::IsUnitLength(vertex(i))) { VLOG(2) << "Vertex " << i << " is not unit length"; - if (err) *err = stream() << "Vertex " << i << " is not unit length"; + if (err) *err = s2_env::StringStream() << "Vertex " << i << " is not unit length"; return false; } } @@ -127,7 +124,8 @@ bool S2Loop::IsValid(string* err) const { for (int i = 0; i < num_vertices(); ++i) { if (!vmap.insert(make_pair(vertex(i), i)).second) { VLOG(2) << "Duplicate vertices: " << vmap[vertex(i)] << " and " << i; - if (err) *err = stream() << "Duplicate vertices: " << vmap[vertex(i)] << " and " << i; + if (err) *err = s2_env::StringStream() << "Duplicate vertices: " << vmap[vertex(i)] + << " and " << i; return false; } } @@ -152,14 +150,14 @@ bool S2Loop::IsValid(string* err) const { if (crosses) { VLOG(2) << "Edges " << i << " and " << ai << " cross"; // additional debugging information, reverse Lat/Lng order. - string errDetail = stream() + string errDetail = s2_env::StringStream() << "Edge locations in degrees: " << S2LatLng(vertex(i)) << "-" << S2LatLng(vertex(i + 1)) << " and " << S2LatLng(vertex(ai)) << "-" << S2LatLng(vertex(ai + 1)); VLOG(2) << errDetail; if (NULL != err) { - *err = stream() + *err = s2_env::StringStream() << "Edges " << i << " and " << ai << " cross. " << errDetail; } break; diff --git a/src/third_party/s2/s2polygon.cc b/src/third_party/s2/s2polygon.cc index afd18467c63..3762ce8c659 100644 --- a/src/third_party/s2/s2polygon.cc +++ b/src/third_party/s2/s2polygon.cc @@ -29,9 +29,6 @@ using std::vector; #include "s2polygonbuilder.h" #include "s2polyline.h" -#include "mongo/util/str.h" -using mongo::str::stream; - static const unsigned char kCurrentEncodingVersionNumber = 1; typedef pair<S2Point, S2Point> S2Edge; @@ -134,7 +131,7 @@ bool S2Polygon::IsValid(const vector<S2Loop*>& loops, string* err) { VLOG(2) << "Duplicate edge: loop " << i << ", edge " << j << " and loop " << other.first << ", edge " << other.second; if (err) { - *err = stream() << "Duplicate edge: loop " << i << ", edge " << j + *err = s2_env::StringStream() << "Duplicate edge: loop " << i << ", edge " << j << " and loop " << other.first << ", edge " << other.second; } return false; @@ -147,7 +144,7 @@ bool S2Polygon::IsValid(const vector<S2Loop*>& loops, string* err) { for (size_t i = 0; i < loops.size(); ++i) { if (!loops[i]->IsNormalized()) { VLOG(2) << "Loop " << i << " encloses more than half the sphere"; - if (err) *err = stream() << "Loop " << i << " encloses more than half the sphere"; + if (err) *err = s2_env::StringStream() << "Loop " << i << " encloses more than half the sphere"; return false; } for (size_t j = i + 1; j < loops.size(); ++j) { @@ -155,7 +152,7 @@ bool S2Polygon::IsValid(const vector<S2Loop*>& loops, string* err) { // cases where the two boundaries cross at a shared vertex. if (loops[i]->ContainsOrCrosses(loops[j]) < 0) { VLOG(2) << "Loop " << i << " crosses loop " << j; - if (err) *err = stream() << "Loop " << i << " crosses loop " << j; + if (err) *err = s2_env::StringStream() << "Loop " << i << " crosses loop " << j; return false; } } @@ -1108,7 +1105,7 @@ bool S2Polygon::IsNormalized(string* err) const { } if (count > 1) { if (err) { - *err = stream() << "Loop " << i << " shares more than one vertex" + *err = s2_env::StringStream() << "Loop " << i << " shares more than one vertex" << " with its parent loop " << GetParent(i); } return false; diff --git a/src/third_party/s2/s2polyline.cc b/src/third_party/s2/s2polyline.cc index 08769555e4a..f23401e205b 100644 --- a/src/third_party/s2/s2polyline.cc +++ b/src/third_party/s2/s2polyline.cc @@ -18,9 +18,6 @@ using std::vector; #include "s2latlng.h" #include "s2edgeutil.h" -#include "mongo/util/str.h" -using mongo::str::stream; - static const unsigned char kCurrentEncodingVersionNumber = 1; S2Polyline::S2Polyline() @@ -80,7 +77,7 @@ bool S2Polyline::IsValid(vector<S2Point> const& v, string* err) { if (!S2::IsUnitLength(v[i])) { S2LOG(INFO) << "Vertex " << i << " is not unit length"; if (err) { - *err = stream() << "Vertex " << i << " is not unit length"; + *err = s2_env::StringStream() << "Vertex " << i << " is not unit length"; } return false; } @@ -92,7 +89,7 @@ bool S2Polyline::IsValid(vector<S2Point> const& v, string* err) { S2LOG(INFO) << "Vertices " << (i - 1) << " and " << i << " are identical or antipodal"; if (err) { - *err = stream() << "Vertices " << (i - 1) << " and " << i + *err = s2_env::StringStream() << "Vertices " << (i - 1) << " and " << i << " are identical or antipodal"; } return false; diff --git a/src/third_party/s2/s2regioncoverer.cc b/src/third_party/s2/s2regioncoverer.cc index 3c3337e27c7..d05499613a0 100644 --- a/src/third_party/s2/s2regioncoverer.cc +++ b/src/third_party/s2/s2regioncoverer.cc @@ -15,6 +15,8 @@ using std::reverse; #include <functional> using std::less; +#include <mutex> + #include <queue> using std::priority_queue; @@ -26,7 +28,6 @@ using std::vector; #include "s2.h" #include "s2cap.h" #include "s2cellunion.h" -#include "mongo/base/init.h" // Define storage for header file constants (the values are not needed here). int const S2RegionCoverer::kDefaultMaxCells = 8; @@ -44,15 +45,13 @@ struct S2RegionCoverer::CompareQueueEntries : public less<QueueEntry> { static S2Cell face_cells[6]; -static void Init() { - for (int face = 0; face < 6; ++face) { - face_cells[face] = S2Cell::FromFacePosLevel(face, 0, 0); - } -} - -MONGO_INITIALIZER_WITH_PREREQUISITES(S2RegionCovererInit, ("S2CellIdInit"))(mongo::InitializerContext *context) { - Init(); - return mongo::Status::OK(); +static std::once_flag flag; +static void MaybeInit() { + std::call_once(flag, []{ + for (int face = 0; face < 6; ++face) { + face_cells[face] = S2Cell::FromFacePosLevel(face, 0, 0); + } + }); } S2RegionCoverer::S2RegionCoverer() : @@ -225,6 +224,7 @@ void S2RegionCoverer::GetInitialCandidates() { } } // Default: start with all six cube faces. + MaybeInit(); for (size_t face = 0; face < 6; ++face) { AddCandidate(NewCandidate(face_cells[face])); } |