Repository: google/filament
File: filament/src/details/BufferAllocator.cpp (C++)

Code before:
    if (size == 0) {
        return { UNALLOCATED, 0 };
    }

    const allocation_size_t alignedSize = alignUp(size);
    auto bestFitIter = mFreeList.lower_bound(alignedSize);

    if (bestFitIter == mFreeList.end()) {
        return { REALLOCATION_REQUIRED, 0 };
    }

    InternalSlotNode* targetNode = bestFitIter->second;
    const allocation_size_t originalSlotSize = targetNode->slot.slotSize;

    mFreeList.erase(bestFitIter);

    const allocation_size_t remainingSize = targetNode->slot.slotSize - alignedSize;
    const allocation_size_t offset = targetNode->slot.offset;
    assert_invariant(remainingSize % mSlotSize == 0);
    assert_invariant((offset + alignedSize) % mSlotSize == 0);

    // Split the slot if it is larger than what we need.
    if (originalSlotSize > alignedSize) {
        // Update Head block
        targetNode->slot.slotSize = alignedSize;
        targetNode->slot.isAllocated = true;

        // Update Tail block
        size_t endSlotIndex = (offset + alignedSize) / mSlotSize - 1;
        mNodes[endSlotIndex] = *targetNode; // Copy Head to Tail

        // The Head of remaining free block
        size_t nextSlotIndex = endSlotIndex + 1;
        InternalSlotNode* nextNode = &mNodes[nextSlotIndex];
        nextNode->slot.offset = offset + alignedSize;
        nextNode->slot.slotSize = remainingSize;
        nextNode->slot.isAllocated = false;
        nextNode->slot.gpuUseCount = 0;
        nextNode->freeListIterator = mFreeList.emplace(remainingSize, nextNode);

        // Update the Tail of remaining free block
        size_t nextEndSlotIndex = (nextNode->slot.offset + nextNode->slot.slotSize) / mSlotSize - 1;
        mNodes[nextEndSlotIndex] = *nextNode; // Copy Head to Tail
    } else {
        // Allocate the whole block
        targetNode->slot.isAllocated = true;

        // Update Tail block
        size_t endSlotIndex = (offset + targetNode->slot.slotSize) / mSlotSize - 1;
        mNodes[endSlotIndex] = *targetNode;
    }

Review comment (refactor):
nit: this `targetNode->slot.isAllocated = true;` is duplicated in the `else` block. You could put this before the if statement.

Code after:
    if (size == 0) {
        return { UNALLOCATED, 0 };
    }

    const allocation_size_t alignedSize = alignUp(size);
    auto bestFitIter = mFreeList.lower_bound(alignedSize);

    if (bestFitIter == mFreeList.end()) {
        return { REALLOCATION_REQUIRED, 0 };
    }

    InternalSlotNode* targetNode = bestFitIter->second;
    const allocation_size_t originalSlotSize = targetNode->slot.slotSize;

    mFreeList.erase(bestFitIter);

    const allocation_size_t remainingSize = targetNode->slot.slotSize - alignedSize;
    const allocation_size_t offset = targetNode->slot.offset;
    assert_invariant(remainingSize % mSlotSize == 0);
    assert_invariant((offset + alignedSize) % mSlotSize == 0);
    targetNode->slot.isAllocated = true;

    // Split the slot if it is larger than what we need.
    if (originalSlotSize > alignedSize) {
        // Update Head block
        targetNode->slot.slotSize = alignedSize;

        // Update Tail block
        const size_t endSlotIndex = (offset + alignedSize) / mSlotSize - 1;
        mNodes[endSlotIndex] = *targetNode; // Copy Head to Tail

        // The Head of remaining free block
        const size_t nextSlotIndex = endSlotIndex + 1;
        InternalSlotNode* nextNode = &mNodes[nextSlotIndex];
        nextNode->slot.offset = offset + alignedSize;
        nextNode->slot.slotSize = remainingSize;
        nextNode->slot.isAllocated = false;
        nextNode->slot.gpuUseCount = 0;
        nextNode->freeListIterator = mFreeList.emplace(remainingSize, nextNode);

        // Update the Tail of remaining free block
        const size_t nextEndSlotIndex = (nextNode->slot.offset + nextNode->slot.slotSize) / mSlotSize - 1;
        mNodes[nextEndSlotIndex] = *nextNode; // Copy Head to Tail
    } else {
        // Allocate the whole block
        // Update Tail block
        const size_t endSlotIndex = (offset + targetNode->slot.slotSize) / mSlotSize - 1;
        mNodes[endSlotIndex] = *targetNode;
    }

    return { calculateIdByOffset(offset), offset };