void LogFile::truncate() { verify(_fd >= 0); MONGO_STATIC_ASSERT(sizeof(off_t) == 8); // we don't want overflow here const off_t pos = lseek(_fd, 0, SEEK_CUR); // doesn't actually seek if (ftruncate(_fd, pos) != 0) { msgasserted(15873, "Couldn't truncate file: " + errnoWithDescription()); } fsync(_fd); }
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; }(); }