Example #1
0
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;
    }();
}