// Copyright 2019 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SRC_DAWN_NATIVE_BUDDYALLOCATOR_H_
#define SRC_DAWN_NATIVE_BUDDYALLOCATOR_H_

#include <cstddef>
#include <cstdint>
#include <limits>
#include <vector>

namespace dawn::native {

// Buddy allocator uses the buddy memory allocation technique to satisfy an allocation request.
// Memory is split into halves until just large enough to fit to the request. This
// requires the allocation size to be a power-of-two value. The allocator "allocates" a block by
// returning the starting offset whose size is guaranteed to be greater than or equal to the
// allocation size. To deallocate, the same offset is used to find the corresponding block.
//
// Internally, it manages a free list to track free blocks in a full binary tree.
// Every index in the free list corresponds to a level in the tree. That level also determines
// the size of the block to be used to satisfy the request. The first level (index=0) represents
// the root whose size is also called the max block size.
//
class BuddyAllocator {
  public:
    explicit BuddyAllocator(uint64_t maxSize);
    ~BuddyAllocator();

    // Required methods.
    uint64_t Allocate(uint64_t allocationSize, uint64_t alignment = 1);
    void Deallocate(uint64_t offset);

    // For testing purposes only.
    uint64_t ComputeTotalNumOfFreeBlocksForTesting() const;

    static constexpr uint64_t kInvalidOffset = std::numeric_limits<uint64_t>::max();

  private:
    uint32_t ComputeLevelFromBlockSize(uint64_t blockSize) const;
    uint64_t GetNextFreeAlignedBlock(size_t allocationBlockLevel, uint64_t alignment) const;

    enum class BlockState { Free, Split, Allocated };

    struct BuddyBlock {
        BuddyBlock(uint64_t size, uint64_t offset)
            : mOffset(offset), mSize(size), mState(BlockState::Free) {
            free.pPrev = nullptr;
            free.pNext = nullptr;
        }

        uint64_t mOffset;
        uint64_t mSize;

        // Pointer to this block's buddy, iff parent is split.
        // Used to quickly merge buddy blocks upon de-allocate.
        BuddyBlock* pBuddy = nullptr;
        BuddyBlock* pParent = nullptr;

        // Track whether this block has been split or not.
        BlockState mState;

        struct FreeLinks {
            BuddyBlock* pPrev;
            BuddyBlock* pNext;
        };

        struct SplitLink {
            BuddyBlock* pLeft;
        };

        union {
            // Used upon allocation.
            // Avoids searching for the next free block.
            FreeLinks free;

            // Used upon de-allocation.
            // Had this block split upon allocation, it and it's buddy is to be deleted.
            SplitLink split;
        };
    };

    void InsertFreeBlock(BuddyBlock* block, size_t level);
    void RemoveFreeBlock(BuddyBlock* block, size_t level);
    void DeleteBlock(BuddyBlock* block);

    uint64_t ComputeNumOfFreeBlocks(BuddyBlock* block) const;

    // Keep track the head and tail (for faster insertion/removal).
    struct BlockList {
        BuddyBlock* head = nullptr;  // First free block in level.
        // TODO(crbug.com/dawn/827): Track the tail.
    };

    BuddyBlock* mRoot = nullptr;  // Used to deallocate non-free blocks.

    uint64_t mMaxBlockSize = 0;

    // List of linked-lists of free blocks where the index is a level that
    // corresponds to a power-of-two sized block.
    std::vector<BlockList> mFreeLists;
};

}  // namespace dawn::native

#endif  // SRC_DAWN_NATIVE_BUDDYALLOCATOR_H_
