/** put the basic write operation into the buffer (bb) to be journaled */ static void prepBasicWrite_inlock(AlignedBuilder& bb, const WriteIntent* i, RelativePath& lastDbPath) { size_t ofs = 1; DurableMappedFile* mmf = findMMF_inlock(i->start(), /*out*/ ofs); if (MONGO_unlikely(!mmf->willNeedRemap())) { // tag this mmf as needed a remap of its private view later. // usually it will already be dirty/already set, so we do the if above first // to avoid possibility of cpu cache line contention mmf->setWillNeedRemap(); } // since we have already looked up the mmf, we go ahead and remember the write view location // so we don't have to find the DurableMappedFile again later in WRITETODATAFILES() // // this was for WRITETODATAFILES_Impl2 so commented out now // /* dassert( i->w_ptr == 0 ); i->w_ptr = ((char*)mmf->view_write()) + ofs; */ JEntry e; e.len = min(i->length(), (unsigned)(mmf->length() - ofs)); // don't write past end of file verify(ofs <= 0x80000000); e.ofs = (unsigned)ofs; e.setFileNo(mmf->fileSuffixNo()); if (mmf->relativePath() == local) { e.setLocalDbContextBit(); } else if (mmf->relativePath() != lastDbPath) { lastDbPath = mmf->relativePath(); JDbContext c; bb.appendStruct(c); bb.appendStr(lastDbPath.toString()); } bb.appendStruct(e); bb.appendBuf(i->start(), e.len); if (MONGO_unlikely(e.len != (unsigned)i->length())) { log() << "journal info splitting prepBasicWrite at boundary" << endl; // This only happens if we write to the last byte in a file and // the fist byte in another file that is mapped adjacently. I // think most OSs leave at least a one page gap between // mappings, but better to be safe. WriteIntent next((char*)i->start() + e.len, i->length() - e.len); prepBasicWrite_inlock(bb, &next, lastDbPath); } }
Status AuthorizationSession::checkAuthForQuery(const NamespaceString& ns, const BSONObj& query) { if (MONGO_unlikely(ns.isCommand())) { return Status(ErrorCodes::InternalError, mongoutils::str::stream() << "Checking query auth on command namespace " << ns.ns()); } if (!isAuthorizedForActionsOnNamespace(ns, ActionType::find)) { return Status(ErrorCodes::Unauthorized, mongoutils::str::stream() << "not authorized for query on " << ns.ns()); } return Status::OK(); }
bool OperationContext::hasDeadlineExpired() const { if (!hasDeadline()) { return false; } if (MONGO_FAIL_POINT(maxTimeNeverTimeOut)) { return false; } if (MONGO_FAIL_POINT(maxTimeAlwaysTimeOut)) { return true; } // TODO: Remove once all OperationContexts are properly connected to Clients and ServiceContexts // in tests. if (MONGO_unlikely(!getClient() || !getServiceContext())) { return false; } const auto now = getServiceContext()->getFastClockSource()->now(); return now >= getDeadline(); }
std::shared_ptr<ViewDefinition> ViewCatalog::_lookup_inlock(OperationContext* txn, StringData ns) { // We expect the catalog to be valid, so short-circuit other checks for best performance. if (MONGO_unlikely(!_valid.load())) { // If the catalog is invalid, we want to avoid references to virtualized or other invalid // collection names to trigger a reload. This makes the system more robust in presence of // invalid view definitions. if (!NamespaceString::validCollectionName(ns)) return nullptr; Status status = _reloadIfNeeded_inlock(txn); // In case of errors we've already logged a message. Only uassert if there actually is // a user connection, as otherwise we'd crash the server. The catalog will remain invalid, // and any views after the first invalid one are ignored. if (txn->getClient()->isFromUserConnection()) uassertStatusOK(status); } ViewMap::const_iterator it = _viewMap.find(ns); if (it != _viewMap.end()) { return it->second; } return nullptr; }
OplogEntry::OplogEntry(BSONObj rawInput) : raw(std::move(rawInput)) { if (MONGO_unlikely(!raw.isOwned())) { raw = raw.copy(); } for (auto elem : raw) { const auto name = elem.fieldNameStringData(); if (name == "ns") { ns = elem.valuestrsafe(); } else if (name == "op") { opType = elem.valuestrsafe(); } else if (name == "o2") { o2 = elem; } else if (name == "ts") { ts = elem; } else if (name == "v") { version = elem; } else if (name == "o") { o = elem; } } }
int BSONElement::computeSize() const { enum SizeStyle : uint8_t { kFixed, // Total size is a fixed amount + key length. kIntPlusFixed, // Like Fixed, but also add in the int32 immediately following the key. kRegEx, // Handled specially. }; struct SizeInfo { uint8_t style : 2; uint8_t bytes : 6; // Includes type byte. Excludes field name and variable lengths. }; MONGO_STATIC_ASSERT(sizeof(SizeInfo) == 1); // This table should take 20 bytes. Align to next power of 2 to avoid splitting across cache // lines unnecessarily. static constexpr SizeInfo kSizeInfoTable alignas(32)[] = { {SizeStyle::kFixed, 1}, // EOO {SizeStyle::kFixed, 9}, // NumberDouble {SizeStyle::kIntPlusFixed, 5}, // String {SizeStyle::kIntPlusFixed, 1}, // Object {SizeStyle::kIntPlusFixed, 1}, // Array {SizeStyle::kIntPlusFixed, 6}, // BinData {SizeStyle::kFixed, 1}, // Undefined {SizeStyle::kFixed, 13}, // OID {SizeStyle::kFixed, 2}, // Bool {SizeStyle::kFixed, 9}, // Date {SizeStyle::kFixed, 1}, // Null {SizeStyle::kRegEx}, // Regex {SizeStyle::kIntPlusFixed, 17}, // DBRef {SizeStyle::kIntPlusFixed, 5}, // Code {SizeStyle::kIntPlusFixed, 5}, // Symbol {SizeStyle::kIntPlusFixed, 1}, // CodeWScope {SizeStyle::kFixed, 5}, // Int {SizeStyle::kFixed, 9}, // Timestamp {SizeStyle::kFixed, 9}, // Long {SizeStyle::kFixed, 17}, // Decimal }; MONGO_STATIC_ASSERT((sizeof(kSizeInfoTable) / sizeof(kSizeInfoTable[0])) == JSTypeMax + 1); // This is the start of the runtime code for this function. Everything above happens at compile // time. This function attempts to push complex handling of unlikely events out-of-line to // ensure that the common cases never need to spill any registers (at least on x64 with // gcc-5.4), which reduces the function call overhead. int8_t type = *data; if (MONGO_unlikely(type < 0 || type > JSTypeMax)) { if (MONGO_unlikely(type != MinKey && type != MaxKey)) { msgAssertedBadType(type); } // MinKey and MaxKey should be treated the same as Null type = jstNULL; } const auto sizeInfo = kSizeInfoTable[type]; if (sizeInfo.style == SizeStyle::kFixed) return sizeInfo.bytes + fieldNameSize(); if (MONGO_likely(sizeInfo.style == SizeStyle::kIntPlusFixed)) return sizeInfo.bytes + fieldNameSize() + valuestrsize(); return [this, type]() NOINLINE_DECL { // Regex is two c-strings back-to-back. invariant(type == BSONType::RegEx); const char* p = value(); size_t len1 = strlen(p); p = p + len1 + 1; size_t len2 = strlen(p); return (len1 + 1 + len2 + 1) + fieldNameSize() + 1; }(); }