-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Server Code Style
-
Use spaces, no literal tabs.
-
4 spaces per indentation.
-
Limit lines to 100 columns.
-
Use LF (Unix-style) line endings, not CR-LF (DOS). git has a config option in Windows to convert line endings automatically (
core.autocrlf
) -
Starting with MongoDB 3.2 code, all code changes must be formatted by Clang-Format (version specified by buildscripts/clang_format.py) before they are checked in. See "clang-format" below for more information.
-
All new files added to the MongoDB code base should use the following copyright notice and SSPL license language, substituting the current year as appropriate:
/** * Copyright (C) 2023-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. */
-
Enterprise source code is not SSPL, therefore has to carry shorten header:
/** * Copyright (C) 2023-present MongoDB, Inc. */
-
For anything that isn't explicitly covered here, default to the Google C++ Style Guide and the Google JavaScript Style Guide.
Use camelCase for most varNames
. Use ProperCase for names of classes and structs. Use camelCase for instances of such classes.
Refer to getting-started-coding-style-guidelines for basic guidelines. Otherwise, default to Google C++ Style Guide for placement of comments.
-
If your inline function is a single line long, put it and its decl on separate lines:
int getLength() const { return _length; }
-
If a function is not performance sensitive, and it isn't one line long, put it in the cpp file. Keep code out of headers.
See util/str.h and base/string_data.h
-
Use
str::startsWith() str::endsWith()
and not
strstr()
. -
Use
<< 'c'
and not
<< "c"
. -
Use
str[0] == '\0'
and not
strlen(str) == 0
.
See server-string-manipulation.
if (0) {
} else if (0) {
} else {
}
do {
} while (0);
class Foo {
public:
int bar;
protected:
int _example;
private:
int _exampleTwo;
};
void foo(int v, MyType myItem);
Avoid declarations of extern functions in source files. Instead, #include
a proper .h
file. Be sure to match the header filename to the source filename where the function definition appears.
void foo(int v, MyType myItem) {
}
The Google C++ Style Guide recommends that output parameters be declared as references.
void exportData(const std::string& tag, MyType& myItem) {
myItem = _getData(tag);
}
The use of references for output parameters over pointers is a recent change in the Google C++ Style Guide so it is possible to find instances of output parameters declared as pointers in the codebase. See SERVER-71412.
namespace foo {
// Contents of namespace are not indented.
int foo;
namespace bar {
int bar;
} // namespace bar
} // namespace foo
See exception architecture documentation.
-
BAD
int foo() { if (x) { ... } }
-
GOOD
int foo() { if (!x) return; ... }
Keeps indentation levels down and makes more readable.
Large, round numeric constants should be written in multiplied form so that you never need to count digits.
const int tenMillion = 10 * 1000 * 1000;
const int megabyte = 1024 * 1024;
To avoid implicit type conversion, use the explicit
keyword before constructors that take a single parameter.
-
Use "double quotes" for local code, <angle brackets> for 3rd party or library headers.
examples: #include "mongo/platform/basic.h" #include <boost/thread.h> #include <vector>
-
Always use forward relative path from
mongo/src/
; do not use..
correct: #include "mongo/db/namespace_details.h" incorrect: #include "../db/namespace_details.h"
- Include your .h file next, if applicable. blank line.
- Include third party headers next, sorted. blank line.
- Include local headers last, sorted.
In versions of the server codebase prior to MongoDB 5.0, #include "mongo/platform/basic.h"
was written as the first include followed by a blank. After SERVER-55834 this is no longer necessary.
example for classy.cpp:
#include "mongo/db/classy.h"
#include <boost/thread/thread.hpp>
#include <cstdio>
#include <string>
#include "mongo/db/db.h"
#include "mongo/db/namespace_details.h"
#include "mongo/util/concurrency/qlock.h"
-
#pragma once
at the top, after the licence - Include third party headers first, sorted. blank line.
- Include local headers last, sorted.
- It's generally preferable to
#include
any headers you need. Forward-declaring type tags from other headers is permissible only when doing so is necessary, such as to break an#include
cycle. Forward declaring symbols other than type tags, such as functions or variables, is forbidden. - Do not include platform/basic.h in a header; assume that all source files will include it prior to including the header.
- Disable formatting for template literals
// clang-format off
newCode = `load("${overridesFile}"); (${jsCode})();`;
// clang-format on
- Class definitions should go in a header file with the same name as the class. Insert
_
in place of a capital letter. Do not use capital letters in filenames. For example:- ClassyClass's definition goes in classy_class.h.
- ClassyClass's member function implementations go in classy_class.cpp.
- Do not be afraid to make another file, even if it is small. This is preferable to inserting your new class into a preexisting file.
- Do not use C-style casts, ever.
- Use
static_cast<>
as needed. Useconst_cast<>
when no other solutions will work. - Be aware that
dynamic_cast<>
, unlike other casts, is done at run-time and calls a function. You should always check the return status ofdynamic_cast<>
fornull
. -
reinterpret_cast<>
should be used sparingly and is typically done for converting structures to raw bytes for use with I/O drivers. - When down-casting from a base type where the program logic guarantees that the runtime type is correct, consider using
checked_cast<>
frommongo/base/checked_cast.h
. It is equivalent to static_cast in release builds, but adds an invariant to debug builds that ensures the cast is valid.
-
Aspire to embrace RAII (Resource Aquisition Is Initialization)
-
When writing functions that take or return bare pointers, document the ownership semantics in a header comment.
- Is the caller responsible for managing returned pointer's memory?
- Does the callee take ownership of the pointed-to parameter, or does the caller retain ownership?
Prefer caller-retains ownership of parameters and takes ownership of returned pointers, but use the appropriate policy for each situation.
-
Generally, bare calls to
delete
andfree()
are red flags- except in destructors
-
Use smart pointers such as
std::unique_ptr
andstd::shared_ptr
(know the difference between them!) to avoid memory leaks and ensure allnew
's andmalloc
's are paired withdelete
's andfree
's -
Use
ON_BLOCK_EXIT
orScopeGuard
to protect other resources that must be released- e.g.
fopen
/fclose
pairs - Or, write an object to do this for you via constructor and destructor
- e.g.
In things like serverStatus
, include the units in the stat name if there is any chance of ambiguity. For example:
writtenMB
timeMs
We should have standards for these -- i.e. megabytes should always be MB
and not Mb
and Megabytes
in different places. So the standards are:
- For bytes: use
MB
and show in megabytes unless you know it will be tiny. Note you can use a float so0.1MB
is fine to show. - For time: use millis (
Ms
) for time by default. You can also use Secs and a float for times you know will be very long. - For microseconds, use
Micros
as the suffix, e.g.,timeMicros
.
As of the 3.2 code, MongoDB uses ESLint version 2.3.0 to lint JS code. ESLint is a JS linting tool that uses the config file located at .eslintrc.yml
, in the root of the mongo repository, to control the linting of the JS code.
important
All JS files must be linted by ESLint before they are formatted by clang-format.
Plugins are available for most editors that will automatically run ESLint on file save. It is recommended to use one of these plugins.
Use the Python script buildscripts/eslint.py
to check that the JS code is linted correctly as well as to fix linting errors in the code.
To lint JS code:
python buildscripts/eslint.py lint
To auto-fix JS code:
python buildscripts/eslint.py fix
As of the 3.5 code, MongoDB uses Clang-Format version 3.9 to enforce coding style. Clang-Format is a C/C++ & JS code formatting tool that uses the config files located at src/mongo/.clang-format
& jstests/.clang-format
to control the format of the code.
important
All code changes must be formatted by clang-format before they are checked in.
Plugins are available for most editors that will automatically run clang-format on file save. It is recommended to use one of these plugins.
Use the Python script buildscripts/clang_format.py
to check that the C/C++ & JS code is formatted correctly as well as to reformat the code.
To lint code:
python buildscripts/clang_format.py lint
To format code:
python buildscripts/clang_format.py format
Getting started
Building
Testing
- Running Tests
- Writing Tests
- Writing Function-level Benchmarks
- Writing JavaScript Integration-level Performance Tests
- Running Bisect
- Running Minimized Jstestfuzz Tests
- Testing with Antithesis
Testing in Evergreen
Code Style
Server Internals