bool MemoryTrunk::CommittedMemoryExpand()

in src/Trinity.C/src/Storage/MemoryTrunk/MemoryTrunk.Memory.cpp [89:216]


    bool MemoryTrunk::CommittedMemoryExpand(uint32_t minimum_size)
    {
        /**
        * There are two major cases:
        * 1) committed_head >= committed_tail
        *      Committed region consists of one part
        * 2) committed_head < committed_tail
        *      Committed region consists of two parts
        * */

        uint32_t minimum_to_expand = ((head.append_head + minimum_size + Memory::PAGE_RANGE_32) & Memory::PAGE_MASK_32) - head.committed_head;
        uint32_t CurrentVMAllocUnit = TrinityConfig::VMAllocUnit < minimum_to_expand ? minimum_to_expand : TrinityConfig::VMAllocUnit;
        bool ret = true;
        uint32_t available_space = 0;

        uint32_t committed_tail_snapshot = committed_tail;

        bool two_region = (head.committed_head < committed_tail_snapshot) ||
            (head.committed_head == committed_tail_snapshot && committed_tail_snapshot != 0);

#pragma region Two Region
        if (two_region)
        {
            available_space = committed_tail_snapshot - head.committed_head;

            // large enough virtual memory between committed_head and committed_tail for allocating VMAllocUnit
            if (CurrentVMAllocUnit <= available_space)
            {
                ret = Memory::ExpandMemoryFromCurrentPosition(trunkPtr + head.committed_head, CurrentVMAllocUnit);
                if (ret) head.committed_head += CurrentVMAllocUnit;
                goto EXPAND_RETURN;
            }

            // Not large enough for VMAllocUnit, but enough for minimum_to_expand
            if (minimum_to_expand <= available_space)
            {
                ret = Memory::ExpandMemoryFromCurrentPosition(trunkPtr + head.committed_head, minimum_to_expand);
                if (ret) head.committed_head += minimum_to_expand;
                goto EXPAND_RETURN;
            }

            // Out of memory, try to reload later
            goto RELOAD_RETURN;
        }
#pragma endregion

#pragma region One Region
        available_space = TrunkLength - head.committed_head;

        // There is enough virtual memory between committed_head to trunk_end for VMAllocUnit
        if (CurrentVMAllocUnit <= available_space)
        {
            ret = Memory::ExpandMemoryFromCurrentPosition(trunkPtr + head.committed_head, CurrentVMAllocUnit);
            if (ret) head.committed_head += CurrentVMAllocUnit;
            goto EXPAND_RETURN;
        }

        // Not enough for VMAllocUnit, but enough for minimum_to_expand
        if (minimum_to_expand <= available_space)
        {
            ret = Memory::ExpandMemoryFromCurrentPosition(trunkPtr + head.committed_head, minimum_to_expand);
            if (ret) head.committed_head += minimum_to_expand;
            goto EXPAND_RETURN;
        }

        // There is not enough virtual memory between committed_head to trunk_end
        //! Now check the space between trunk_ptr and committed_tail

        // Enough available memory for VMAllocUnit
        if (CurrentVMAllocUnit <= committed_tail) //available_space = committed_tail - 0
        {
            //First allocate the memory between committed_head to trunk_end
            uint32_t padding_size = available_space;
            
            if (padding_size)
            {
                ret = Memory::ExpandMemoryFromCurrentPosition(trunkPtr + head.committed_head, padding_size);
                if (!ret) goto EXPAND_RETURN;
            }

            //Then allocate memory between trunk_ptr to committed_tail
            split_lock->lock();
            ret = Memory::ExpandMemoryFromCurrentPosition(trunkPtr, CurrentVMAllocUnit);
            if (ret)
            {
                head.append_head = 0; //warp back to head
                head.committed_head = CurrentVMAllocUnit;
            }
            split_lock->unlock();
            goto EXPAND_RETURN;
        }

        // Not enough for VMAllocUnit, but enough for minimum_to_expand
        if (minimum_to_expand <= committed_tail) //vailable_space = committed_tail - 0
        {
            //First allocate the memory between committed_head to trunk_end
            uint32_t padding_size = available_space;

            if (padding_size)
            {
                ret = Memory::ExpandMemoryFromCurrentPosition(trunkPtr + head.committed_head, padding_size);
                if (!ret) goto EXPAND_RETURN;
            }

            //Then allocate memory between trunk_ptr to committed_tail
            split_lock->lock();
            ret = Memory::ExpandMemoryFromCurrentPosition(trunkPtr, minimum_to_expand);
            if (ret)
            {
                head.append_head = 0; //warp back to head
                head.committed_head = minimum_to_expand;
            }
            split_lock->unlock();
            goto EXPAND_RETURN;
        }

        // Out of memory
        goto RELOAD_RETURN;
#pragma endregion
    EXPAND_RETURN:
        if (ret == false)
        {
            Trinity::Diagnostics::WriteLine(Diagnostics::LogLevel::Error, "CommittedMemoryExpand: MemoryTrunk {0} failed to expand. LastError = {1}", TrunkId, GetLastError());
        }
        return ret;
    RELOAD_RETURN:
        return Reload(minimum_size);
    }